girara
tabs.c
Go to the documentation of this file.
00001 /* See LICENSE file for license and copyright information */
00002 
00003 #include "tabs.h"
00004 #include "session.h"
00005 #include "internal.h"
00006 
00007 #define UNTITLED_TAB_TITLE "untitled"
00008 
00009 #if GTK_MAJOR_VERSION == 2
00010 #include "gtk2-compat.h"
00011 #endif
00012 
00021 static bool girara_callback_tab_clicked(GtkWidget* widget, GdkEventButton* event, gpointer data);
00022 
00023 void
00024 girara_tabs_enable(girara_session_t* session)
00025 {
00026   if (session == NULL || session->gtk.tabs == NULL) {
00027     return;
00028   }
00029 
00030   /* Display tab view */
00031   girara_set_view(session, GTK_WIDGET(session->gtk.tabs));
00032 
00033   /* Display tab bar */
00034   if (session->gtk.tabbar) {
00035     gtk_widget_show(session->gtk.tabbar);
00036   }
00037 }
00038 
00039 girara_tab_t*
00040 girara_tab_new(girara_session_t* session, const char* title, GtkWidget* widget,
00041     bool next_to_current, void* data)
00042 {
00043   if (session == NULL || widget == NULL) {
00044     return NULL;
00045   }
00046 
00047   girara_tab_t* tab = g_slice_new(girara_tab_t);
00048 
00049   tab->title   = title ? g_strdup(title) : g_strdup(UNTITLED_TAB_TITLE);
00050   tab->widget  = widget;
00051   tab->session = session;
00052   tab->data    = data;
00053 
00054   int position = (next_to_current) ?
00055     (gtk_notebook_get_current_page(session->gtk.tabs) + 1) : -1;
00056 
00057   /* insert tab into notebook */
00058   if (gtk_notebook_insert_page(session->gtk.tabs, tab->widget, NULL, position) == -1) {
00059     g_free(tab->title);
00060     g_slice_free(girara_tab_t, tab);
00061     return NULL;
00062   }
00063 
00064   /* create tab label */
00065   GtkWidget *tab_label = gtk_label_new(tab->title);
00066   GtkWidget *tab_event = gtk_event_box_new();
00067 
00068   g_object_set_data(G_OBJECT(tab->widget), "event", (gpointer) tab_event);
00069   g_object_set_data(G_OBJECT(tab->widget), "label", (gpointer) tab_label);
00070   g_object_set_data(G_OBJECT(tab->widget), "tab",   (gpointer) tab);
00071 
00072   g_signal_connect(G_OBJECT(tab_event), "button_press_event",
00073       G_CALLBACK(girara_callback_tab_clicked), tab);
00074 
00075   gtk_misc_set_alignment(GTK_MISC(tab_label), 0.0f, 0.0f);
00076   gtk_misc_set_padding(GTK_MISC(tab_label),   4, 4);
00077   gtk_widget_modify_font(tab_label, session->style.font);
00078 
00079   gtk_container_add(GTK_CONTAINER(tab_event), tab_label);
00080   gtk_box_pack_start(GTK_BOX(session->gtk.tabbar), tab_event, TRUE, TRUE, 0);
00081   gtk_box_reorder_child(GTK_BOX(session->gtk.tabbar), tab_event, position);
00082 
00083   gtk_widget_show_all(widget);
00084   gtk_widget_show_all(tab_event);
00085 
00086   gtk_notebook_set_current_page(session->gtk.tabs, position);
00087 
00088   girara_tab_update(session);
00089 
00090   return tab;
00091 }
00092 
00093 void
00094 girara_tab_remove(girara_session_t* session, girara_tab_t* tab)
00095 {
00096   if (session == NULL || tab == NULL || session->gtk.tabbar == NULL) {
00097     return;
00098   }
00099 
00100   /* Remove page from notebook */
00101   int tab_id = girara_tab_position_get(session, tab);
00102 
00103   /* Remove entry from tabbar */
00104   GtkWidget* tab_event = GTK_WIDGET(g_object_get_data(G_OBJECT(tab->widget), "event"));
00105 
00106   if (tab_event != NULL) {
00107     gtk_container_remove(GTK_CONTAINER(session->gtk.tabbar), tab_event);
00108   }
00109 
00110   if (tab_id != -1) {
00111     gtk_notebook_remove_page(session->gtk.tabs, tab_id);
00112   }
00113 
00114   g_free(tab->title);
00115   g_slice_free(girara_tab_t, tab);
00116 
00117   girara_tab_update(session);
00118 }
00119 
00120 girara_tab_t*
00121 girara_tab_get(girara_session_t* session, unsigned int index)
00122 {
00123   if (session == NULL || session->gtk.tabs == NULL) {
00124     return 0;
00125   }
00126 
00127   GtkWidget* widget = gtk_notebook_get_nth_page(session->gtk.tabs, index);
00128 
00129   return (girara_tab_t*) g_object_get_data(G_OBJECT(widget), "tab");
00130 }
00131 
00132 int
00133 girara_get_number_of_tabs(girara_session_t* session)
00134 {
00135   if (session == NULL || session->gtk.tabs == NULL) {
00136     return 0;
00137   }
00138 
00139   return gtk_notebook_get_n_pages(session->gtk.tabs);
00140 }
00141 
00142 void
00143 girara_tab_update(girara_session_t* session)
00144 {
00145   if (session == NULL || session->gtk.tabs == NULL) {
00146     return;
00147   }
00148 
00149   int number_of_tabs = girara_get_number_of_tabs(session);
00150   int current_tab    = girara_tab_position_get(session, girara_tab_current_get(session));
00151 
00152   for (int i = 0; i < number_of_tabs; i++) {
00153     GtkWidget* widget = gtk_notebook_get_nth_page(session->gtk.tabs, i);
00154     girara_tab_t* tab = (girara_tab_t*) g_object_get_data(G_OBJECT(widget), "tab");
00155 
00156     if (tab == NULL) {
00157       continue;
00158     }
00159 
00160     GtkWidget* tab_event = GTK_WIDGET(g_object_get_data(G_OBJECT(tab->widget), "event"));
00161     GtkWidget* tab_label = GTK_WIDGET(g_object_get_data(G_OBJECT(tab->widget), "label"));
00162 
00163     if (i == current_tab) {
00164       gtk_widget_override_background_color(tab_event, GTK_STATE_NORMAL, &(session->style.tabbar_focus_background));
00165       gtk_widget_override_color(tab_label, GTK_STATE_NORMAL, &(session->style.tabbar_focus_foreground));
00166     } else {
00167       gtk_widget_override_background_color(tab_event, GTK_STATE_NORMAL, &(session->style.tabbar_background));
00168       gtk_widget_override_color(tab_label, GTK_STATE_NORMAL, &(session->style.tabbar_foreground));
00169     }
00170   }
00171 }
00172 
00173 girara_tab_t*
00174 girara_tab_current_get(girara_session_t* session)
00175 {
00176   if (session == NULL || session->gtk.tabs == NULL) {
00177     return NULL;
00178   }
00179 
00180   int current = gtk_notebook_get_current_page(session->gtk.tabs);
00181 
00182   if (current != -1) {
00183     GtkWidget* widget = gtk_notebook_get_nth_page(session->gtk.tabs, current);
00184     return (girara_tab_t*) g_object_get_data(G_OBJECT(widget), "tab");
00185   } else {
00186     return NULL;
00187   }
00188 }
00189 
00190 void
00191 girara_tab_current_set(girara_session_t* session, girara_tab_t* tab)
00192 {
00193   if (session == NULL || session->gtk.tabs == NULL
00194       || tab == NULL || tab->widget == NULL) {
00195     return;
00196   }
00197 
00198   int index = gtk_notebook_page_num(session->gtk.tabs, tab->widget);
00199 
00200   if (index != -1) {
00201     gtk_notebook_set_current_page(session->gtk.tabs, index);
00202   }
00203 
00204   girara_tab_update(session);
00205 }
00206 
00207 void
00208 girara_tab_title_set(girara_tab_t* tab, const char* title)
00209 {
00210   if (tab == NULL) {
00211     return;
00212   }
00213 
00214   g_free(tab->title);
00215   tab->title = title ? g_strdup(title) : g_strdup(UNTITLED_TAB_TITLE);
00216 
00217   GtkWidget* tab_label = GTK_WIDGET(g_object_get_data(G_OBJECT(tab->widget), "label"));
00218   if (tab_label) {
00219     gtk_label_set_text(GTK_LABEL(tab_label), tab->title);
00220   }
00221 }
00222 
00223 const char*
00224 girara_tab_title_get(girara_tab_t* tab)
00225 {
00226   if (tab == NULL) {
00227     return NULL;
00228   }
00229 
00230   return tab->title;
00231 }
00232 
00233 int
00234 girara_tab_position_get(girara_session_t* session, girara_tab_t* tab)
00235 {
00236   if (session == NULL || session->gtk.tabs == NULL
00237       || tab == NULL || tab->widget == NULL) {
00238     return -1;
00239   }
00240 
00241   return gtk_notebook_page_num(session->gtk.tabs, tab->widget);
00242 }
00243 
00244 void
00245 girara_tab_position_set(girara_session_t* session, girara_tab_t* tab, unsigned int position)
00246 {
00247   if (session == NULL || session->gtk.tabs == NULL
00248       || tab == NULL || tab->widget == NULL) {
00249     return;
00250   }
00251 
00252   gtk_notebook_reorder_child(session->gtk.tabs, tab->widget, position);
00253 }
00254 
00255 static bool
00256 girara_callback_tab_clicked(GtkWidget* UNUSED(widget), GdkEventButton* event, gpointer data)
00257 {
00258   if (data == NULL) {
00259     return false;
00260   }
00261 
00262   girara_tab_t* tab         = (girara_tab_t*) data;
00263   girara_session_t* session = tab->session;
00264 
00265   switch (event->button) {
00266     case 1:
00267       girara_tab_current_set(session, tab);
00268       break;
00269     case 2:
00270       girara_tab_remove(session, tab);
00271       break;
00272   }
00273 
00274   return true;
00275 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines