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