1 /*
2  *	Copyright (C) 2004-2005 Vadim Berezniker
3  *	http://www.kryptolus.com
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with GNU Make; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21 
22 #include "stdafx.h"
23 
24 #include "common.h"
25 
26 #include "sabbu.h"
27 #include "gui_status_bar.h"
28 
29 extern struct sabbu app;
30 
gui_status_bar_set_text_from_string_internal(struct KryStatusBar * bar,char * text)31 static void gui_status_bar_set_text_from_string_internal(struct KryStatusBar *bar, char *text)
32 {
33   gtk_label_set_text(bar->status_label, text);
34 }
35 
gui_status_bar_set_color(struct KryStatusBar * bar,kryColor * color)36 static void gui_status_bar_set_color(struct KryStatusBar *bar, kryColor *color)
37 {
38   GdkColor color_gdk;
39   color_gdk.red = color->GetRed() * 257;
40   color_gdk.green = color->GetGreen() * 257;
41   color_gdk.blue = color->GetBlue() * 257;
42 
43   gtk_widget_modify_bg(GTK_WIDGET(bar->status_label_border), GTK_STATE_NORMAL, &color_gdk);
44   gtk_widget_modify_bg(GTK_WIDGET(bar->status_label_border), GTK_STATE_ACTIVE, &color_gdk);
45 }
46 
gui_status_bar_set_text_from_info_internal(struct KryStatusBar * bar,struct KryStatusBarInfo * info)47 static void gui_status_bar_set_text_from_info_internal(struct KryStatusBar *bar, struct KryStatusBarInfo *info)
48 {
49   if(!info)
50   {
51     g_warning("empty info passed to gui_main_status_set_text_temp");
52     return;
53   }
54 
55   bar->status_info_current = info;
56 
57   if(info->color)
58   {
59     gui_status_bar_set_color(bar, info->color);
60   }
61   else
62   {
63     gtk_widget_modify_bg(GTK_WIDGET(bar->status_label_border), GTK_STATE_NORMAL, NULL);
64     gtk_widget_modify_bg(GTK_WIDGET(bar->status_label_border), GTK_STATE_ACTIVE, NULL);
65   }
66 
67   gui_status_bar_set_text_from_string_internal(bar, info->text);
68 }
69 
gui_status_bar_set_text_internal(struct KryStatusBar * bar,enum status_type id,char * text,kryColor * color)70 static void gui_status_bar_set_text_internal(struct KryStatusBar *bar, enum status_type id, char *text, kryColor *color)
71 {
72   if(!bar->progress_bar)
73     return;
74 
75   if(bar->status_info_perm_text)
76     kry_free(bar->status_info_perm_text);
77 
78   struct KryStatusBarInfo *info = kry_new0(struct KryStatusBarInfo);
79   info->id = id;
80   info->text = text;
81   info->color = color;
82 
83   bar->status_info_perm_text = info;
84   bar->status_info_current = info;
85 
86   if(!bar->progress_bar_mode && !bar->update_timeout_id)
87     gui_status_bar_set_text_from_info_internal(bar, info);
88 }
89 
gui_status_bar_set_text(struct KryStatusBar * bar,enum status_type id,char * text)90 void gui_status_bar_set_text(struct KryStatusBar *bar, enum status_type id, char *text)
91 {
92   gui_status_bar_set_text_internal(bar, id, text, NULL);
93 }
94 
gui_status_bar_set_text_with_color(struct KryStatusBar * bar,enum status_type id,char * text,kryColor * color)95 void gui_status_bar_set_text_with_color(struct KryStatusBar *bar, enum status_type id, char *text, kryColor *color)
96 {
97   gui_status_bar_set_text_internal(bar, id, text, color);
98 }
99 
100 
gui_main_status_update_timeout(struct KryStatusBar * bar)101 gboolean gui_main_status_update_timeout(struct KryStatusBar *bar)
102 {
103   if(!bar->status_info_stack)
104   {
105     bar->update_timeout_id = 0;
106     return FALSE;
107   }
108 
109   struct KryStatusBarInfo *info = (struct KryStatusBarInfo *) bar->status_info_stack->data;
110   double secs = g_timer_elapsed(info->timer, NULL);
111   if(secs < 1.5)
112     return TRUE;
113 
114   g_timer_destroy(info->timer);
115   kry_free(info);
116   bar->status_info_stack = bar->status_info_stack->next;
117 
118   if(bar->status_info_stack)
119   {
120     struct KryStatusBarInfo *info = (struct KryStatusBarInfo *) bar->status_info_stack->data;
121     info->timer = g_timer_new();
122     gdk_threads_enter();
123     gui_status_bar_set_text_from_info_internal(bar, info);
124     gdk_threads_leave();
125     return TRUE;
126   }
127 
128   gdk_threads_enter();
129   gui_status_bar_set_text_from_info_internal(bar, bar->status_info_perm_text);
130   gdk_threads_leave();
131 
132   bar->update_timeout_id = 0;
133 
134   return FALSE;
135 }
136 
gui_status_bar_push_text_internal(struct KryStatusBar * bar,enum status_type id,char * text,kryColor * color)137 void gui_status_bar_push_text_internal(struct KryStatusBar *bar, enum status_type id, char *text, kryColor *color)
138 {
139   if(bar->status_info_stack)
140   {
141     struct KryStatusBarInfo *info_top = (struct KryStatusBarInfo *) bar->status_info_stack->data;
142     if(info_top->id == id)
143     {
144       g_timer_start(info_top->timer);
145       return;
146     }
147   }
148 
149   struct KryStatusBarInfo *info = kry_new0(struct KryStatusBarInfo);
150   info->id = id;
151   info->text = text;
152   info->color = color;
153 
154   bar->status_info_current = info;
155   bar->status_info_stack = g_list_append(bar->status_info_stack, info);
156 
157   if(!bar->update_timeout_id)
158   {
159     info->timer = g_timer_new();
160     gui_status_bar_set_text_from_info_internal(bar, info);
161     bar->update_timeout_id = g_timeout_add(500, (GSourceFunc) gui_main_status_update_timeout, bar);
162   }
163 
164 }
165 
gui_status_bar_push_text(struct KryStatusBar * bar,enum status_type id,char * text)166 void gui_status_bar_push_text(struct KryStatusBar *bar, enum status_type id, char *text)
167 {
168   gui_status_bar_push_text_internal(bar, id, text, NULL);
169 }
170 
gui_status_bar_push_text_with_color(struct KryStatusBar * bar,enum status_type id,char * text,kryColor * color)171 void gui_status_bar_push_text_with_color(struct KryStatusBar *bar, enum status_type id, char *text, kryColor *color)
172 {
173   gui_status_bar_push_text_internal(bar, id, text, color);
174 }
175 
176 
gui_status_bar_free_stack(struct KryStatusBar * bar)177 void gui_status_bar_free_stack(struct KryStatusBar *bar)
178 {
179   GList *ptr;
180   for(ptr = bar->status_info_stack; ptr; ptr = ptr->next)
181   {
182     struct KryStatusBarInfo *info = (struct KryStatusBarInfo *) ptr->data;
183     if(info->timer)
184       g_timer_destroy(info->timer);
185 
186     kry_free(info);
187   }
188 
189   bar->status_info_stack = NULL;
190 }
191 
gui_status_bar_text_and_progress_mode(struct KryStatusBar * bar,char * title)192 void gui_status_bar_text_and_progress_mode(struct KryStatusBar *bar, char *title)
193 {
194   bar->progress_bar_mode = TRUE;
195 
196   gui_status_bar_free_stack(bar);
197   gtk_widget_show(GTK_WIDGET(bar->progress_bar));
198 
199   gui_status_bar_set_text_from_string_internal(bar, title);
200 }
201 
gui_status_bar_set_progress(struct KryStatusBar * bar,double progress,gboolean update)202 void gui_status_bar_set_progress(struct KryStatusBar *bar, double progress, gboolean update)
203 {
204   gtk_progress_bar_set_fraction(bar->progress_bar, progress);
205 
206   if(update)
207     while (gtk_events_pending ())
208   	  gtk_main_iteration ();
209 }
210 
gui_status_bar_text_only_mode(struct KryStatusBar * bar)211 void gui_status_bar_text_only_mode(struct KryStatusBar *bar)
212 {
213   bar->progress_bar_mode = FALSE;
214   gui_status_bar_set_progress(bar, 0);
215 
216   gtk_widget_hide(GTK_WIDGET(bar->progress_bar));
217   gui_status_bar_set_text_from_info_internal(bar, bar->status_info_perm_text);
218 }
219 
220 
221 
gui_status_bar_get_widget(struct KryStatusBar * bar)222 GtkWidget *gui_status_bar_get_widget(struct KryStatusBar *bar)
223 {
224   return GTK_WIDGET(bar->hbox_status);
225 }
226 
gui_status_bar_hide_progress_bar(struct KryStatusBar * bar)227 void gui_status_bar_hide_progress_bar(struct KryStatusBar *bar)
228 {
229   gtk_widget_hide(GTK_WIDGET(bar->progress_bar));
230 }
231 
gui_status_bar_clicked_cb(GtkWidget widget,GdkEventButton * event,gpointer user_data)232 gboolean gui_status_bar_clicked_cb(GtkWidget widget, GdkEventButton *event, gpointer user_data)
233 {
234   return TRUE;
235 }
236 
gui_status_bar_color_changed_cb(kryColor * color,void * param,struct KryStatusBar * bar)237 void gui_status_bar_color_changed_cb(kryColor *color, void *param, struct KryStatusBar *bar)
238 {
239   if(bar->status_info_current->color == color)
240     gui_status_bar_set_color(bar, color);
241 }
242 
gui_status_bar_new()243 struct KryStatusBar *gui_status_bar_new()
244 {
245   struct KryStatusBar *bar = kry_new0(struct KryStatusBar);
246 
247   bar->hbox_status = GTK_HBOX(gtk_hbox_new(FALSE, 0));
248   bar->progress_bar = GTK_PROGRESS_BAR(gtk_progress_bar_new());
249   bar->status_label = GTK_LABEL(gtk_label_new(""));
250   gtk_widget_set_sensitive(GTK_WIDGET(bar->progress_bar), FALSE);
251 
252   bar->status_label_border = GTK_EVENT_BOX(gtk_event_box_new());
253   bar->status_label_frame = GTK_FRAME(gtk_frame_new(NULL));
254 
255   gtk_misc_set_padding(GTK_MISC(bar->status_label), 0, 3);
256 
257   gtk_container_add(GTK_CONTAINER(bar->status_label_border), GTK_WIDGET(bar->status_label_frame));
258   gtk_container_add(GTK_CONTAINER(bar->status_label_frame), GTK_WIDGET(bar->status_label));
259 
260   gtk_box_pack_start(GTK_BOX(bar->hbox_status), GTK_WIDGET(bar->status_label_border), TRUE, TRUE, 0);
261   gtk_box_pack_start(GTK_BOX(bar->hbox_status), GTK_WIDGET(bar->progress_bar), TRUE, TRUE, 0);
262 
263   gtk_widget_show_all(GTK_WIDGET(bar->status_label_border));
264 
265   g_signal_connect(G_OBJECT(bar->status_label_border), "button-press-event", G_CALLBACK(gui_status_bar_clicked_cb), NULL);
266 
267   bar->status_bar_color_changed_signal_id[0] =
268     app.ui.status_bar_color_table->Get(STATUS_COLOR_UNSAVED)
269       ->ConnectSignal(kryColor::SIGNAL_CHANGED, (krySignalFunc1) gui_status_bar_color_changed_cb, bar);
270 
271   bar->status_bar_color_changed_signal_id[1] =
272     app.ui.status_bar_color_table->Get(STATUS_COLOR_SUCCESS)
273       ->ConnectSignal(kryColor::SIGNAL_CHANGED, (krySignalFunc1) gui_status_bar_color_changed_cb, bar);
274 
275   return bar;
276 }
277 
gui_status_bar_free(struct KryStatusBar * bar)278 void gui_status_bar_free(struct KryStatusBar *bar)
279 {
280   app.ui.status_bar_color_table->Get(STATUS_COLOR_UNSAVED)
281     ->DisconnectSignal(kryColor::SIGNAL_CHANGED, bar->status_bar_color_changed_signal_id[0]);
282 
283   app.ui.status_bar_color_table->Get(STATUS_COLOR_SUCCESS)
284     ->DisconnectSignal(kryColor::SIGNAL_CHANGED, bar->status_bar_color_changed_signal_id[1]);
285 }
286