girara
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
tabs.c
Go to the documentation of this file.
1 /* See LICENSE file for license and copyright information */
2 
3 #include "tabs.h"
4 #include "session.h"
5 #include "internal.h"
6 
7 #define UNTITLED_TAB_TITLE "untitled"
8 
17 static bool girara_callback_tab_clicked(GtkWidget* widget, GdkEventButton* event, gpointer data);
18 
19 void
20 girara_tabs_enable(girara_session_t* session)
21 {
22  if (session == NULL || session->gtk.tabs == NULL) {
23  return;
24  }
25 
26  /* Display tab view */
27  girara_set_view(session, GTK_WIDGET(session->gtk.tabs));
28 
29  /* Display tab bar */
30  if (session->gtk.tabbar) {
31  gtk_widget_show(session->gtk.tabbar);
32  }
33 }
34 
35 girara_tab_t*
36 girara_tab_new(girara_session_t* session, const char* title, GtkWidget* widget,
37  bool next_to_current, void* data)
38 {
39  if (session == NULL || widget == NULL) {
40  return NULL;
41  }
42 
43  girara_tab_t* tab = g_slice_new(girara_tab_t);
44 
45  tab->title = title ? g_strdup(title) : g_strdup(UNTITLED_TAB_TITLE);
46  tab->widget = widget;
47  tab->session = session;
48  tab->data = data;
49 
50  int position = (next_to_current) ?
51  (gtk_notebook_get_current_page(session->gtk.tabs) + 1) : -1;
52 
53  /* insert tab into notebook */
54  if (gtk_notebook_insert_page(session->gtk.tabs, tab->widget, NULL, position) == -1) {
55  g_free(tab->title);
56  g_slice_free(girara_tab_t, tab);
57  return NULL;
58  }
59 
60  /* create tab label */
61  GtkWidget *tab_label = gtk_label_new(tab->title);
62  GtkWidget *tab_event = gtk_event_box_new();
63 
64  g_object_set_data(G_OBJECT(tab->widget), "event", (gpointer) tab_event);
65  g_object_set_data(G_OBJECT(tab->widget), "label", (gpointer) tab_label);
66  g_object_set_data(G_OBJECT(tab->widget), "tab", (gpointer) tab);
67 
68  g_signal_connect(G_OBJECT(tab_event), "button_press_event",
69  G_CALLBACK(girara_callback_tab_clicked), tab);
70 
71  gtk_widget_set_halign(tab_label, GTK_ALIGN_START);
72  gtk_widget_set_valign(tab_label, GTK_ALIGN_START);
73  widget_add_class(tab_label, "tab");
74  widget_add_class(tab_event, "tab");
75  gtk_label_set_ellipsize(GTK_LABEL(tab_label), PANGO_ELLIPSIZE_MIDDLE);
76 
77  gtk_container_add(GTK_CONTAINER(tab_event), tab_label);
78  gtk_box_pack_start(GTK_BOX(session->gtk.tabbar), tab_event, TRUE, TRUE, 0);
79  gtk_box_reorder_child(GTK_BOX(session->gtk.tabbar), tab_event, position);
80 
81  gtk_widget_show_all(widget);
82  gtk_widget_show_all(tab_event);
83 
84  gtk_notebook_set_current_page(session->gtk.tabs, position);
85 
86  girara_tab_update(session);
87 
88  return tab;
89 }
90 
91 void
92 girara_tab_remove(girara_session_t* session, girara_tab_t* tab)
93 {
94  if (session == NULL || tab == NULL || session->gtk.tabbar == NULL) {
95  return;
96  }
97 
98  /* Remove page from notebook */
99  int tab_id = girara_tab_position_get(session, tab);
100 
101  /* Remove entry from tabbar */
102  GtkWidget* tab_event = GTK_WIDGET(g_object_get_data(G_OBJECT(tab->widget), "event"));
103 
104  if (tab_event != NULL) {
105  gtk_container_remove(GTK_CONTAINER(session->gtk.tabbar), tab_event);
106  }
107 
108  if (tab_id != -1) {
109  gtk_notebook_remove_page(session->gtk.tabs, tab_id);
110  }
111 
112  g_free(tab->title);
113  g_slice_free(girara_tab_t, tab);
114 
115  girara_tab_update(session);
116 }
117 
118 girara_tab_t*
119 girara_tab_get(girara_session_t* session, unsigned int index)
120 {
121  if (session == NULL || session->gtk.tabs == NULL) {
122  return 0;
123  }
124 
125  GtkWidget* widget = gtk_notebook_get_nth_page(session->gtk.tabs, index);
126 
127  return (girara_tab_t*) g_object_get_data(G_OBJECT(widget), "tab");
128 }
129 
130 int
131 girara_get_number_of_tabs(girara_session_t* session)
132 {
133  if (session == NULL || session->gtk.tabs == NULL) {
134  return 0;
135  }
136 
137  return gtk_notebook_get_n_pages(session->gtk.tabs);
138 }
139 
140 void
141 girara_tab_update(girara_session_t* session)
142 {
143  if (session == NULL || session->gtk.tabs == NULL) {
144  return;
145  }
146 
147  int number_of_tabs = girara_get_number_of_tabs(session);
148  int current_tab = girara_tab_position_get(session, girara_tab_current_get(session));
149 
150  for (int i = 0; i < number_of_tabs; i++) {
151  GtkWidget* widget = gtk_notebook_get_nth_page(session->gtk.tabs, i);
152  girara_tab_t* tab = (girara_tab_t*) g_object_get_data(G_OBJECT(widget), "tab");
153 
154  if (tab == NULL) {
155  continue;
156  }
157 
158  GtkWidget* tab_event = GTK_WIDGET(g_object_get_data(G_OBJECT(tab->widget), "event"));
159  GtkWidget* tab_label = GTK_WIDGET(g_object_get_data(G_OBJECT(tab->widget), "label"));
160 
161  if (i == current_tab) {
162  gtk_widget_set_state_flags(tab_event, GTK_STATE_FLAG_SELECTED, false);
163  gtk_widget_set_state_flags(tab_label, GTK_STATE_FLAG_SELECTED, false);
164  } else {
165  gtk_widget_unset_state_flags(tab_event, GTK_STATE_FLAG_SELECTED);
166  gtk_widget_unset_state_flags(tab_label, GTK_STATE_FLAG_SELECTED);
167  }
168  }
169 }
170 
171 girara_tab_t*
172 girara_tab_current_get(girara_session_t* session)
173 {
174  if (session == NULL || session->gtk.tabs == NULL) {
175  return NULL;
176  }
177 
178  int current = gtk_notebook_get_current_page(session->gtk.tabs);
179 
180  if (current != -1) {
181  GtkWidget* widget = gtk_notebook_get_nth_page(session->gtk.tabs, current);
182  return (girara_tab_t*) g_object_get_data(G_OBJECT(widget), "tab");
183  } else {
184  return NULL;
185  }
186 }
187 
188 void
189 girara_tab_current_set(girara_session_t* session, girara_tab_t* tab)
190 {
191  if (session == NULL || session->gtk.tabs == NULL
192  || tab == NULL || tab->widget == NULL) {
193  return;
194  }
195 
196  int index = gtk_notebook_page_num(session->gtk.tabs, tab->widget);
197 
198  if (index != -1) {
199  gtk_notebook_set_current_page(session->gtk.tabs, index);
200  }
201 
202  girara_tab_update(session);
203 }
204 
205 void
206 girara_tab_title_set(girara_tab_t* tab, const char* title)
207 {
208  if (tab == NULL) {
209  return;
210  }
211 
212  g_free(tab->title);
213  tab->title = title ? g_strdup(title) : g_strdup(UNTITLED_TAB_TITLE);
214 
215  GtkWidget* tab_label = GTK_WIDGET(g_object_get_data(G_OBJECT(tab->widget), "label"));
216  if (tab_label) {
217  gtk_label_set_text(GTK_LABEL(tab_label), tab->title);
218  }
219 }
220 
221 const char*
222 girara_tab_title_get(girara_tab_t* tab)
223 {
224  if (tab == NULL) {
225  return NULL;
226  }
227 
228  return tab->title;
229 }
230 
231 int
232 girara_tab_position_get(girara_session_t* session, girara_tab_t* tab)
233 {
234  if (session == NULL || session->gtk.tabs == NULL
235  || tab == NULL || tab->widget == NULL) {
236  return -1;
237  }
238 
239  return gtk_notebook_page_num(session->gtk.tabs, tab->widget);
240 }
241 
242 void
243 girara_tab_position_set(girara_session_t* session, girara_tab_t* tab, unsigned int position)
244 {
245  if (session == NULL || session->gtk.tabs == NULL
246  || tab == NULL || tab->widget == NULL) {
247  return;
248  }
249 
250  gtk_notebook_reorder_child(session->gtk.tabs, tab->widget, position);
251 }
252 
253 static bool
254 girara_callback_tab_clicked(GtkWidget* UNUSED(widget), GdkEventButton* event, gpointer data)
255 {
256  if (data == NULL) {
257  return false;
258  }
259 
260  girara_tab_t* tab = (girara_tab_t*) data;
261  girara_session_t* session = tab->session;
262 
263  switch (event->button) {
264  case 1:
265  girara_tab_current_set(session, tab);
266  break;
267  case 2:
268  girara_tab_remove(session, tab);
269  break;
270  }
271 
272  return true;
273 }
void girara_tab_update(girara_session_t *session)
Definition: tabs.c:141
#define UNUSED(x)
Definition: internal.h:15
void girara_tab_remove(girara_session_t *session, girara_tab_t *tab)
Definition: tabs.c:92
void girara_tab_current_set(girara_session_t *session, girara_tab_t *tab)
Definition: tabs.c:189
girara_tab_t * girara_tab_new(girara_session_t *session, const char *title, GtkWidget *widget, bool next_to_current, void *data)
Definition: tabs.c:36
girara_tab_t * girara_tab_current_get(girara_session_t *session)
Definition: tabs.c:172
bool girara_set_view(girara_session_t *session, GtkWidget *widget)
Definition: session.c:780
int girara_tab_position_get(girara_session_t *session, girara_tab_t *tab)
Definition: tabs.c:232
HIDDEN void widget_add_class(GtkWidget *widget, const char *styleclass)
Definition: utils.c:532
int girara_get_number_of_tabs(girara_session_t *session)
Definition: tabs.c:131
void girara_tab_position_set(girara_session_t *session, girara_tab_t *tab, unsigned int position)
Definition: tabs.c:243
girara_tab_t * girara_tab_get(girara_session_t *session, unsigned int index)
Definition: tabs.c:119
const char * girara_tab_title_get(girara_tab_t *tab)
Definition: tabs.c:222
void girara_tabs_enable(girara_session_t *session)
Definition: tabs.c:20
#define UNTITLED_TAB_TITLE
Definition: tabs.c:7
void girara_tab_title_set(girara_tab_t *tab, const char *title)
Definition: tabs.c:206