00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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
00296
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