summaryrefslogtreecommitdiff
path: root/src/ui/listwidget.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-09-24 07:36:08 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-09-24 07:36:08 +0300
commit446df26adb969dcb4dd9cf5e171fbb9453a8e27c (patch)
tree562c647f7c9dc907d34e263d44c9a414a80a8017 /src/ui/listwidget.c
parent27ebfc904b9b3eac3ef5479ed0d0ba166fac1543 (diff)
SidebarWidget: Reordering bookmarks manually
One can now drag and drop bookmarks to change their order in the list.
Diffstat (limited to 'src/ui/listwidget.c')
-rw-r--r--src/ui/listwidget.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/src/ui/listwidget.c b/src/ui/listwidget.c
index 6a1372ab..a34f3d03 100644
--- a/src/ui/listwidget.c
+++ b/src/ui/listwidget.c
@@ -277,7 +277,7 @@ size_t hoverItemIndex_ListWidget(const iListWidget *d) {
277 return d->hoverItem; 277 return d->hoverItem;
278} 278}
279 279
280static void setHoverItem_ListWidget_(iListWidget *d, size_t index) { 280void setHoverItem_ListWidget(iListWidget *d, size_t index) {
281 if (index < size_PtrArray(&d->items)) { 281 if (index < size_PtrArray(&d->items)) {
282 const iListItem *item = at_PtrArray(&d->items, index); 282 const iListItem *item = at_PtrArray(&d->items, index);
283 if (item->isSeparator) { 283 if (item->isSeparator) {
@@ -294,7 +294,7 @@ static void setHoverItem_ListWidget_(iListWidget *d, size_t index) {
294 294
295void updateMouseHover_ListWidget(iListWidget *d) { 295void updateMouseHover_ListWidget(iListWidget *d) {
296 const iInt2 mouse = mouseCoord_Window(get_Window(), 0); 296 const iInt2 mouse = mouseCoord_Window(get_Window(), 0);
297 setHoverItem_ListWidget_(d, itemIndex_ListWidget(d, mouse)); 297 setHoverItem_ListWidget(d, itemIndex_ListWidget(d, mouse));
298} 298}
299 299
300void sort_ListWidget(iListWidget *d, int (*cmp)(const iListItem **item1, const iListItem **item2)) { 300void sort_ListWidget(iListWidget *d, int (*cmp)(const iListItem **item1, const iListItem **item2)) {
@@ -318,19 +318,18 @@ static void updateHover_ListWidget_(iListWidget *d, const iInt2 mouse) {
318 contains_Widget(constAs_Widget(d), mouse)) { 318 contains_Widget(constAs_Widget(d), mouse)) {
319 hover = itemIndex_ListWidget(d, mouse); 319 hover = itemIndex_ListWidget(d, mouse);
320 } 320 }
321 setHoverItem_ListWidget_(d, hover); 321 setHoverItem_ListWidget(d, hover);
322} 322}
323 323
324static size_t resolveDragDestination_ListWidget_(const iListWidget *d, iInt2 dstPos, iBool *isOnto) { 324static size_t resolveDragDestination_ListWidget_(const iListWidget *d, iInt2 dstPos, iBool *isOnto) {
325 size_t index = itemIndex_ListWidget(d, dstPos); 325 size_t index = itemIndex_ListWidget(d, dstPos);
326 const iRect rect = itemRect_ListWidget(d, index);
327 const iListItem *item = constItem_ListWidget(d, index); 326 const iListItem *item = constItem_ListWidget(d, index);
328 const iRangei span = ySpan_Rect(rect);
329 if (!item) { 327 if (!item) {
330 item = constItem_ListWidget( 328 index = (dstPos.y < mid_Rect(bounds_Widget(constAs_Widget(d))).y ? 0 : (numItems_ListWidget(d) - 1));
331 d, 329 item = constItem_ListWidget(d, index);
332 dstPos.y < mid_Rect(bounds_Widget(constAs_Widget(d))).y ? 0 : (numItems_ListWidget(d) - 1));
333 } 330 }
331 const iRect rect = itemRect_ListWidget(d, index);
332 const iRangei span = ySpan_Rect(rect);
334 if (item->isDropTarget) { 333 if (item->isDropTarget) {
335 const int pad = size_Range(&span) / 4; 334 const int pad = size_Range(&span) / 4;
336 if (dstPos.y >= span.start + pad && dstPos.y < span.end) { 335 if (dstPos.y >= span.start + pad && dstPos.y < span.end) {
@@ -350,6 +349,7 @@ static iBool endDrag_ListWidget_(iListWidget *d, iInt2 endPos) {
350 if (d->dragItem == iInvalidPos) { 349 if (d->dragItem == iInvalidPos) {
351 return iFalse; 350 return iFalse;
352 } 351 }
352 stop_Anim(&d->scrollY.pos);
353 iBool isOnto; 353 iBool isOnto;
354 const size_t index = resolveDragDestination_ListWidget_(d, endPos, &isOnto); 354 const size_t index = resolveDragDestination_ListWidget_(d, endPos, &isOnto);
355 if (isOnto) { 355 if (isOnto) {
@@ -385,14 +385,34 @@ static iBool processEvent_ListWidget_(iListWidget *d, const SDL_Event *ev) {
385 d->noHoverWhileScrolling = iFalse; 385 d->noHoverWhileScrolling = iFalse;
386 } 386 }
387 if (ev->type == SDL_MOUSEMOTION) { 387 if (ev->type == SDL_MOUSEMOTION) {
388 const iInt2 mousePos = init_I2(ev->motion.x, ev->motion.y);
388 if (ev->motion.state == 0 /* not dragging */) { 389 if (ev->motion.state == 0 /* not dragging */) {
389 if (ev->motion.which != SDL_TOUCH_MOUSEID) { 390 if (ev->motion.which != SDL_TOUCH_MOUSEID) {
390 d->noHoverWhileScrolling = iFalse; 391 d->noHoverWhileScrolling = iFalse;
391 } 392 }
392 updateHover_ListWidget_(d, init_I2(ev->motion.x, ev->motion.y)); 393 updateHover_ListWidget_(d, mousePos);
393 } 394 }
394 else if (d->dragItem != iInvalidPos) { 395 else if (d->dragItem != iInvalidPos) {
395 refresh_Widget(d); 396 /* Start scrolling if near the ends. */
397 const int zone = d->itemHeight;
398 const iRect bounds = bounds_Widget(w);
399 float scrollSpeed = 0.0f;
400 if (mousePos.y > bottom_Rect(bounds) - zone) {
401 scrollSpeed = (mousePos.y - bottom_Rect(bounds) + zone) / (float) zone;
402 }
403 else if (mousePos.y < top_Rect(bounds) + zone) {
404 scrollSpeed = -(top_Rect(bounds) + zone - mousePos.y) / (float) zone;
405 }
406 scrollSpeed = iClamp(scrollSpeed, -1.0f, 1.0f);
407 if (iAbs(scrollSpeed) < 0.001f) {
408 stop_Anim(&d->scrollY.pos);
409 refresh_Widget(d);
410 }
411 else {
412 setValueSpeed_Anim(&d->scrollY.pos, scrollSpeed < 0 ? 0 : scrollMax_ListWidget_(d),
413 iAbs(scrollSpeed * gap_UI * 100));
414 refreshWhileScrolling_ListWidget_(d);
415 }
396 } 416 }
397 } 417 }
398 if (ev->type == SDL_MOUSEWHEEL && isHover_Widget(w)) { 418 if (ev->type == SDL_MOUSEWHEEL && isHover_Widget(w)) {
@@ -416,7 +436,12 @@ static iBool processEvent_ListWidget_(iListWidget *d, const SDL_Event *ev) {
416 redrawHoverItem_ListWidget_(d); 436 redrawHoverItem_ListWidget_(d);
417 return iTrue; 437 return iTrue;
418 case aborted_ClickResult: 438 case aborted_ClickResult:
419 endDrag_ListWidget_(d, pos_Click(&d->click)); 439// endDrag_ListWidget_(d, pos_Click(&d->click));
440 if (d->dragItem != iInvalidPos) {
441 stop_Anim(&d->scrollY.pos);
442 invalidateItem_ListWidget(d, d->dragItem);
443 d->dragItem = iInvalidPos;
444 }
420 redrawHoverItem_ListWidget_(d); 445 redrawHoverItem_ListWidget_(d);
421 break; 446 break;
422 case drag_ClickResult: 447 case drag_ClickResult:
@@ -436,7 +461,7 @@ static iBool processEvent_ListWidget_(iListWidget *d, const SDL_Event *ev) {
436 return iTrue; 461 return iTrue;
437 } 462 }
438 redrawHoverItem_ListWidget_(d); 463 redrawHoverItem_ListWidget_(d);
439 if (contains_Rect(innerBounds_Widget(w), pos_Click(&d->click)) && 464 if (contains_Rect(itemRect_ListWidget(d, d->hoverItem), pos_Click(&d->click)) &&
440 d->hoverItem != iInvalidPos) { 465 d->hoverItem != iInvalidPos) {
441 postCommand_Widget(w, "list.clicked arg:%zu item:%p", 466 postCommand_Widget(w, "list.clicked arg:%zu item:%p",
442 d->hoverItem, constHoverItem_ListWidget(d)); 467 d->hoverItem, constHoverItem_ListWidget(d));
@@ -542,14 +567,10 @@ static void draw_ListWidget_(const iListWidget *d) {
542 const iListItem *item = constAt_PtrArray(&d->items, d->dragItem); 567 const iListItem *item = constAt_PtrArray(&d->items, d->dragItem);
543 const iRect itemRect = { init_I2(left_Rect(bounds), pos.y), init_I2(d->visBuf->texSize.x, d->itemHeight) }; 568 const iRect itemRect = { init_I2(left_Rect(bounds), pos.y), init_I2(d->visBuf->texSize.x, d->itemHeight) };
544 SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_BLEND); 569 SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_BLEND);
545// setOpacity_Text(0.25f);
546// SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_NONE);
547// setOpacity_Text(1.0f);
548 iBool dstOnto; 570 iBool dstOnto;
549 const size_t dstIndex = resolveDragDestination_ListWidget_(d, mousePos, &dstOnto); 571 const size_t dstIndex = resolveDragDestination_ListWidget_(d, mousePos, &dstOnto);
550 if (dstIndex != d->dragItem && dstIndex != d->dragItem + 1) { 572 if (dstIndex != d->dragItem && dstIndex != d->dragItem + 1) {
551 const iRect dstRect = itemRect_ListWidget(d, dstIndex); 573 const iRect dstRect = itemRect_ListWidget(d, dstIndex);
552// SDL_SetRenderDrawBlendMode(renderer_Window(get_Window()), SDL_BLENDMODE_BLEND);
553 p.alpha = 0xff; 574 p.alpha = 0xff;
554 if (dstOnto) { 575 if (dstOnto) {
555 fillRect_Paint(&p, dstRect, uiTextAction_ColorId); 576 fillRect_Paint(&p, dstRect, uiTextAction_ColorId);