summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-08-11 22:33:19 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-08-11 22:33:19 +0300
commit38e09f15ff3e9c4781236016bfbb0b0f9062590b (patch)
tree43bf5e99e68d208056c9749d6e713502f66d143f /src
parent601f1dbde6f98b68ed6df9339bf6fafec16f0f57 (diff)
SidebarWidget: Scrolling and the scrollbar
Diffstat (limited to 'src')
-rw-r--r--src/gmdocument.c2
-rw-r--r--src/ui/scrollwidget.c4
-rw-r--r--src/ui/sidebarwidget.c54
-rw-r--r--src/ui/window.c2
4 files changed, 45 insertions, 17 deletions
diff --git a/src/gmdocument.c b/src/gmdocument.c
index c3559bf3..3fa4a32a 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -384,7 +384,7 @@ static void doLayout_GmDocument_(iGmDocument *d) {
384 /* Empty lines don't produce text runs. */ 384 /* Empty lines don't produce text runs. */
385 if (isEmpty_Range(&line)) { 385 if (isEmpty_Range(&line)) {
386 pos.y += lineHeight_Text(run.font); 386 pos.y += lineHeight_Text(run.font);
387 prevType = text_GmLineType; 387 prevType = type;
388 /* TODO: Extra skip needed here? */ 388 /* TODO: Extra skip needed here? */
389 continue; 389 continue;
390 } 390 }
diff --git a/src/ui/scrollwidget.c b/src/ui/scrollwidget.c
index 92139a60..d43a1fad 100644
--- a/src/ui/scrollwidget.c
+++ b/src/ui/scrollwidget.c
@@ -115,8 +115,8 @@ static void draw_ScrollWidget_(const iScrollWidget *d) {
115 iPaint p; 115 iPaint p;
116 init_Paint(&p); 116 init_Paint(&p);
117 drawRect_Paint(&p, bounds, black_ColorId); 117 drawRect_Paint(&p, bounds, black_ColorId);
118 fillRect_Paint(&p, shrunk_Rect(thumbRect_ScrollWidget_(d), init1_I2(gap_UI / 2)), 118 const iRect thumbRect = shrunk_Rect(thumbRect_ScrollWidget_(d), init_I2(gap_UI, gap_UI / 2));
119 isPressed ? orange_ColorId : gray25_ColorId); 119 fillRect_Paint(&p, thumbRect, isPressed ? orange_ColorId : tmQuote_ColorId);
120 } 120 }
121} 121}
122 122
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c
index 872d3f4a..fa550176 100644
--- a/src/ui/sidebarwidget.c
+++ b/src/ui/sidebarwidget.c
@@ -61,6 +61,31 @@ static void clearItems_SidebarWidget_(iSidebarWidget *d) {
61 clear_Array(&d->items); 61 clear_Array(&d->items);
62} 62}
63 63
64static iRect contentBounds_SidebarWidget_(const iSidebarWidget *d) {
65 iRect bounds = bounds_Widget(constAs_Widget(d));
66 adjustEdges_Rect(&bounds, as_Widget(d->modeButtons[0])->rect.size.y + gap_UI,
67 -constAs_Widget(d->scroll)->rect.size.x, -gap_UI, 0);
68 return bounds;
69}
70
71static int scrollMax_SidebarWidget_(const iSidebarWidget *d) {
72 return iMax(0,
73 (int) size_Array(&d->items) * d->itemHeight -
74 height_Rect(contentBounds_SidebarWidget_(d)));
75}
76
77static void updateVisible_SidebarWidget_(iSidebarWidget *d) {
78 // iWidget *w = as_Widget(d);
79 const int contentSize = size_Array(&d->items) * d->itemHeight;
80 const iRect bounds = contentBounds_SidebarWidget_(d);
81 setRange_ScrollWidget(d->scroll, (iRangei){ 0, scrollMax_SidebarWidget_(d) });
82 setThumb_ScrollWidget(d->scroll,
83 d->scrollY,
84 contentSize > 0 ? height_Rect(bounds_Widget(as_Widget(d->scroll))) *
85 height_Rect(bounds) / contentSize
86 : 0);
87}
88
64static void updateItems_SidebarWidget_(iSidebarWidget *d) { 89static void updateItems_SidebarWidget_(iSidebarWidget *d) {
65 clearItems_SidebarWidget_(d); 90 clearItems_SidebarWidget_(d);
66 switch (d->mode) { 91 switch (d->mode) {
@@ -84,6 +109,7 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) {
84 default: 109 default:
85 break; 110 break;
86 } 111 }
112 updateVisible_SidebarWidget_(d);
87 refresh_Widget(as_Widget(d)); 113 refresh_Widget(as_Widget(d));
88} 114}
89 115
@@ -131,12 +157,6 @@ void deinit_SidebarWidget(iSidebarWidget *d) {
131 deinit_Array(&d->items); 157 deinit_Array(&d->items);
132} 158}
133 159
134static iRect contentBounds_SidebarWidget_(const iSidebarWidget *d) {
135 iRect bounds = bounds_Widget(constAs_Widget(d));
136 adjustEdges_Rect(&bounds, as_Widget(d->modeButtons[0])->rect.size.y + gap_UI, 0, 0, 0);
137 return bounds;
138}
139
140static int visCount_SidebarWidget_(const iSidebarWidget *d) { 160static int visCount_SidebarWidget_(const iSidebarWidget *d) {
141 return iMin(height_Rect(bounds_Widget(constAs_Widget(d))) / d->itemHeight, 161 return iMin(height_Rect(bounds_Widget(constAs_Widget(d))) / d->itemHeight,
142 (int) size_Array(&d->items)); 162 (int) size_Array(&d->items));
@@ -174,17 +194,25 @@ static void scroll_SidebarWidget_(iSidebarWidget *d, int offset) {
174 if (d->scrollY < 0) { 194 if (d->scrollY < 0) {
175 d->scrollY = 0; 195 d->scrollY = 0;
176 } 196 }
177 const int scrollMax = iMax(0, 197 const int scrollMax = scrollMax_SidebarWidget_(d);
178 (int) size_Array(&d->items) * d->itemHeight -
179 height_Rect(contentBounds_SidebarWidget_(d)));
180 d->scrollY = iMin(d->scrollY, scrollMax); 198 d->scrollY = iMin(d->scrollY, scrollMax);
199 updateVisible_SidebarWidget_(d);
181 refresh_Widget(as_Widget(d)); 200 refresh_Widget(as_Widget(d));
182} 201}
183 202
184static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) { 203static iBool processEvent_SidebarWidget_(iSidebarWidget *d, const SDL_Event *ev) {
185 iWidget *w = as_Widget(d); 204 iWidget *w = as_Widget(d);
186 /* Handle commands. */ 205 /* Handle commands. */
187 if (ev->type == SDL_USEREVENT && ev->user.code == command_UserEventCode) { 206 if (isResize_UserEvent(ev)) {
207 updateVisible_SidebarWidget_(d);
208 }
209 else if (isCommand_Widget(w, ev, "scroll.moved")) {
210 d->scrollY = arg_Command(command_UserEvent(ev));
211 d->hoverItem = iInvalidPos;
212 refresh_Widget(w);
213 return iTrue;
214 }
215 else if (ev->type == SDL_USEREVENT && ev->user.code == command_UserEventCode) {
188 const char *cmd = command_UserEvent(ev); 216 const char *cmd = command_UserEvent(ev);
189 if (isCommand_Widget(w, ev, "sidebar.mode")) { 217 if (isCommand_Widget(w, ev, "sidebar.mode")) {
190 setMode_SidebarWidget(d, arg_Command(cmd)); 218 setMode_SidebarWidget(d, arg_Command(cmd));
@@ -240,7 +268,6 @@ static void draw_SidebarWidget_(const iSidebarWidget *d) {
240 init_Paint(&p); 268 init_Paint(&p);
241 /* Draw the items. */ { 269 /* Draw the items. */ {
242 const int font = default_FontId; 270 const int font = default_FontId;
243// /iConstForEach(Array, i, &d->items) {
244 const iRanges visRange = visRange_SidebarWidget_(d); 271 const iRanges visRange = visRange_SidebarWidget_(d);
245 iInt2 pos = addY_I2(topLeft_Rect(bounds), -(d->scrollY % d->itemHeight)); 272 iInt2 pos = addY_I2(topLeft_Rect(bounds), -(d->scrollY % d->itemHeight));
246 for (size_t i = visRange.start; i < visRange.end; i++) { 273 for (size_t i = visRange.start; i < visRange.end; i++) {
@@ -250,9 +277,10 @@ static void draw_SidebarWidget_(const iSidebarWidget *d) {
250 if (isHover) { 277 if (isHover) {
251 fillRect_Paint(&p, itemRect, isPressing ? orange_ColorId : teal_ColorId); 278 fillRect_Paint(&p, itemRect, isPressing ? orange_ColorId : teal_ColorId);
252 } 279 }
253 setClip_Paint(&p, itemRect); 280 setClip_Paint(&p, intersect_Rect(itemRect, bounds));
254 const int fg = isHover ? (isPressing ? black_ColorId : white_ColorId) : gray75_ColorId;
255 if (d->mode == documentOutline_SidebarMode) { 281 if (d->mode == documentOutline_SidebarMode) {
282 const int fg = isHover ? (isPressing ? black_ColorId : white_ColorId) :
283 (item->indent == 0 ? white_ColorId : gray75_ColorId);
256 drawRange_Text(font, init_I2(pos.x + 3 * gap_UI + item->indent, 284 drawRange_Text(font, init_I2(pos.x + 3 * gap_UI + item->indent,
257 mid_Rect(itemRect).y - lineHeight_Text(font) / 2), 285 mid_Rect(itemRect).y - lineHeight_Text(font) / 2),
258 fg, range_String(&item->label)); 286 fg, range_String(&item->label));
diff --git a/src/ui/window.c b/src/ui/window.c
index 10f1bba3..c68331a0 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -349,7 +349,7 @@ void init_Window(iWindow *d) {
349 fprintf(stderr, "Error when creating window: %s\n", SDL_GetError()); 349 fprintf(stderr, "Error when creating window: %s\n", SDL_GetError());
350 exit(-2); 350 exit(-2);
351 } 351 }
352 SDL_SetWindowMinimumSize(d->win, 320, 240); 352 SDL_SetWindowMinimumSize(d->win, 640, 400);
353 SDL_SetWindowTitle(d->win, "Lagrange"); 353 SDL_SetWindowTitle(d->win, "Lagrange");
354 /* Some info. */ { 354 /* Some info. */ {
355 SDL_RendererInfo info; 355 SDL_RendererInfo info;