This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch main
in repository eradio.
View the commit online.
commit 67007fa1d502f7f234e8fe8b4a96704ed26a50a3
Author: politebot <[email protected]>
AuthorDate: Fri Oct 10 18:35:17 2025 -0500
Add a toolbar, favorites view
---
src/appdata.h | 8 +++++-
src/http.c | 3 ++-
src/station_list.c | 74 ++++++++++++++++++++++++++++++++++++++++++------------
src/ui.c | 67 ++++++++++++++++++++++++++++++++++++------------
4 files changed, 118 insertions(+), 34 deletions(-)
diff --git a/src/appdata.h b/src/appdata.h
index 8531af1..29ad24e 100644
--- a/src/appdata.h
+++ b/src/appdata.h
@@ -13,6 +13,11 @@ typedef struct _Station
Eina_Bool favorite;
} Station;
+typedef enum {
+ VIEW_SEARCH,
+ VIEW_FAVORITES
+} ViewMode;
+
typedef struct _AppData
{
Evas_Object *win;
@@ -23,9 +28,10 @@ typedef struct _AppData
Evas_Object *play_pause_btn;
Evas_Object *stop_btn;
Evas_Object *search_btn;
+ Evas_Object *search_bar;
Eina_List *stations;
Eina_Bool playing;
Eina_Hash *favorites;
Eina_List *favorites_stations;
- Evas_Object *favorites_btn;
+ ViewMode view_mode;
} AppData;
diff --git a/src/http.c b/src/http.c
index e59bed8..33d3bc2 100644
--- a/src/http.c
+++ b/src/http.c
@@ -236,7 +236,8 @@ _handle_station_list_complete(Ecore_Con_Event_Url_Complete *ev)
}
favorites_apply_to_stations(ad);
- station_list_populate(ad, ad->stations);
+ if (ad->view_mode == VIEW_SEARCH)
+ station_list_populate(ad, ad->stations);
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);
diff --git a/src/station_list.c b/src/station_list.c
index 7ccab08..0de62dc 100644
--- a/src/station_list.c
+++ b/src/station_list.c
@@ -4,6 +4,7 @@
#include "favorites.h"
static void _favorite_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
+static void _favorite_remove_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
static void
_station_click_counter_request(Station *st)
@@ -52,26 +53,43 @@ station_list_populate(AppData *ad, Eina_List *stations)
{
Evas_Object *icon = elm_icon_add(ad->win);
elm_icon_standard_set(icon, "radio");
- Evas_Object *fav_btn = elm_button_add(ad->win);
- evas_object_size_hint_min_set(fav_btn, 40, 40);
- evas_object_propagate_events_set(fav_btn, EINA_FALSE);
- if (st->favorite)
- elm_object_text_set(fav_btn, "★");
- else
- elm_object_text_set(fav_btn, "☆");
+ Evas_Object *fav_btn = NULL;
+ if (ad->view_mode == VIEW_SEARCH)
+ {
+ fav_btn = elm_button_add(ad->win);
+ evas_object_size_hint_min_set(fav_btn, 40, 40);
+ evas_object_propagate_events_set(fav_btn, EINA_FALSE);
+ if (st->favorite)
+ elm_object_text_set(fav_btn, "★");
+ else
+ elm_object_text_set(fav_btn, "☆");
+ }
+ else if (ad->view_mode == VIEW_FAVORITES)
+ {
+ fav_btn = elm_button_add(ad->win);
+ evas_object_size_hint_min_set(fav_btn, 60, 30);
+ evas_object_propagate_events_set(fav_btn, EINA_FALSE);
+ elm_object_text_set(fav_btn, "Remove");
+ }
Elm_Object_Item *li = elm_list_item_append(ad->list, st->name, icon, fav_btn, _list_item_selected_cb, ad);
elm_object_item_data_set(li, st);
- // Attach callback with context so we can save favorites on toggle
- typedef struct {
- AppData *ad;
- Elm_Object_Item *li;
- } FavCtx;
- FavCtx *ctx = calloc(1, sizeof(FavCtx));
- ctx->ad = ad;
- ctx->li = li;
- evas_object_smart_callback_add(fav_btn, "clicked", _favorite_btn_clicked_cb, ctx);
+ // Attach callback only when a button exists
+ if (fav_btn)
+ {
+ typedef struct {
+ AppData *ad;
+ Elm_Object_Item *li;
+ } FavCtx;
+ FavCtx *ctx = calloc(1, sizeof(FavCtx));
+ ctx->ad = ad;
+ ctx->li = li;
+ if (ad->view_mode == VIEW_SEARCH)
+ evas_object_smart_callback_add(fav_btn, "clicked", _favorite_btn_clicked_cb, ctx);
+ else
+ evas_object_smart_callback_add(fav_btn, "clicked", _favorite_remove_btn_clicked_cb, ctx);
+ }
if (st->favicon && st->favicon[0])
{
@@ -110,3 +128,27 @@ _favorite_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
free(ctx);
}
+
+static void
+_favorite_remove_btn_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ typedef struct {
+ AppData *ad;
+ Elm_Object_Item *li;
+ } FavCtx;
+
+ FavCtx *ctx = data;
+ if (!ctx) return;
+ Station *st = elm_object_item_data_get(ctx->li);
+ if (!st) { free(ctx); return; }
+
+ st->favorite = EINA_FALSE;
+ favorites_set(ctx->ad, st, EINA_FALSE);
+ favorites_save(ctx->ad);
+
+ // Rebuild favorites list to reflect removal
+ favorites_rebuild_station_list(ctx->ad);
+ station_list_populate(ctx->ad, ctx->ad->favorites_stations);
+
+ free(ctx);
+}
diff --git a/src/ui.c b/src/ui.c
index 80bef67..346a1bc 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -6,6 +6,8 @@
static void _win_del_cb(void *data, Evas_Object *obj, void *event_info);
static void _app_exit_cb(void *data, Evas_Object *obj, void *event_info);
static void _hoversel_item_selected_cb(void *data, Evas_Object *obj, void *event_info);
+static void _tb_favorites_clicked_cb(void *data, Evas_Object *obj, void *event_info);
+static void _tb_search_clicked_cb(void *data, Evas_Object *obj, void *event_info);
// Forward declarations for callbacks
void _play_pause_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
@@ -61,13 +63,27 @@ ui_create(AppData *ad)
elm_win_resize_object_add(ad->win, box);
evas_object_show(box);
- Evas_Object *search_hbox = elm_box_add(ad->win);
- elm_box_horizontal_set(search_hbox, EINA_TRUE);
- elm_box_padding_set(search_hbox, 10, 0);
- evas_object_size_hint_weight_set(search_hbox, EVAS_HINT_EXPAND, 0);
- evas_object_size_hint_align_set(search_hbox, EVAS_HINT_FILL, 0);
- elm_box_pack_end(box, search_hbox);
- evas_object_show(search_hbox);
+ /* Toolbar at the top */
+ Evas_Object *toolbar = elm_toolbar_add(ad->win);
+ elm_toolbar_shrink_mode_set(toolbar, ELM_TOOLBAR_SHRINK_MENU);
+ elm_toolbar_homogeneous_set(toolbar, EINA_TRUE);
+ elm_object_style_set(toolbar, "transparent");
+ evas_object_size_hint_weight_set(toolbar, EVAS_HINT_EXPAND, 0);
+ evas_object_size_hint_align_set(toolbar, EVAS_HINT_FILL, 0);
+ elm_box_pack_end(box, toolbar);
+ evas_object_show(toolbar);
+
+ /* Toolbar items */
+ elm_toolbar_item_append(toolbar, "system-search", "Search", _tb_search_clicked_cb, ad);
+ elm_toolbar_item_append(toolbar, "emblem-favorite", "Favorites", _tb_favorites_clicked_cb, ad);
+
+ ad->search_bar = elm_box_add(ad->win);
+ elm_box_horizontal_set(ad->search_bar, EINA_TRUE);
+ elm_box_padding_set(ad->search_bar, 10, 0);
+ evas_object_size_hint_weight_set(ad->search_bar, EVAS_HINT_EXPAND, 0);
+ evas_object_size_hint_align_set(ad->search_bar, EVAS_HINT_FILL, 0);
+ elm_box_pack_end(box, ad->search_bar);
+ evas_object_show(ad->search_bar);
ad->search_entry = elm_entry_add(ad->win);
elm_entry_single_line_set(ad->search_entry, EINA_TRUE);
@@ -75,7 +91,7 @@ ui_create(AppData *ad)
evas_object_size_hint_weight_set(ad->search_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(ad->search_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_part_text_set(ad->search_entry, "guide", "Search for stations...");
- elm_box_pack_end(search_hbox, ad->search_entry);
+ elm_box_pack_end(ad->search_bar, ad->search_entry);
evas_object_show(ad->search_entry);
elm_object_focus_set(ad->search_entry, EINA_TRUE);
@@ -86,18 +102,15 @@ ui_create(AppData *ad)
elm_hoversel_item_add(ad->search_hoversel, "country", NULL, ELM_ICON_NONE, _hoversel_item_selected_cb, NULL);
elm_hoversel_item_add(ad->search_hoversel, "language", NULL, ELM_ICON_NONE, _hoversel_item_selected_cb, NULL);
elm_hoversel_item_add(ad->search_hoversel, "tag", NULL, ELM_ICON_NONE, _hoversel_item_selected_cb, NULL);
- elm_box_pack_end(search_hbox, ad->search_hoversel);
+ elm_box_pack_end(ad->search_bar, ad->search_hoversel);
evas_object_show(ad->search_hoversel);
ad->search_btn = elm_button_add(ad->win);
elm_object_text_set(ad->search_btn, "Search");
- elm_box_pack_end(search_hbox, ad->search_btn);
+ elm_box_pack_end(ad->search_bar, ad->search_btn);
evas_object_show(ad->search_btn);
- ad->favorites_btn = elm_button_add(ad->win);
- elm_object_text_set(ad->favorites_btn, "Favorites");
- elm_box_pack_end(search_hbox, ad->favorites_btn);
- evas_object_show(ad->favorites_btn);
+ /* Removed redundant Favorites button from search bar; toolbar handles view switching */
ad->list = elm_list_add(ad->win);
evas_object_size_hint_weight_set(ad->list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
@@ -137,16 +150,38 @@ ui_create(AppData *ad)
evas_object_smart_callback_add(ad->search_btn, "clicked", _search_btn_clicked_cb, ad);
evas_object_smart_callback_add(ad->search_entry, "activated", _search_entry_activated_cb, ad);
evas_object_smart_callback_add(ad->list, "selected", _list_item_selected_cb, ad);
- evas_object_smart_callback_add(ad->favorites_btn, "clicked", _favorites_btn_clicked_cb, ad);
+ /* Favorites view button removed; toolbar callbacks handle switching */
+
+ /* Default to Search view on startup */
+ ad->view_mode = VIEW_SEARCH;
+ evas_object_show(ad->search_bar);
+ if (ad->stations)
+ station_list_populate(ad, ad->stations);
+ else
+ station_list_clear(ad);
evas_object_resize(ad->win, 400, 600);
evas_object_show(ad->win);
}
static void
-_favorites_btn_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+_tb_favorites_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
AppData *ad = data;
+ ad->view_mode = VIEW_FAVORITES;
+ evas_object_hide(ad->search_bar);
favorites_rebuild_station_list(ad);
station_list_populate(ad, ad->favorites_stations);
}
+
+static void
+_tb_search_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+ AppData *ad = data;
+ ad->view_mode = VIEW_SEARCH;
+ evas_object_show(ad->search_bar);
+ if (ad->stations)
+ station_list_populate(ad, ad->stations);
+ else
+ station_list_clear(ad);
+}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.