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_misc_set_alignment(GTK_MISC(tab_label), 0.0f, 0.0f);
72  widget_add_class(tab_label, "tab");
73  widget_add_class(tab_event, "tab");
74  gtk_label_set_ellipsize(GTK_LABEL(tab_label), PANGO_ELLIPSIZE_MIDDLE);
75 
76  gtk_container_add(GTK_CONTAINER(tab_event), tab_label);
77  gtk_box_pack_start(GTK_BOX(session->gtk.tabbar), tab_event, TRUE, TRUE, 0);
78  gtk_box_reorder_child(GTK_BOX(session->gtk.tabbar), tab_event, position);
79 
80  gtk_widget_show_all(widget);
81  gtk_widget_show_all(tab_event);
82 
83  gtk_notebook_set_current_page(session->gtk.tabs, position);
84 
85  girara_tab_update(session);
86 
87  return tab;
88 }
89 
90 void
91 girara_tab_remove(girara_session_t* session, girara_tab_t* tab)
92 {
93  if (session == NULL || tab == NULL || session->gtk.tabbar == NULL) {
94  return;
95  }
96 
97  /* Remove page from notebook */
98  int tab_id = girara_tab_position_get(session, tab);
99 
100  /* Remove entry from tabbar */
101  GtkWidget* tab_event = GTK_WIDGET(g_object_get_data(G_OBJECT(tab->widget), "event"));
102 
103  if (tab_event != NULL) {
104  gtk_container_remove(GTK_CONTAINER(session->gtk.tabbar), tab_event);
105  }
106 
107  if (tab_id != -1) {
108  gtk_notebook_remove_page(session->gtk.tabs, tab_id);
109  }
110 
111  g_free(tab->title);
112  g_slice_free(girara_tab_t, tab);
113 
114  girara_tab_update(session);
115 }
116 
117 girara_tab_t*
118 girara_tab_get(girara_session_t* session, unsigned int index)
119 {
120  if (session == NULL || session->gtk.tabs == NULL) {
121  return 0;
122  }
123 
124  GtkWidget* widget = gtk_notebook_get_nth_page(session->gtk.tabs, index);
125 
126  return (girara_tab_t*) g_object_get_data(G_OBJECT(widget), "tab");
127 }
128 
129 int
130 girara_get_number_of_tabs(girara_session_t* session)
131 {
132  if (session == NULL || session->gtk.tabs == NULL) {
133  return 0;
134  }
135 
136  return gtk_notebook_get_n_pages(session->gtk.tabs);
137 }
138 
139 void
140 girara_tab_update(girara_session_t* session)
141 {
142  if (session == NULL || session->gtk.tabs == NULL) {
143  return;
144  }
145 
146  int number_of_tabs = girara_get_number_of_tabs(session);
147  int current_tab = girara_tab_position_get(session, girara_tab_current_get(session));
148 
149  for (int i = 0; i < number_of_tabs; i++) {
150  GtkWidget* widget = gtk_notebook_get_nth_page(session->gtk.tabs, i);
151  girara_tab_t* tab = (girara_tab_t*) g_object_get_data(G_OBJECT(widget), "tab");
152 
153  if (tab == NULL) {
154  continue;
155  }
156 
157  GtkWidget* tab_event = GTK_WIDGET(g_object_get_data(G_OBJECT(tab->widget), "event"));
158  GtkWidget* tab_label = GTK_WIDGET(g_object_get_data(G_OBJECT(tab->widget), "label"));
159 
160  if (i == current_tab) {
161  gtk_widget_set_state_flags(tab_event, GTK_STATE_FLAG_SELECTED, false);
162  gtk_widget_set_state_flags(tab_label, GTK_STATE_FLAG_SELECTED, false);
163  } else {
164  gtk_widget_unset_state_flags(tab_event, GTK_STATE_FLAG_SELECTED);
165  gtk_widget_unset_state_flags(tab_label, GTK_STATE_FLAG_SELECTED);
166  }
167  }
168 }
169 
170 girara_tab_t*
171 girara_tab_current_get(girara_session_t* session)
172 {
173  if (session == NULL || session->gtk.tabs == NULL) {
174  return NULL;
175  }
176 
177  int current = gtk_notebook_get_current_page(session->gtk.tabs);
178 
179  if (current != -1) {
180  GtkWidget* widget = gtk_notebook_get_nth_page(session->gtk.tabs, current);
181  return (girara_tab_t*) g_object_get_data(G_OBJECT(widget), "tab");
182  } else {
183  return NULL;
184  }
185 }
186 
187 void
188 girara_tab_current_set(girara_session_t* session, girara_tab_t* tab)
189 {
190  if (session == NULL || session->gtk.tabs == NULL
191  || tab == NULL || tab->widget == NULL) {
192  return;
193  }
194 
195  int index = gtk_notebook_page_num(session->gtk.tabs, tab->widget);
196 
197  if (index != -1) {
198  gtk_notebook_set_current_page(session->gtk.tabs, index);
199  }
200 
201  girara_tab_update(session);
202 }
203 
204 void
205 girara_tab_title_set(girara_tab_t* tab, const char* title)
206 {
207  if (tab == NULL) {
208  return;
209  }
210 
211  g_free(tab->title);
212  tab->title = title ? g_strdup(title) : g_strdup(UNTITLED_TAB_TITLE);
213 
214  GtkWidget* tab_label = GTK_WIDGET(g_object_get_data(G_OBJECT(tab->widget), "label"));
215  if (tab_label) {
216  gtk_label_set_text(GTK_LABEL(tab_label), tab->title);
217  }
218 }
219 
220 const char*
221 girara_tab_title_get(girara_tab_t* tab)
222 {
223  if (tab == NULL) {
224  return NULL;
225  }
226 
227  return tab->title;
228 }
229 
230 int
231 girara_tab_position_get(girara_session_t* session, girara_tab_t* tab)
232 {
233  if (session == NULL || session->gtk.tabs == NULL
234  || tab == NULL || tab->widget == NULL) {
235  return -1;
236  }
237 
238  return gtk_notebook_page_num(session->gtk.tabs, tab->widget);
239 }
240 
241 void
242 girara_tab_position_set(girara_session_t* session, girara_tab_t* tab, unsigned int position)
243 {
244  if (session == NULL || session->gtk.tabs == NULL
245  || tab == NULL || tab->widget == NULL) {
246  return;
247  }
248 
249  gtk_notebook_reorder_child(session->gtk.tabs, tab->widget, position);
250 }
251 
252 static bool
253 girara_callback_tab_clicked(GtkWidget* UNUSED(widget), GdkEventButton* event, gpointer data)
254 {
255  if (data == NULL) {
256  return false;
257  }
258 
259  girara_tab_t* tab = (girara_tab_t*) data;
260  girara_session_t* session = tab->session;
261 
262  switch (event->button) {
263  case 1:
264  girara_tab_current_set(session, tab);
265  break;
266  case 2:
267  girara_tab_remove(session, tab);
268  break;
269  }
270 
271  return true;
272 }
void girara_tab_update(girara_session_t *session)
Definition: tabs.c:140
#define UNUSED(x)
Definition: internal.h:15
void girara_tab_remove(girara_session_t *session, girara_tab_t *tab)
Definition: tabs.c:91
void girara_tab_current_set(girara_session_t *session, girara_tab_t *tab)
Definition: tabs.c:188
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:171
bool girara_set_view(girara_session_t *session, GtkWidget *widget)
Definition: session.c:769
int girara_tab_position_get(girara_session_t *session, girara_tab_t *tab)
Definition: tabs.c:231
HIDDEN void widget_add_class(GtkWidget *widget, const char *styleclass)
Definition: utils.c:528
int girara_get_number_of_tabs(girara_session_t *session)
Definition: tabs.c:130
void girara_tab_position_set(girara_session_t *session, girara_tab_t *tab, unsigned int position)
Definition: tabs.c:242
girara_tab_t * girara_tab_get(girara_session_t *session, unsigned int index)
Definition: tabs.c:118
const char * girara_tab_title_get(girara_tab_t *tab)
Definition: tabs.c:221
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:205