diff options
Diffstat (limited to 'src/ui/listwidget.c')
-rw-r--r-- | src/ui/listwidget.c | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/src/ui/listwidget.c b/src/ui/listwidget.c index 3c061bdc..06689023 100644 --- a/src/ui/listwidget.c +++ b/src/ui/listwidget.c | |||
@@ -97,6 +97,11 @@ void invalidate_ListWidget(iListWidget *d) { | |||
97 | refresh_Widget(as_Widget(d)); | 97 | refresh_Widget(as_Widget(d)); |
98 | } | 98 | } |
99 | 99 | ||
100 | void invalidateItem_ListWidget(iListWidget *d, size_t index) { | ||
101 | insert_IntSet(&d->invalidItems, index); | ||
102 | refresh_Widget(d); | ||
103 | } | ||
104 | |||
100 | void clear_ListWidget(iListWidget *d) { | 105 | void clear_ListWidget(iListWidget *d) { |
101 | iForEach(PtrArray, i, &d->items) { | 106 | iForEach(PtrArray, i, &d->items) { |
102 | deref_Object(i.ptr); | 107 | deref_Object(i.ptr); |
@@ -124,14 +129,18 @@ static int scrollMax_ListWidget_(const iListWidget *d) { | |||
124 | } | 129 | } |
125 | 130 | ||
126 | void updateVisible_ListWidget(iListWidget *d) { | 131 | void updateVisible_ListWidget(iListWidget *d) { |
127 | const int contentSize = size_PtrArray(&d->items) * d->itemHeight; | 132 | const int contentSize = size_PtrArray(&d->items) * d->itemHeight; |
128 | const iRect bounds = innerBounds_Widget(as_Widget(d)); | 133 | const iRect bounds = innerBounds_Widget(as_Widget(d)); |
134 | const iBool wasVisible = isVisible_Widget(d->scroll); | ||
129 | setRange_ScrollWidget(d->scroll, (iRangei){ 0, scrollMax_ListWidget_(d) }); | 135 | setRange_ScrollWidget(d->scroll, (iRangei){ 0, scrollMax_ListWidget_(d) }); |
130 | setThumb_ScrollWidget(d->scroll, | 136 | setThumb_ScrollWidget(d->scroll, |
131 | d->scrollY, | 137 | d->scrollY, |
132 | contentSize > 0 ? height_Rect(bounds_Widget(as_Widget(d->scroll))) * | 138 | contentSize > 0 ? height_Rect(bounds_Widget(as_Widget(d->scroll))) * |
133 | height_Rect(bounds) / contentSize | 139 | height_Rect(bounds) / contentSize |
134 | : 0); | 140 | : 0); |
141 | if (wasVisible != isVisible_Widget(d->scroll)) { | ||
142 | invalidate_ListWidget(d); /* clip margins changed */ | ||
143 | } | ||
135 | } | 144 | } |
136 | 145 | ||
137 | void setItemHeight_ListWidget(iListWidget *d, int itemHeight) { | 146 | void setItemHeight_ListWidget(iListWidget *d, int itemHeight) { |
@@ -193,20 +202,28 @@ size_t itemIndex_ListWidget(const iListWidget *d, iInt2 pos) { | |||
193 | return index; | 202 | return index; |
194 | } | 203 | } |
195 | 204 | ||
196 | const iAnyObject *constHoverItem_ListWidget(const iListWidget *d) { | 205 | const iAnyObject *constItem_ListWidget(const iListWidget *d, size_t index) { |
197 | if (d->hoverItem < size_PtrArray(&d->items)) { | 206 | if (index < size_PtrArray(&d->items)) { |
198 | return constAt_PtrArray(&d->items, d->hoverItem); | 207 | return constAt_PtrArray(&d->items, index); |
199 | } | 208 | } |
200 | return NULL; | 209 | return NULL; |
201 | } | 210 | } |
202 | 211 | ||
203 | iAnyObject *hoverItem_ListWidget(iListWidget *d) { | 212 | const iAnyObject *constHoverItem_ListWidget(const iListWidget *d) { |
204 | if (d->hoverItem < size_PtrArray(&d->items)) { | 213 | return constItem_ListWidget(d, d->hoverItem); |
205 | return at_PtrArray(&d->items, d->hoverItem); | 214 | } |
215 | |||
216 | iAnyObject *item_ListWidget(iListWidget *d, size_t index) { | ||
217 | if (index < size_PtrArray(&d->items)) { | ||
218 | return at_PtrArray(&d->items, index); | ||
206 | } | 219 | } |
207 | return NULL; | 220 | return NULL; |
208 | } | 221 | } |
209 | 222 | ||
223 | iAnyObject *hoverItem_ListWidget(iListWidget *d) { | ||
224 | return item_ListWidget(d, d->hoverItem); | ||
225 | } | ||
226 | |||
210 | static void setHoverItem_ListWidget_(iListWidget *d, size_t index) { | 227 | static void setHoverItem_ListWidget_(iListWidget *d, size_t index) { |
211 | if (index < size_PtrArray(&d->items)) { | 228 | if (index < size_PtrArray(&d->items)) { |
212 | const iListItem *item = at_PtrArray(&d->items, index); | 229 | const iListItem *item = at_PtrArray(&d->items, index); |
@@ -265,7 +282,7 @@ static iBool processEvent_ListWidget_(iListWidget *d, const SDL_Event *ev) { | |||
265 | switch (processEvent_Click(&d->click, ev)) { | 282 | switch (processEvent_Click(&d->click, ev)) { |
266 | case started_ClickResult: | 283 | case started_ClickResult: |
267 | redrawHoverItem_ListWidget_(d); | 284 | redrawHoverItem_ListWidget_(d); |
268 | break; | 285 | return iTrue; |
269 | case aborted_ClickResult: | 286 | case aborted_ClickResult: |
270 | redrawHoverItem_ListWidget_(d); | 287 | redrawHoverItem_ListWidget_(d); |
271 | break; | 288 | break; |
@@ -277,7 +294,7 @@ static iBool processEvent_ListWidget_(iListWidget *d, const SDL_Event *ev) { | |||
277 | postCommand_Widget(w, "list.clicked arg:%zu item:%p", | 294 | postCommand_Widget(w, "list.clicked arg:%zu item:%p", |
278 | d->hoverItem, constHoverItem_ListWidget(d)); | 295 | d->hoverItem, constHoverItem_ListWidget(d)); |
279 | } | 296 | } |
280 | break; | 297 | return iTrue; |
281 | default: | 298 | default: |
282 | break; | 299 | break; |
283 | } | 300 | } |
@@ -382,7 +399,15 @@ static void draw_ListWidget_(const iListWidget *d) { | |||
382 | fillRect_Paint(&p, itemRect, w->bgColor); | 399 | fillRect_Paint(&p, itemRect, w->bgColor); |
383 | } | 400 | } |
384 | class_ListItem(item)->draw(item, &p, itemRect, d); | 401 | class_ListItem(item)->draw(item, &p, itemRect, d); |
385 | unsetClip_Paint(&p); | 402 | /* Clear under the scrollbar. */ |
403 | if (isVisible_Widget(d->scroll)) { | ||
404 | fillRect_Paint( | ||
405 | &p, | ||
406 | (iRect){ addX_I2(topRight_Rect(itemRect), -width_Widget(d->scroll)), | ||
407 | bottomRight_Rect(itemRect) }, | ||
408 | w->bgColor); | ||
409 | } | ||
410 | unsetClip_Paint(&p); | ||
386 | } | 411 | } |
387 | pos.y += d->itemHeight; | 412 | pos.y += d->itemHeight; |
388 | } | 413 | } |