summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/constants.h2
-rw-r--r--src/input.c5
-rw-r--r--src/layout.c6
-rw-r--r--src/render.c22
-rw-r--r--src/widget/widget.h10
5 files changed, 39 insertions, 6 deletions
diff --git a/src/constants.h b/src/constants.h
index 457f461..0d93d14 100644
--- a/src/constants.h
+++ b/src/constants.h
@@ -4,4 +4,4 @@
4#define MaxWidgetEvents 8 4#define MaxWidgetEvents 8
5 5
6// Width of scroll bars in pixels. 6// Width of scroll bars in pixels.
7#define ScrollBarWidth 16 7#define ScrollBarWidth 32
diff --git a/src/input.c b/src/input.c
index c4b1be7..20551a6 100644
--- a/src/input.c
+++ b/src/input.c
@@ -6,6 +6,7 @@
6 6
7#include <cassert.h> 7#include <cassert.h>
8 8
9#define Min(a, b) ((a) < (b) ? (a) : (b))
9#define Max(a, b) ((a) > (b) ? (a) : (b)) 10#define Max(a, b) ((a) > (b) ? (a) : (b))
10 11
11/// Return true if the rectangle contains the point. 12/// Return true if the rectangle contains the point.
@@ -85,7 +86,9 @@ static void ClickTable(uiTable* table, const uiMouseClickEvent* event) {
85static void ScrollTable(uiTable* table, const uiMouseScrollEvent* event) { 86static void ScrollTable(uiTable* table, const uiMouseScrollEvent* event) {
86 assert(table); 87 assert(table);
87 assert(event); 88 assert(event);
88 table->offset = Max(0, table->offset - event->scroll_offset); 89 table->offset =
90 Min(table->rows - table->num_visible_rows,
91 Max(0, table->offset - event->scroll_offset));
89} 92}
90 93
91/// Process a scroll event. 94/// Process a scroll event.
diff --git a/src/layout.c b/src/layout.c
index 9d4b556..f83976f 100644
--- a/src/layout.c
+++ b/src/layout.c
@@ -13,6 +13,12 @@ static void ResizeTable(uiTable* table, int width, int height) {
13 return; 13 return;
14 } 14 }
15 15
16 table->height = height;
17
18 // Compute the number of rows that are visible at once.
19 table->num_visible_rows = height / g_ui.font->header.glyph_height;
20 assert(table->num_visible_rows <= table->rows);
21
16 // Determine if there is vertical overflow. This determines whether we need to 22 // Determine if there is vertical overflow. This determines whether we need to
17 // render a scroll bar, in which case room must be made for it. 23 // render a scroll bar, in which case room must be made for it.
18 table->flags.vertical_overflow = 24 table->flags.vertical_overflow =
diff --git a/src/render.c b/src/render.c
index 24490c0..b1fd3e8 100644
--- a/src/render.c
+++ b/src/render.c
@@ -186,6 +186,8 @@ static void RenderTable(const uiTable* table, RenderState* state) {
186 uiRect original_subsurface = {0}; 186 uiRect original_subsurface = {0};
187 uiPoint original_pen = {0}; 187 uiPoint original_pen = {0};
188 188
189 int col_widths_sum = 0;
190
189 // Render header. 191 // Render header.
190 if (table->header) { 192 if (table->header) {
191 for (int col = 0; col < table->cols; ++col) { 193 for (int col = 0; col < table->cols; ++col) {
@@ -201,6 +203,9 @@ static void RenderTable(const uiTable* table, RenderState* state) {
201 // Reset the original subsurface and pen for subsequent columns. 203 // Reset the original subsurface and pen for subsequent columns.
202 PopSubsurface(state, &original_subsurface, &original_pen); 204 PopSubsurface(state, &original_subsurface, &original_pen);
203 205
206 // Keep track of the sum of column widths to later render the scroll bar.
207 col_widths_sum += table->widths[col];
208
204 // Next column. 209 // Next column.
205 state->pen.x += table->widths[col]; 210 state->pen.x += table->widths[col];
206 } 211 }
@@ -235,6 +240,23 @@ static void RenderTable(const uiTable* table, RenderState* state) {
235 state->pen.y += g_ui.font->header.glyph_height; 240 state->pen.y += g_ui.font->header.glyph_height;
236 } 241 }
237 state->pen.y = y0; 242 state->pen.y = y0;
243
244 // Render scrollbar.
245 if (table->flags.vertical_overflow) {
246 state->pen.x = col_widths_sum;
247
248 const int y_start = (int)((double)table->offset / (double)table->rows *
249 (double)table->height);
250
251 const int height = (int)((double)table->num_visible_rows /
252 (double)table->rows * (double)table->height);
253
254 FillRect(
255 &(uiRect){.y = y_start, .width = ScrollBarWidth, .height = height},
256 uiPink, state);
257
258 state->pen.x = x0;
259 }
238} 260}
239 261
240/// Render a widget. 262/// Render a widget.
diff --git a/src/widget/widget.h b/src/widget/widget.h
index a2c96bc..c75bd65 100644
--- a/src/widget/widget.h
+++ b/src/widget/widget.h
@@ -54,10 +54,12 @@ typedef struct uiTable {
54 uiWidget widget; 54 uiWidget widget;
55 int rows; 55 int rows;
56 int cols; 56 int cols;
57 int* widths; // Width, in pixels, for each column. 57 int height; // Height in pixels.
58 uiCell* header; // If non-null, row of 'cols' header cells. 58 int* widths; // Width, in pixels, for each column.
59 uiCell** cells; // Array of 'rows' rows, each of 'cols' cells. 59 uiCell* header; // If non-null, row of 'cols' header cells.
60 int offset; // Offset into the rows of the table. Units: rows. 60 uiCell** cells; // Array of 'rows' rows, each of 'cols' cells.
61 int offset; // Offset into the rows of the table. Units: rows.
62 int num_visible_rows; // The number of rows that are visible at once.
61 struct { 63 struct {
62 bool vertical_overflow : 1; // True if contents overflow vertically. 64 bool vertical_overflow : 1; // True if contents overflow vertically.
63 } flags; 65 } flags;