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