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 enabled[2];
|
||||||
bool dragScrolling;
|
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];
|
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;
|
uint16_t flags;
|
||||||
|
|
||||||
void Setup(EsElement *parent, uint8_t xMode, uint8_t yMode, 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;
|
mode[1] = _yMode;
|
||||||
flags = _flags;
|
flags = _flags;
|
||||||
|
|
||||||
if (mode[0] == SCROLL_MODE_NONE) flags &= ~SCROLL_X_DRAG;
|
if (mode[0] == ES_SCROLL_MODE_NONE) flags &= ~SCROLL_X_DRAG;
|
||||||
if (mode[1] == SCROLL_MODE_NONE) flags &= ~SCROLL_Y_DRAG;
|
if (mode[1] == ES_SCROLL_MODE_NONE) flags &= ~SCROLL_Y_DRAG;
|
||||||
|
|
||||||
for (int axis = 0; axis < 2; axis++) {
|
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);
|
uint64_t flags = ES_CELL_FILL | ES_ELEMENT_NON_CLIENT | (axis ? ES_SCROLLBAR_VERTICAL : ES_SCROLLBAR_HORIZONTAL);
|
||||||
|
|
||||||
if (!bar[axis]) {
|
if (!bar[axis]) {
|
||||||
|
@ -2870,7 +2863,7 @@ void ScrollPane::ReceivedMessage(EsMessage *message) {
|
||||||
message->animate.complete = false;
|
message->animate.complete = false;
|
||||||
}
|
}
|
||||||
} else if (message->type == ES_MSG_GET_HEIGHT) {
|
} 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,
|
// To accurately measure the height of the element for this width,
|
||||||
// we need to determine whether the horizontal scrollbar will be present.
|
// 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,
|
// 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;
|
parent->internalOffsetBottom = (m.measure.width + fixedViewport[0] > message->measure.width) ? bar[0]->currentStyle->preferredHeight : 0;
|
||||||
}
|
}
|
||||||
} else if (message->type == ES_MSG_GET_WIDTH) {
|
} 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.
|
// As above.
|
||||||
EsMessage m = {};
|
EsMessage m = {};
|
||||||
m.type = ES_MSG_GET_HEIGHT;
|
m.type = ES_MSG_GET_HEIGHT;
|
||||||
|
@ -2895,7 +2888,7 @@ void ScrollPane::ReceivedMessage(EsMessage *message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScrollPane::SetPosition(int axis, double newScroll, bool sendMovedMessage) {
|
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;
|
if (newScroll < 0) newScroll = 0;
|
||||||
else if (newScroll > limit[axis]) newScroll = limit[axis];
|
else if (newScroll > limit[axis]) newScroll = limit[axis];
|
||||||
if (newScroll == position[axis]) return;
|
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) {
|
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;
|
uint8_t *internalOffset = axis ? &parent->internalOffsetRight : &parent->internalOffsetBottom;
|
||||||
EsRectangle bounds = parent->GetBounds();
|
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);
|
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;
|
*internalOffset = axis ? bar[axis]->currentStyle->preferredWidth : bar[axis]->currentStyle->preferredHeight;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2950,8 +2943,8 @@ void ScrollPane::Refresh() {
|
||||||
InspectorNotifyElementEvent(parent, "scroll", "Refreshing scroll pane...\n");
|
InspectorNotifyElementEvent(parent, "scroll", "Refreshing scroll pane...\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
parent->internalOffsetRight = mode[1] == SCROLL_MODE_FIXED ? bar[1]->currentStyle->preferredWidth : 0;
|
parent->internalOffsetRight = mode[1] == ES_SCROLL_MODE_FIXED ? bar[1]->currentStyle->preferredWidth : 0;
|
||||||
parent->internalOffsetBottom = mode[0] == SCROLL_MODE_FIXED ? bar[0]->currentStyle->preferredHeight : 0;
|
parent->internalOffsetBottom = mode[0] == ES_SCROLL_MODE_FIXED ? bar[0]->currentStyle->preferredHeight : 0;
|
||||||
|
|
||||||
int64_t contentWidth = 0, contentHeight = 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.
|
// --------------------------------- Panels.
|
||||||
|
|
||||||
void PanelSwitcherTransitionComplete(EsPanel *panel) {
|
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;
|
if (flags & ES_PANEL_REVERSE) panel->flags |= ES_ELEMENT_LAYOUT_HINT_REVERSE;
|
||||||
|
|
||||||
panel->scroll.Setup(panel,
|
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_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) ? SCROLL_MODE_FIXED : (flags & ES_PANEL_V_SCROLL_AUTO) ? SCROLL_MODE_AUTO : 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);
|
ES_FLAGS_DEFAULT);
|
||||||
|
|
||||||
return panel;
|
return panel;
|
||||||
|
@ -3824,7 +3836,7 @@ EsCanvasPane *EsCanvasPaneCreate(EsElement *parent, uint64_t flags, const EsStyl
|
||||||
pane->Initialise(parent, flags, ProcessCanvasPaneMessage, style);
|
pane->Initialise(parent, flags, ProcessCanvasPaneMessage, style);
|
||||||
pane->cName = "canvas pane";
|
pane->cName = "canvas pane";
|
||||||
pane->zoom = 1.0;
|
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;
|
return pane;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1925,18 +1925,18 @@ void EsListViewChangeStyles(EsListView *view, const EsStyle *style, const EsStyl
|
||||||
view->scroll.fixedViewport[1] = 0;
|
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.
|
// because decreasing the secondary axis can only increase the primary axis.
|
||||||
|
|
||||||
uint8_t scrollXMode = 0, scrollYMode = 0;
|
uint8_t scrollXMode = 0, scrollYMode = 0;
|
||||||
|
|
||||||
if (view->flags & ES_LIST_VIEW_COLUMNS) {
|
if (view->flags & ES_LIST_VIEW_COLUMNS) {
|
||||||
scrollXMode = SCROLL_MODE_AUTO;
|
scrollXMode = ES_SCROLL_MODE_AUTO;
|
||||||
scrollYMode = SCROLL_MODE_AUTO;
|
scrollYMode = ES_SCROLL_MODE_AUTO;
|
||||||
} else if (view->flags & ES_LIST_VIEW_HORIZONTAL) {
|
} else if (view->flags & ES_LIST_VIEW_HORIZONTAL) {
|
||||||
scrollXMode = SCROLL_MODE_AUTO;
|
scrollXMode = ES_SCROLL_MODE_AUTO;
|
||||||
} else {
|
} else {
|
||||||
scrollYMode = SCROLL_MODE_AUTO;
|
scrollYMode = ES_SCROLL_MODE_AUTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
view->scroll.Setup(view, scrollXMode, scrollYMode, SCROLL_X_DRAG | SCROLL_Y_DRAG);
|
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 EsListDisplay EsElement;
|
||||||
opaque_type EsCanvasPane EsElement;
|
opaque_type EsCanvasPane EsElement;
|
||||||
opaque_type EsSlider EsElement;
|
opaque_type EsSlider EsElement;
|
||||||
|
opaque_type EsScrollView EsElement;
|
||||||
opaque_type EsTextPlan none;
|
opaque_type EsTextPlan none;
|
||||||
opaque_type EsPaintTarget none;
|
opaque_type EsPaintTarget none;
|
||||||
opaque_type EsUndoManager 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)
|
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
|
include desktop/icons.header
|
||||||
|
|
||||||
enum EsFatalError {
|
enum EsFatalError {
|
||||||
|
@ -2378,7 +2389,19 @@ function void EsElementGetTextStyle(EsElement *element, EsTextStyle *style);
|
||||||
function EsRectangle EsElementGetWindowBounds(EsElement *element, bool client = true);
|
function EsRectangle EsElementGetWindowBounds(EsElement *element, bool client = true);
|
||||||
function EsRectangle EsElementGetScreenBounds(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 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.
|
// Windows, menus, popups, toolbars and dialogs.
|
||||||
|
|
||||||
|
|
|
@ -4714,8 +4714,8 @@ EsTextbox *EsTextboxCreate(EsElement *parent, uint64_t flags, const EsStyle *sty
|
||||||
textbox->cName = "textbox";
|
textbox->cName = "textbox";
|
||||||
|
|
||||||
textbox->scroll.Setup(textbox,
|
textbox->scroll.Setup(textbox,
|
||||||
(flags & ES_TEXTBOX_MULTILINE) ? SCROLL_MODE_AUTO : SCROLL_MODE_HIDDEN,
|
(flags & ES_TEXTBOX_MULTILINE) ? ES_SCROLL_MODE_AUTO : ES_SCROLL_MODE_HIDDEN,
|
||||||
(flags & ES_TEXTBOX_MULTILINE) ? SCROLL_MODE_AUTO : SCROLL_MODE_NONE,
|
(flags & ES_TEXTBOX_MULTILINE) ? ES_SCROLL_MODE_AUTO : ES_SCROLL_MODE_NONE,
|
||||||
SCROLL_X_DRAG | SCROLL_Y_DRAG);
|
SCROLL_X_DRAG | SCROLL_Y_DRAG);
|
||||||
|
|
||||||
textbox->undo = &textbox->localUndo;
|
textbox->undo = &textbox->localUndo;
|
||||||
|
|
|
@ -477,3 +477,13 @@ EsCRTstrtod=475
|
||||||
EsCRTstrtof=476
|
EsCRTstrtof=476
|
||||||
EsOpenDocumentQueryInformation=477
|
EsOpenDocumentQueryInformation=477
|
||||||
EsDrawTextThemed=478
|
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