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