summaryrefslogtreecommitdiff
path: root/src/ui/listwidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/listwidget.c')
-rw-r--r--src/ui/listwidget.c47
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
100void invalidateItem_ListWidget(iListWidget *d, size_t index) {
101 insert_IntSet(&d->invalidItems, index);
102 refresh_Widget(d);
103}
104
100void clear_ListWidget(iListWidget *d) { 105void 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
126void updateVisible_ListWidget(iListWidget *d) { 131void 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
137void setItemHeight_ListWidget(iListWidget *d, int itemHeight) { 146void 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
196const iAnyObject *constHoverItem_ListWidget(const iListWidget *d) { 205const 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
203iAnyObject *hoverItem_ListWidget(iListWidget *d) { 212const 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
216iAnyObject *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
223iAnyObject *hoverItem_ListWidget(iListWidget *d) {
224 return item_ListWidget(d, d->hoverItem);
225}
226
210static void setHoverItem_ListWidget_(iListWidget *d, size_t index) { 227static 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 }