UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2024 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "headerbar.h" 30 31 #include "button.h" 32 #include "menu.h" 33 34 #if GTK_CHECK_VERSION(3, 10, 0) 35 36 void ui_fill_headerbar(UiObject *obj, GtkWidget *headerbar) { 37 CxList *left_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_LEFT); 38 CxList *center_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_CENTER); 39 CxList *right_defaults = uic_get_toolbar_defaults(UI_TOOLBAR_RIGHT); 40 41 ui_headerbar_add_items(obj, headerbar, left_defaults, UI_TOOLBAR_LEFT); 42 ui_headerbar_add_items(obj, headerbar, center_defaults, UI_TOOLBAR_CENTER); 43 44 UiToolbarMenuItem *appmenu = uic_get_appmenu(); 45 if(appmenu) { 46 ui_add_headerbar_menu(headerbar, NULL, appmenu, obj, UI_TOOLBAR_RIGHT); 47 } 48 ui_headerbar_add_items(obj, headerbar, right_defaults, UI_TOOLBAR_RIGHT); 49 } 50 51 static void create_item(UiObject *obj, GtkWidget *headerbar, GtkWidget *box, UiToolbarItemI *i, enum UiToolbarPos pos) { 52 switch(i->type) { 53 case UI_TOOLBAR_ITEM: { 54 ui_add_headerbar_item(headerbar, box, (UiToolbarItem*)i, obj, pos); 55 break; 56 } 57 case UI_TOOLBAR_TOGGLEITEM: { 58 ui_add_headerbar_toggleitem(headerbar, box, (UiToolbarToggleItem*)i, obj, pos); 59 break; 60 } 61 case UI_TOOLBAR_MENU: { 62 ui_add_headerbar_menu(headerbar, box, (UiToolbarMenuItem*)i, obj, pos); 63 break; 64 } 65 default: fprintf(stderr, "toolbar item type unimplemented: %d\n", (int)i->type); 66 } 67 } 68 69 static void headerbar_add(GtkWidget *headerbar, GtkWidget *box, GtkWidget *item, enum UiToolbarPos pos) { 70 switch(pos) { 71 case UI_TOOLBAR_LEFT: { 72 UI_HEADERBAR_PACK_START(headerbar, item); 73 break; 74 } 75 case UI_TOOLBAR_CENTER: { 76 77 #if GTK_MAJOR_VERSION >= 4 78 gtk_box_append(GTK_BOX(box), item); 79 #else 80 gtk_box_pack_start(GTK_BOX(box), item, 0, 0, 0); 81 #endif 82 break; 83 } 84 case UI_TOOLBAR_RIGHT: { 85 UI_HEADERBAR_PACK_END(headerbar, item); 86 break; 87 } 88 } 89 } 90 91 void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos) { 92 GtkWidget *box = NULL; 93 94 if(pos == UI_TOOLBAR_CENTER && cxListSize(items) > 0) { 95 box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); 96 UI_HEADERBAR_SET_TITLE_WIDGET(headerbar, box); 97 } 98 99 CxIterator i = pos == UI_TOOLBAR_RIGHT ? cxListBackwardsIterator(items) : cxListIterator(items); 100 cx_foreach(char*, def, i) { 101 UiToolbarItemI* item = uic_toolbar_get_item(def); 102 if (!item) { 103 fprintf(stderr, "unknown toolbar item: %s\n", def); 104 continue; 105 } 106 create_item(obj, headerbar, box, item, pos); 107 } 108 } 109 110 void ui_add_headerbar_item( 111 GtkWidget *headerbar, 112 GtkWidget *box, 113 UiToolbarItem *item, 114 UiObject *obj, 115 enum UiToolbarPos pos) 116 { 117 GtkWidget *button = ui_create_button(obj, item->args.label, item->args.icon, item->args.onclick, item->args.onclickdata, 0, FALSE); 118 ui_set_widget_groups(obj->ctx, button, item->args.groups); 119 WIDGET_ADD_CSS_CLASS(button, "flat"); 120 headerbar_add(headerbar, box, button, pos); 121 } 122 123 void ui_add_headerbar_toggleitem( 124 GtkWidget *headerbar, 125 GtkWidget *box, 126 UiToolbarToggleItem *item, 127 UiObject *obj, 128 enum UiToolbarPos pos) 129 { 130 GtkWidget *button = gtk_toggle_button_new(); 131 ui_set_widget_groups(obj->ctx, button, item->args.groups); 132 WIDGET_ADD_CSS_CLASS(button, "flat"); 133 ui_setup_togglebutton(obj, button, item->args.label, item->args.icon, item->args.varname, NULL, item->args.onchange, item->args.onchangedata, 0); 134 headerbar_add(headerbar, box, button, pos); 135 } 136 137 void ui_add_headerbar_menu( 138 GtkWidget *headerbar, 139 GtkWidget *box, 140 UiToolbarMenuItem *item, 141 UiObject *obj, 142 enum UiToolbarPos pos) 143 { 144 145 146 #if GTK_MAJOR_VERSION >= 4 147 GtkWidget *menubutton = gtk_menu_button_new(); 148 if(item->args.label) { 149 gtk_menu_button_set_label(GTK_MENU_BUTTON(menubutton), item->args.label); 150 } 151 if(item->args.icon) { 152 gtk_menu_button_set_icon_name(GTK_MENU_BUTTON(menubutton), item->args.icon); 153 } 154 155 if(!item->args.label && !item->args.icon) { 156 gtk_menu_button_set_icon_name(GTK_MENU_BUTTON(menubutton), "open-menu-symbolic"); 157 } 158 159 GMenu *menu = g_menu_new(); 160 ui_gmenu_add_menu_items(menu, 0, &item->menu, obj); 161 162 gtk_menu_button_set_menu_model(GTK_MENU_BUTTON(menubutton), G_MENU_MODEL(menu)); 163 #else 164 GtkWidget *menubutton = gtk_menu_button_new(); 165 166 // TODO 167 168 169 #endif 170 171 headerbar_add(headerbar, box, menubutton, pos); 172 } 173 174 #endif // GTK_CHECK_VERSION(3, 10, 0) 175