taskbar.c

Go to the documentation of this file.
00001 /*
00002  * File Name: taskbar.c
00003  */
00004 
00005 /*
00006  * This file is part of popupmenu.
00007  *
00008  * popupmenu is free software: you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation, either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * popupmenu is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00020  */
00021  
00022 /**
00023  * Copyright (C) 2009 iRex Technologies B.V.
00024  * All rights reserved.
00025  */
00026 
00027 #include "config.h"
00028 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00029 
00030 #include <string.h>
00031 #include <stdlib.h>
00032 
00033 #include <gtk/gtk.h>
00034 #include <libergtk/ergtk.h>
00035 
00036 #include "ipc.h"
00037 #include "log.h"
00038 #include "i18n.h"
00039 #include "taskbar.h"
00040 
00041 #define WINDOW_WIDTH  40
00042 #define NUM_TASKS 5
00043 #define FOLDER_XID -1
00044 #define TASKBAR_HEIGHT 38
00045 
00046 static GtkWidget *g_notebook = NULL;
00047 static GtkWidget *g_window = NULL;
00048 static int g_labelheight = -1;
00049 
00050 struct task {
00051     int xid;
00052     int active;
00053     GtkWidget* labelWidget;
00054 };
00055 
00056 static GList *tasks = NULL;
00057 static guint numtasks = 0;
00058 static gboolean g_enabled = TRUE;
00059 
00060 
00061 void testing_taskbar_print()
00062 {
00063 #if (LOGGING_ON)
00064     int i = 0;
00065     GList *iter = tasks;
00066     printf("------ Tasks ------\n");
00067     while (iter) {
00068         const struct task *t = (struct task*)iter->data;
00069         GList *children = gtk_container_get_children(GTK_CONTAINER(t->labelWidget));
00070         const char* text = gtk_label_get_text(GTK_LABEL(children->data));
00071         printf("  [%d]  %8d  '%s'  %s\n", i, t->xid, text, t->active ? "ACTIVE" : "");
00072         iter = iter->next;
00073         i++;
00074     }
00075 #endif
00076 }
00077 
00078 
00079 static void taskbar_resize(int screenheight) {
00080     int width;
00081     int height = screenheight;
00082     gtk_widget_set_size_request(g_window, WINDOW_WIDTH, screenheight);
00083     gtk_window_get_size(GTK_WINDOW(g_window), &width, &height);
00084 
00085     g_labelheight = (height - 100) / NUM_TASKS;
00086     GList *iter = tasks;
00087     while (iter) {
00088         struct task *t = (struct task*)iter->data;
00089         gtk_widget_set_size_request(t->labelWidget, -1, g_labelheight);
00090         iter = iter->next;
00091     }
00092 }
00093 
00094 
00095 static void on_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer data)
00096 {
00097     static gint height = 0;
00098 
00099     if (allocation->height != height) {
00100         height = allocation->height;
00101         taskbar_resize(allocation->height);
00102     }
00103 }
00104 
00105 static void set_active_task(struct task* activeTask, gboolean update_gui)
00106 {
00107     GList *iter = tasks;
00108     int page = 0;
00109     int activePage = 0;
00110     while (iter) {
00111         struct task *t = (struct task*)iter->data;
00112         if (t == activeTask) {
00113             if (t->active == 1) return;
00114             t->active = 1;
00115             activePage = page;
00116         } else t->active = 0;
00117         page++;
00118         iter = iter->next;
00119     }
00120     if (update_gui) gtk_notebook_set_current_page(GTK_NOTEBOOK(g_notebook), activePage);
00121 #if (LOGGING_ON)
00122     testing_taskbar_print();
00123 #endif
00124 }
00125 
00126 
00127 static struct task* page2task(int page_num) {
00128     GList *iter = tasks;
00129     int cur_page = 0;
00130     while (cur_page != page_num) {
00131         iter = iter->next;
00132         cur_page++;
00133     }
00134     return (struct task*)iter->data;
00135 }
00136 
00137 
00138 static void task_clicked(GtkNotebook *widget, GtkNotebookPage *page, guint page_num, gpointer user_data)
00139 {
00140     LOGPRINTF("Task selected page=%d", page_num);
00141     g_assert (page_num <= numtasks);
00142   
00143     if (!ipc_is_enabled()) return;
00144 
00145     struct task* t = page2task(page_num);
00146     if (t->active) return;
00147     set_active_task(t, FALSE);
00148     ipc_send_task_activated(t->xid);
00149 }
00150 
00151 
00152 void taskbar_create()
00153 {
00154     GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00155     g_window = window;
00156 
00157     GdkColor color;
00158     gdk_color_parse ("#bbbbbb", &color);
00159     gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &color);
00160 
00161     gtk_window_set_type_hint(GTK_WINDOW(window), GDK_WINDOW_TYPE_HINT_DOCK);
00162     gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
00163     gtk_window_set_accept_focus(GTK_WINDOW(window), FALSE);
00164     gtk_widget_set_size_request(g_window, WINDOW_WIDTH, gdk_screen_height() - TASKBAR_HEIGHT);
00165     gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
00166     gtk_window_move(GTK_WINDOW(g_window), gdk_screen_width() - WINDOW_WIDTH, 0);
00167 
00168     GtkWidget *alignment = gtk_alignment_new(0, 0, 1, 1);
00169     gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 0, 5);
00170     gtk_container_add(GTK_CONTAINER(window), alignment);
00171     gtk_widget_show(alignment);
00172 
00173     GtkWidget *notebook = gtk_notebook_new();
00174     gtk_widget_set_name(notebook, "irex-taskbar-notebook");
00175     gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook), FALSE);
00176     gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_RIGHT);
00177     gtk_container_add(GTK_CONTAINER(alignment), notebook);
00178     g_notebook = notebook;
00179 
00180     taskbar_resize(gdk_screen_height() - TASKBAR_HEIGHT);
00181 
00182     // add first special task
00183     taskbar_add_task(FOLDER_XID, _("Folder"));
00184 
00185     gtk_widget_show_all(window);
00186     gdk_flush();
00187     g_signal_connect(G_OBJECT(notebook), "switch-page", G_CALLBACK(task_clicked), NULL);
00188     g_signal_connect(window, "size-allocate", G_CALLBACK(on_size_allocate), NULL);
00189 }
00190 
00191 
00192 void taskbar_enable(gboolean enabled)
00193 {
00194     if (g_enabled == enabled) return;
00195 
00196     g_enabled = enabled;
00197     gtk_widget_set_sensitive(g_notebook, enabled); 
00198 }
00199 
00200 
00201 static GtkWidget* create_page(const char* labelname)
00202 {
00203     GtkWidget* labelbox = gtk_vbox_new(FALSE, 0);
00204     gtk_widget_set_size_request(labelbox, -1, g_labelheight);
00205 
00206     GtkWidget *label = gtk_label_new(labelname);
00207     gtk_label_set_angle(GTK_LABEL(label), 270);
00208     gtk_label_set_single_line_mode(GTK_LABEL(label), TRUE);
00209     gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
00210     gtk_box_pack_start(GTK_BOX(labelbox), label, TRUE, TRUE, 15);
00211 
00212     GtkWidget* page = gtk_vbox_new(FALSE, 0);
00213     gtk_container_set_border_width(GTK_CONTAINER(page), 0);
00214     gtk_widget_show(page);
00215     gtk_widget_show(label);
00216     gtk_widget_show(labelbox);
00217     gtk_notebook_append_page(GTK_NOTEBOOK(g_notebook), page, labelbox);
00218     gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(g_notebook), page, FALSE, FALSE, GTK_PACK_START);
00219 
00220     return labelbox;
00221 }
00222 
00223 
00224 void taskbar_update_locale()
00225 {
00226     GList *elem = g_list_first(tasks);
00227     struct task *t = (struct task*)elem->data;
00228     GList *children = gtk_container_get_children(GTK_CONTAINER(t->labelWidget));
00229     gtk_label_set_text(GTK_LABEL(children->data), _("Folder"));
00230 }
00231 
00232 
00233 static GList* find_task(int xid)
00234 {
00235     GList *iter = tasks;
00236     while (iter) {
00237         struct task *t = (struct task*)iter->data;
00238         if (xid == t->xid) return iter;
00239         iter = iter->next;
00240     }
00241     return NULL;
00242 }
00243 
00244 
00245 void taskbar_add_task(int xid, const char* label)
00246 {
00247     LOGPRINTF("xid=%d  label=%s",  xid, label);
00248 
00249     if (numtasks == NUM_TASKS + 1) {
00250         ERRORPRINTF("%s: error already has 1 extra task!", __func__);
00251         return;
00252     }
00253     numtasks++;
00254     if (find_task(xid)) {
00255         ERRORPRINTF("task [%d] already known!", xid);
00256         return;
00257     }
00258     struct task *newtask = malloc(sizeof(struct task));
00259     newtask->xid = xid;
00260     newtask->active = 0;
00261     tasks = g_list_append(tasks, newtask);
00262     newtask->labelWidget = create_page(label);
00263     set_active_task(newtask, TRUE);
00264 }
00265 
00266 
00267 static void remove_page(GList* elem)
00268 {
00269     GList *iter = tasks;
00270     int page = 0;
00271     while (iter) {
00272         if (iter == elem) {
00273             gtk_notebook_remove_page(GTK_NOTEBOOK(g_notebook), page);
00274             return;
00275         }
00276         page++;
00277         iter = iter->next;
00278     }
00279 }
00280 
00281 
00282 void taskbar_remove_task(int xid)
00283 {
00284     LOGPRINTF("xid=%d",  xid);
00285 
00286     if (xid == FOLDER_XID) {
00287         ERRORPRINTF("cannot removed fixed task!");
00288         return;
00289     }
00290     GList *elem = find_task(xid);
00291     if (!elem) {
00292         ERRORPRINTF("task [%d] unknown!",xid);
00293         return;
00294     }
00295     // if removing extra task, switch to last task,
00296     // otherwise switch to 'Folder' on close
00297     GList *folder;
00298     if (numtasks == NUM_TASKS + 1) folder = g_list_last(tasks); 
00299     else folder = g_list_first(tasks); 
00300     set_active_task(folder->data, TRUE);
00301 
00302     remove_page(elem);
00303     free(elem->data);
00304     tasks = g_list_remove(tasks, elem->data);
00305     numtasks--;
00306 #if (LOGGING_ON)
00307     testing_taskbar_print();
00308 #endif
00309 }
00310 
00311 
00312 void taskbar_rename_task(int xid, const char* label)
00313 {
00314     LOGPRINTF("xid=%d  label='%s'", xid, label);
00315     GList *elem = find_task(xid);
00316     if (!elem) {
00317         ERRORPRINTF("task [%d] unknown!", xid);
00318         return;
00319     }
00320     const struct task *task = (struct task*)elem->data;
00321     GList *children = gtk_container_get_children(GTK_CONTAINER(task->labelWidget));
00322     gtk_label_set_text(GTK_LABEL(children->data), label);
00323 }
00324 
00325 
00326 void taskbar_select_task(int xid)
00327 {
00328     LOGPRINTF("xid=%d", xid);
00329     GList *task = find_task(xid);
00330     if (!task) {
00331         ERRORPRINTF("task [%d] unknown!", xid);
00332         return;
00333     }
00334     set_active_task(task->data, TRUE);
00335 }
00336 
00337 #endif
00338 
00339 void taskbar_select_folder()
00340 {
00341 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00342     taskbar_select_task(FOLDER_XID);
00343 #endif
00344 }
00345 
00346 
Generated by  doxygen 1.6.2-20100208