diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-11-23 16:16:29 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-11-23 16:16:29 +0200 |
commit | adfd2d702195103e69a3cacdeadb9709ba9be130 (patch) | |
tree | 631f40093031e053bef7960caf9a7d2c92a73f73 /src | |
parent | 678ed94bf55bc15592d14aed1ace04863e5483d1 (diff) |
SidebarWidget: Date separators in Feeds
Diffstat (limited to 'src')
-rw-r--r-- | src/feeds.c | 7 | ||||
-rw-r--r-- | src/ui/sidebarwidget.c | 79 |
2 files changed, 59 insertions, 27 deletions
diff --git a/src/feeds.c b/src/feeds.c index 5034c616..7e54a633 100644 --- a/src/feeds.c +++ b/src/feeds.c | |||
@@ -440,6 +440,11 @@ void deinit_Feeds(void) { | |||
440 | deinit_SortedArray(&d->entries); | 440 | deinit_SortedArray(&d->entries); |
441 | } | 441 | } |
442 | 442 | ||
443 | static int cmpTimeDescending_FeedEntryPtr_(const void *a, const void *b) { | ||
444 | const iFeedEntry * const *e1 = a, * const *e2 = b; | ||
445 | return -cmp_Time(&(*e1)->timestamp, &(*e2)->timestamp); | ||
446 | } | ||
447 | |||
443 | const iPtrArray *listEntries_Feeds(void) { | 448 | const iPtrArray *listEntries_Feeds(void) { |
444 | iFeeds *d = &feeds_; | 449 | iFeeds *d = &feeds_; |
445 | lock_Mutex(d->mtx); | 450 | lock_Mutex(d->mtx); |
@@ -447,6 +452,6 @@ const iPtrArray *listEntries_Feeds(void) { | |||
447 | of the array in case the worker modifies it. */ | 452 | of the array in case the worker modifies it. */ |
448 | iPtrArray *list = collect_PtrArray(copy_Array(&d->entries.values)); | 453 | iPtrArray *list = collect_PtrArray(copy_Array(&d->entries.values)); |
449 | unlock_Mutex(d->mtx); | 454 | unlock_Mutex(d->mtx); |
450 | /* TODO: Sort the entries based on time. */ | 455 | sort_Array(list, cmpTimeDescending_FeedEntryPtr_); |
451 | return list; | 456 | return list; |
452 | } | 457 | } |
diff --git a/src/ui/sidebarwidget.c b/src/ui/sidebarwidget.c index aac7459e..3cde7c3f 100644 --- a/src/ui/sidebarwidget.c +++ b/src/ui/sidebarwidget.c | |||
@@ -113,9 +113,25 @@ static void updateItems_SidebarWidget_(iSidebarWidget *d) { | |||
113 | d->menu = NULL; | 113 | d->menu = NULL; |
114 | switch (d->mode) { | 114 | switch (d->mode) { |
115 | case feeds_SidebarMode: { | 115 | case feeds_SidebarMode: { |
116 | iDate on; | ||
117 | iZap(on); | ||
116 | iConstForEach(PtrArray, i, listEntries_Feeds()) { | 118 | iConstForEach(PtrArray, i, listEntries_Feeds()) { |
117 | const iFeedEntry *entry = i.ptr; | 119 | const iFeedEntry *entry = i.ptr; |
118 | /* TODO: Insert date separators. */ | 120 | /* Insert date separators. */ { |
121 | iDate entryDate; | ||
122 | init_Date(&entryDate, &entry->timestamp); | ||
123 | if (on.year != entryDate.year || on.month != entryDate.month || | ||
124 | on.day != entryDate.day) { | ||
125 | on = entryDate; | ||
126 | iSidebarItem *sep = new_SidebarItem(); | ||
127 | sep->listItem.isSeparator = iTrue; | ||
128 | iString *text = format_Date(&on, "%Y %b %d"); | ||
129 | set_String(&sep->meta, text); | ||
130 | delete_String(text); | ||
131 | addItem_ListWidget(d->list, sep); | ||
132 | iRelease(sep); | ||
133 | } | ||
134 | } | ||
119 | iSidebarItem *item = new_SidebarItem(); | 135 | iSidebarItem *item = new_SidebarItem(); |
120 | item->icon = 0; | 136 | item->icon = 0; |
121 | const iTime visitTime = urlVisitTime_Visited(visited_App(), &entry->url); | 137 | const iTime visitTime = urlVisitTime_Visited(visited_App(), &entry->url); |
@@ -303,7 +319,7 @@ iBool setMode_SidebarWidget(iSidebarWidget *d, enum iSidebarMode mode) { | |||
303 | for (enum iSidebarMode i = 0; i < max_SidebarMode; i++) { | 319 | for (enum iSidebarMode i = 0; i < max_SidebarMode; i++) { |
304 | setFlags_Widget(as_Widget(d->modeButtons[i]), selected_WidgetFlag, i == d->mode); | 320 | setFlags_Widget(as_Widget(d->modeButtons[i]), selected_WidgetFlag, i == d->mode); |
305 | } | 321 | } |
306 | const float heights[max_SidebarMode] = { 2.5f, 1.333f, 1.333f, 3.5f, 1.2f }; | 322 | const float heights[max_SidebarMode] = { 2.333f, 1.333f, 1.333f, 3.5f, 1.2f }; |
307 | setBackgroundColor_Widget(as_Widget(d->list), | 323 | setBackgroundColor_Widget(as_Widget(d->list), |
308 | d->mode == documentOutline_SidebarMode ? tmBannerBackground_ColorId | 324 | d->mode == documentOutline_SidebarMode ? tmBannerBackground_ColorId |
309 | : uiBackground_ColorId); | 325 | : uiBackground_ColorId); |
@@ -858,27 +874,38 @@ static void draw_SidebarItem_(const iSidebarItem *d, iPaint *p, iRect itemRect, | |||
858 | else if (sidebar->mode == feeds_SidebarMode) { | 874 | else if (sidebar->mode == feeds_SidebarMode) { |
859 | const int fg = isHover ? (isPressing ? uiTextPressed_ColorId : uiTextFramelessHover_ColorId) | 875 | const int fg = isHover ? (isPressing ? uiTextPressed_ColorId : uiTextFramelessHover_ColorId) |
860 | : uiText_ColorId; | 876 | : uiText_ColorId; |
861 | const int h1 = lineHeight_Text(uiLabel_FontId); | 877 | if (d->listItem.isSeparator) { |
862 | const int h2 = lineHeight_Text(uiContent_FontId); | 878 | drawRange_Text( |
863 | const iRect iconArea = { addY_I2(pos, h1), init_I2(7 * gap_UI, itemHeight - h1) }; | 879 | uiLabelLarge_FontId, |
864 | if (d->icon) { | 880 | add_I2(pos, |
865 | iString str; | 881 | init_I2(3 * gap_UI, |
866 | initUnicodeN_String(&str, &d->icon, 1); | 882 | itemHeight - lineHeight_Text(uiLabelLarge_FontId) - 2 * gap_UI)), |
867 | drawCentered_Text(uiContent_FontId, iconArea, iFalse, iconColor, "%s", cstr_String(&str)); | 883 | uiIcon_ColorId, |
868 | deinit_String(&str); | 884 | range_String(&d->meta)); |
869 | } | 885 | } |
870 | pos = add_I2(pos, init_I2(7 * gap_UI, (itemHeight - h1 - h2) / 2)); | 886 | else { |
871 | draw_Text(uiLabel_FontId, | 887 | const int h1 = lineHeight_Text(uiLabel_FontId); |
872 | pos, | 888 | const int h2 = lineHeight_Text(uiContent_FontId); |
873 | isPressing ? fg : uiHeading_ColorId, | 889 | const iRect iconArea = { addY_I2(pos, h1), init_I2(7 * gap_UI, itemHeight - h1) }; |
874 | "%s", | 890 | if (d->icon) { |
875 | cstr_String(&d->meta)); | 891 | iString str; |
876 | pos.y += h1; | 892 | initUnicodeN_String(&str, &d->icon, 1); |
877 | draw_Text(uiContent_FontId, | 893 | drawCentered_Text(uiContent_FontId, iconArea, iFalse, iconColor, "%s", cstr_String(&str)); |
878 | pos, | 894 | deinit_String(&str); |
879 | isPressing ? fg : uiTextStrong_ColorId, | 895 | } |
880 | "%s", | 896 | pos = add_I2(pos, init_I2(7 * gap_UI, (itemHeight - h1 - h2) / 2)); |
881 | cstr_String(&d->label)); | 897 | draw_Text(uiLabel_FontId, |
898 | pos, | ||
899 | isPressing ? fg : uiHeading_ColorId, | ||
900 | "%s", | ||
901 | cstr_String(&d->meta)); | ||
902 | pos.y += h1; | ||
903 | draw_Text(uiContent_FontId, | ||
904 | pos, | ||
905 | isPressing ? fg : uiTextStrong_ColorId, | ||
906 | "%s", | ||
907 | cstr_String(&d->label)); | ||
908 | } | ||
882 | } | 909 | } |
883 | else if (sidebar->mode == bookmarks_SidebarMode) { | 910 | else if (sidebar->mode == bookmarks_SidebarMode) { |
884 | const int fg = isHover ? (isPressing ? uiTextPressed_ColorId : uiTextFramelessHover_ColorId) | 911 | const int fg = isHover ? (isPressing ? uiTextPressed_ColorId : uiTextFramelessHover_ColorId) |
@@ -899,11 +926,11 @@ static void draw_SidebarItem_(const iSidebarItem *d, iPaint *p, iRect itemRect, | |||
899 | if (d->listItem.isSeparator) { | 926 | if (d->listItem.isSeparator) { |
900 | if (!isEmpty_String(&d->meta)) { | 927 | if (!isEmpty_String(&d->meta)) { |
901 | iInt2 drawPos = addY_I2(topLeft_Rect(itemRect), d->id); | 928 | iInt2 drawPos = addY_I2(topLeft_Rect(itemRect), d->id); |
902 | drawHLine_Paint(p, drawPos, width_Rect(itemRect), uiIcon_ColorId); | 929 | drawHLine_Paint(p, addY_I2(drawPos, -gap_UI), width_Rect(itemRect), uiIcon_ColorId); |
903 | drawRange_Text( | 930 | drawRange_Text( |
904 | default_FontId, | 931 | uiLabelLarge_FontId, |
905 | add_I2(drawPos, | 932 | add_I2(drawPos, |
906 | init_I2(3 * gap_UI, (itemHeight - lineHeight_Text(default_FontId)) / 2)), | 933 | init_I2(3 * gap_UI, (itemHeight - lineHeight_Text(uiLabelLarge_FontId)) / 2)), |
907 | uiIcon_ColorId, | 934 | uiIcon_ColorId, |
908 | range_String(&d->meta)); | 935 | range_String(&d->meta)); |
909 | } | 936 | } |