mirror of https://gitlab.com/nakst/essence
EsScrollView
This commit is contained in:
parent
4d1c7ace98
commit
8ce9eddea3
|
@ -323,14 +323,7 @@ struct ScrollPane {
|
|||
bool enabled[2];
|
||||
bool dragScrolling;
|
||||
|
||||
#define SCROLL_MODE_NONE (0) // No scrolling takes place on this axis.
|
||||
#define SCROLL_MODE_HIDDEN (1) // Scrolling takes place, but there is no visible scrollbar.
|
||||
#define SCROLL_MODE_FIXED (2) // The scrollbar is always visible.
|
||||
#define SCROLL_MODE_AUTO (3) // The scrollbar is only visible if the content is larger than the viewport.
|
||||
uint8_t mode[2];
|
||||
#define SCROLL_X_DRAG (1 << 0)
|
||||
#define SCROLL_Y_DRAG (1 << 1)
|
||||
#define SCROLL_MANUAL (1 << 2) // The parent is responsible for updating the position of the scroll bars.
|
||||
uint16_t flags;
|
||||
|
||||
void Setup(EsElement *parent, uint8_t xMode, uint8_t yMode, uint16_t flags);
|
||||
|
@ -2790,11 +2783,11 @@ void ScrollPane::Setup(EsElement *_parent, uint8_t _xMode, uint8_t _yMode, uint1
|
|||
mode[1] = _yMode;
|
||||
flags = _flags;
|
||||
|
||||
if (mode[0] == SCROLL_MODE_NONE) flags &= ~SCROLL_X_DRAG;
|
||||
if (mode[1] == SCROLL_MODE_NONE) flags &= ~SCROLL_Y_DRAG;
|
||||
if (mode[0] == ES_SCROLL_MODE_NONE) flags &= ~SCROLL_X_DRAG;
|
||||
if (mode[1] == ES_SCROLL_MODE_NONE) flags &= ~SCROLL_Y_DRAG;
|
||||
|
||||
for (int axis = 0; axis < 2; axis++) {
|
||||
if (mode[axis] == SCROLL_MODE_FIXED || mode[axis] == SCROLL_MODE_AUTO) {
|
||||
if (mode[axis] == ES_SCROLL_MODE_FIXED || mode[axis] == ES_SCROLL_MODE_AUTO) {
|
||||
uint64_t flags = ES_CELL_FILL | ES_ELEMENT_NON_CLIENT | (axis ? ES_SCROLLBAR_VERTICAL : ES_SCROLLBAR_HORIZONTAL);
|
||||
|
||||
if (!bar[axis]) {
|
||||
|
@ -2870,7 +2863,7 @@ void ScrollPane::ReceivedMessage(EsMessage *message) {
|
|||
message->animate.complete = false;
|
||||
}
|
||||
} else if (message->type == ES_MSG_GET_HEIGHT) {
|
||||
if (message->measure.width && (mode[0] == SCROLL_MODE_AUTO) && (mode[1] != SCROLL_MODE_AUTO)) {
|
||||
if (message->measure.width && (mode[0] == ES_SCROLL_MODE_AUTO) && (mode[1] != ES_SCROLL_MODE_AUTO)) {
|
||||
// To accurately measure the height of the element for this width,
|
||||
// we need to determine whether the horizontal scrollbar will be present.
|
||||
// TODO This assumes that the element will be send a LAYOUT message after measurements are complete,
|
||||
|
@ -2881,7 +2874,7 @@ void ScrollPane::ReceivedMessage(EsMessage *message) {
|
|||
parent->internalOffsetBottom = (m.measure.width + fixedViewport[0] > message->measure.width) ? bar[0]->currentStyle->preferredHeight : 0;
|
||||
}
|
||||
} else if (message->type == ES_MSG_GET_WIDTH) {
|
||||
if (message->measure.width && (mode[1] == SCROLL_MODE_AUTO) && (mode[0] != SCROLL_MODE_AUTO)) {
|
||||
if (message->measure.width && (mode[1] == ES_SCROLL_MODE_AUTO) && (mode[0] != ES_SCROLL_MODE_AUTO)) {
|
||||
// As above.
|
||||
EsMessage m = {};
|
||||
m.type = ES_MSG_GET_HEIGHT;
|
||||
|
@ -2895,7 +2888,7 @@ void ScrollPane::ReceivedMessage(EsMessage *message) {
|
|||
}
|
||||
|
||||
void ScrollPane::SetPosition(int axis, double newScroll, bool sendMovedMessage) {
|
||||
if (mode[axis] == SCROLL_MODE_NONE) return;
|
||||
if (mode[axis] == ES_SCROLL_MODE_NONE) return;
|
||||
if (newScroll < 0) newScroll = 0;
|
||||
else if (newScroll > limit[axis]) newScroll = limit[axis];
|
||||
if (newScroll == position[axis]) return;
|
||||
|
@ -2917,7 +2910,7 @@ void ScrollPane::SetPosition(int axis, double newScroll, bool sendMovedMessage)
|
|||
}
|
||||
|
||||
bool ScrollPane::RefreshLimit(int axis, int64_t *contentSize) {
|
||||
if (mode[axis] != SCROLL_MODE_NONE) {
|
||||
if (mode[axis] != ES_SCROLL_MODE_NONE) {
|
||||
uint8_t *internalOffset = axis ? &parent->internalOffsetRight : &parent->internalOffsetBottom;
|
||||
EsRectangle bounds = parent->GetBounds();
|
||||
|
||||
|
@ -2936,7 +2929,7 @@ bool ScrollPane::RefreshLimit(int axis, int64_t *contentSize) {
|
|||
axis + 'X', limit[axis], *contentSize, axis ? bounds.r : bounds.b);
|
||||
}
|
||||
|
||||
if (mode[axis] == SCROLL_MODE_AUTO && limit[axis] > 0 && !(*internalOffset)) {
|
||||
if (mode[axis] == ES_SCROLL_MODE_AUTO && limit[axis] > 0 && !(*internalOffset)) {
|
||||
*internalOffset = axis ? bar[axis]->currentStyle->preferredWidth : bar[axis]->currentStyle->preferredHeight;
|
||||
return true;
|
||||
}
|
||||
|
@ -2950,8 +2943,8 @@ void ScrollPane::Refresh() {
|
|||
InspectorNotifyElementEvent(parent, "scroll", "Refreshing scroll pane...\n");
|
||||
}
|
||||
|
||||
parent->internalOffsetRight = mode[1] == SCROLL_MODE_FIXED ? bar[1]->currentStyle->preferredWidth : 0;
|
||||
parent->internalOffsetBottom = mode[0] == SCROLL_MODE_FIXED ? bar[0]->currentStyle->preferredHeight : 0;
|
||||
parent->internalOffsetRight = mode[1] == ES_SCROLL_MODE_FIXED ? bar[1]->currentStyle->preferredWidth : 0;
|
||||
parent->internalOffsetBottom = mode[0] == ES_SCROLL_MODE_FIXED ? bar[0]->currentStyle->preferredHeight : 0;
|
||||
|
||||
int64_t contentWidth = 0, contentHeight = 0;
|
||||
|
||||
|
@ -2993,6 +2986,25 @@ void ScrollPane::Refresh() {
|
|||
}
|
||||
}
|
||||
|
||||
struct EsScrollView : EsElement { ScrollPane scroll; };
|
||||
void EsScrollViewSetup(EsScrollView *view, uint8_t xMode, uint8_t yMode, uint16_t flags) { view->scroll.Setup(view, xMode, yMode, flags); }
|
||||
void EsScrollViewSetPosition(EsScrollView *view, int axis, double newPosition, bool notify) { view->scroll.SetPosition(axis, newPosition, notify); }
|
||||
void EsScrollViewRefresh(EsScrollView *view) { view->scroll.Refresh(); }
|
||||
void EsScrollViewReceivedMessage(EsScrollView *view, EsMessage *message) { view->scroll.ReceivedMessage(message); }
|
||||
int64_t EsScrollViewGetPosition(EsScrollView *view, int axis) { return view->scroll.position[axis]; }
|
||||
int64_t EsScrollViewGetLimit(EsScrollView *view, int axis) { return view->scroll.limit[axis]; }
|
||||
void EsScrollViewSetFixedViewport(EsScrollView *view, int axis, int32_t value) { view->scroll.fixedViewport[axis] = value; }
|
||||
bool EsScrollViewIsBarEnabled(EsScrollView *view, int axis) { return view->scroll.enabled[axis]; }
|
||||
bool EsScrollViewIsInDragScroll(EsScrollView *view) { return view->scroll.dragScrolling; }
|
||||
|
||||
EsScrollView *EsCustomScrollViewCreate(EsElement *parent, uint64_t flags, const EsStyle *style) {
|
||||
EsScrollView *element = (EsScrollView *) EsHeapAllocate(sizeof(EsScrollView), true);
|
||||
if (!element) return nullptr;
|
||||
element->Initialise(parent, flags, nullptr, style);
|
||||
element->cName = "custom scroll view";
|
||||
return element;
|
||||
}
|
||||
|
||||
// --------------------------------- Panels.
|
||||
|
||||
void PanelSwitcherTransitionComplete(EsPanel *panel) {
|
||||
|
@ -3386,8 +3398,8 @@ EsPanel *EsPanelCreate(EsElement *parent, uint64_t flags, const EsStyle *style)
|
|||
if (flags & ES_PANEL_REVERSE) panel->flags |= ES_ELEMENT_LAYOUT_HINT_REVERSE;
|
||||
|
||||
panel->scroll.Setup(panel,
|
||||
((flags & ES_PANEL_H_SCROLL_FIXED) ? SCROLL_MODE_FIXED : (flags & ES_PANEL_H_SCROLL_AUTO) ? SCROLL_MODE_AUTO : SCROLL_MODE_NONE),
|
||||
((flags & ES_PANEL_V_SCROLL_FIXED) ? SCROLL_MODE_FIXED : (flags & ES_PANEL_V_SCROLL_AUTO) ? SCROLL_MODE_AUTO : SCROLL_MODE_NONE),
|
||||
((flags & ES_PANEL_H_SCROLL_FIXED) ? ES_SCROLL_MODE_FIXED : (flags & ES_PANEL_H_SCROLL_AUTO) ? ES_SCROLL_MODE_AUTO : ES_SCROLL_MODE_NONE),
|
||||
((flags & ES_PANEL_V_SCROLL_FIXED) ? ES_SCROLL_MODE_FIXED : (flags & ES_PANEL_V_SCROLL_AUTO) ? ES_SCROLL_MODE_AUTO : ES_SCROLL_MODE_NONE),
|
||||
ES_FLAGS_DEFAULT);
|
||||
|
||||
return panel;
|
||||
|
@ -3824,7 +3836,7 @@ EsCanvasPane *EsCanvasPaneCreate(EsElement *parent, uint64_t flags, const EsStyl
|
|||
pane->Initialise(parent, flags, ProcessCanvasPaneMessage, style);
|
||||
pane->cName = "canvas pane";
|
||||
pane->zoom = 1.0;
|
||||
pane->scroll.Setup(pane, SCROLL_MODE_AUTO, SCROLL_MODE_AUTO, SCROLL_MANUAL);
|
||||
pane->scroll.Setup(pane, ES_SCROLL_MODE_AUTO, ES_SCROLL_MODE_AUTO, SCROLL_MANUAL);
|
||||
return pane;
|
||||
}
|
||||
|
||||
|
|
|
@ -1925,18 +1925,18 @@ void EsListViewChangeStyles(EsListView *view, const EsStyle *style, const EsStyl
|
|||
view->scroll.fixedViewport[1] = 0;
|
||||
}
|
||||
|
||||
// It's safe to use SCROLL_MODE_AUTO even in tiled mode,
|
||||
// It's safe to use ES_SCROLL_MODE_AUTO even in tiled mode,
|
||||
// because decreasing the secondary axis can only increase the primary axis.
|
||||
|
||||
uint8_t scrollXMode = 0, scrollYMode = 0;
|
||||
|
||||
if (view->flags & ES_LIST_VIEW_COLUMNS) {
|
||||
scrollXMode = SCROLL_MODE_AUTO;
|
||||
scrollYMode = SCROLL_MODE_AUTO;
|
||||
scrollXMode = ES_SCROLL_MODE_AUTO;
|
||||
scrollYMode = ES_SCROLL_MODE_AUTO;
|
||||
} else if (view->flags & ES_LIST_VIEW_HORIZONTAL) {
|
||||
scrollXMode = SCROLL_MODE_AUTO;
|
||||
scrollXMode = ES_SCROLL_MODE_AUTO;
|
||||
} else {
|
||||
scrollYMode = SCROLL_MODE_AUTO;
|
||||
scrollYMode = ES_SCROLL_MODE_AUTO;
|
||||
}
|
||||
|
||||
view->scroll.Setup(view, scrollXMode, scrollYMode, SCROLL_X_DRAG | SCROLL_Y_DRAG);
|
||||
|
|
|
@ -14,6 +14,7 @@ opaque_type EsImageDisplay EsElement;
|
|||
opaque_type EsListDisplay EsElement;
|
||||
opaque_type EsCanvasPane EsElement;
|
||||
opaque_type EsSlider EsElement;
|
||||
opaque_type EsScrollView EsElement;
|
||||
opaque_type EsTextPlan none;
|
||||
opaque_type EsPaintTarget none;
|
||||
opaque_type EsUndoManager none;
|
||||
|
@ -735,6 +736,16 @@ define ES_CLIPBOARD_ADD_LAZY_CUT (1 << 0) // Only perform the deletion after pas
|
|||
|
||||
define ES_SCROLL_WHEEL_NOTCH (0x100)
|
||||
|
||||
// Scroll view modes.
|
||||
define ES_SCROLL_MODE_NONE (0) // No scrolling takes place on this axis.
|
||||
define ES_SCROLL_MODE_HIDDEN (1) // Scrolling takes place, but there is no visible scrollbar.
|
||||
define ES_SCROLL_MODE_FIXED (2) // The scrollbar is always visible.
|
||||
define ES_SCROLL_MODE_AUTO (3) // The scrollbar is only visible if the content is larger than the viewport.
|
||||
// Scroll view flags.
|
||||
define SCROLL_X_DRAG (1 << 0)
|
||||
define SCROLL_Y_DRAG (1 << 1)
|
||||
private define SCROLL_MANUAL (1 << 2) // The parent is responsible for updating the position of the scroll bars.
|
||||
|
||||
include desktop/icons.header
|
||||
|
||||
enum EsFatalError {
|
||||
|
@ -2378,7 +2389,19 @@ function void EsElementGetTextStyle(EsElement *element, EsTextStyle *style);
|
|||
function EsRectangle EsElementGetWindowBounds(EsElement *element, bool client = true);
|
||||
function EsRectangle EsElementGetScreenBounds(EsElement *element, bool client = true);
|
||||
|
||||
// TODO Rename these functions?
|
||||
function EsElement *EsCustomElementCreate(EsElement *parent, uint64_t flags = ES_FLAGS_DEFAULT, const EsStyle *style = ES_NULL);
|
||||
function EsScrollView *EsCustomScrollViewCreate(EsElement *parent, uint64_t flags = ES_FLAGS_DEFAULT, const EsStyle *style = ES_NULL);
|
||||
|
||||
function void EsScrollViewReceivedMessage(EsScrollView *view, EsMessage *message); // You *must* call this *before* handling any messages.
|
||||
function void EsScrollViewSetup(EsScrollView *view, uint8_t xMode, uint8_t yMode, uint16_t flags);
|
||||
function void EsScrollViewSetPosition(EsScrollView *view, int axis, double newPosition, bool sendMovedMessage = true);
|
||||
function void EsScrollViewRefresh(EsScrollView *view);
|
||||
function int64_t EsScrollViewGetPosition(EsScrollView *view, int axis);
|
||||
function int64_t EsScrollViewGetLimit(EsScrollView *view, int axis);
|
||||
function void EsScrollViewSetFixedViewport(EsScrollView *view, int axis, int32_t value);
|
||||
function bool EsScrollViewIsBarEnabled(EsScrollView *view, int axis);
|
||||
function bool EsScrollViewIsInDragScroll(EsScrollView *view);
|
||||
|
||||
// Windows, menus, popups, toolbars and dialogs.
|
||||
|
||||
|
|
|
@ -4714,8 +4714,8 @@ EsTextbox *EsTextboxCreate(EsElement *parent, uint64_t flags, const EsStyle *sty
|
|||
textbox->cName = "textbox";
|
||||
|
||||
textbox->scroll.Setup(textbox,
|
||||
(flags & ES_TEXTBOX_MULTILINE) ? SCROLL_MODE_AUTO : SCROLL_MODE_HIDDEN,
|
||||
(flags & ES_TEXTBOX_MULTILINE) ? SCROLL_MODE_AUTO : SCROLL_MODE_NONE,
|
||||
(flags & ES_TEXTBOX_MULTILINE) ? ES_SCROLL_MODE_AUTO : ES_SCROLL_MODE_HIDDEN,
|
||||
(flags & ES_TEXTBOX_MULTILINE) ? ES_SCROLL_MODE_AUTO : ES_SCROLL_MODE_NONE,
|
||||
SCROLL_X_DRAG | SCROLL_Y_DRAG);
|
||||
|
||||
textbox->undo = &textbox->localUndo;
|
||||
|
|
|
@ -477,3 +477,13 @@ EsCRTstrtod=475
|
|||
EsCRTstrtof=476
|
||||
EsOpenDocumentQueryInformation=477
|
||||
EsDrawTextThemed=478
|
||||
EsCustomScrollViewCreate=479
|
||||
EsScrollViewSetup=480
|
||||
EsScrollViewSetPosition=481
|
||||
EsScrollViewRefresh=482
|
||||
EsScrollViewReceivedMessage=483
|
||||
EsScrollViewGetPosition=484
|
||||
EsScrollViewGetLimit=485
|
||||
EsScrollViewSetFixedViewport=486
|
||||
EsScrollViewIsBarEnabled=487
|
||||
EsScrollViewIsInDragScroll=488
|
||||
|
|
Loading…
Reference in New Issue