/* * Copyright (C) 2004-2005 Vadim Berezniker * http://www.kryptolus.com * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This Program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * http://www.gnu.org/copyleft/gpl.html * */ #include "stdafx.h" #include "common.h" #include "sabbu.h" #include "gui_status_bar.h" extern struct sabbu app; static void gui_status_bar_set_text_from_string_internal(struct KryStatusBar *bar, char *text) { gtk_label_set_text(bar->status_label, text); } static void gui_status_bar_set_color(struct KryStatusBar *bar, kryColor *color) { GdkColor color_gdk; color_gdk.red = color->GetRed() * 257; color_gdk.green = color->GetGreen() * 257; color_gdk.blue = color->GetBlue() * 257; gtk_widget_modify_bg(GTK_WIDGET(bar->status_label_border), GTK_STATE_NORMAL, &color_gdk); gtk_widget_modify_bg(GTK_WIDGET(bar->status_label_border), GTK_STATE_ACTIVE, &color_gdk); } static void gui_status_bar_set_text_from_info_internal(struct KryStatusBar *bar, struct KryStatusBarInfo *info) { if(!info) { g_warning("empty info passed to gui_main_status_set_text_temp"); return; } bar->status_info_current = info; if(info->color) { gui_status_bar_set_color(bar, info->color); } else { gtk_widget_modify_bg(GTK_WIDGET(bar->status_label_border), GTK_STATE_NORMAL, NULL); gtk_widget_modify_bg(GTK_WIDGET(bar->status_label_border), GTK_STATE_ACTIVE, NULL); } gui_status_bar_set_text_from_string_internal(bar, info->text); } static void gui_status_bar_set_text_internal(struct KryStatusBar *bar, enum status_type id, char *text, kryColor *color) { if(!bar->progress_bar) return; if(bar->status_info_perm_text) kry_free(bar->status_info_perm_text); struct KryStatusBarInfo *info = kry_new0(struct KryStatusBarInfo); info->id = id; info->text = text; info->color = color; bar->status_info_perm_text = info; bar->status_info_current = info; if(!bar->progress_bar_mode && !bar->update_timeout_id) gui_status_bar_set_text_from_info_internal(bar, info); } void gui_status_bar_set_text(struct KryStatusBar *bar, enum status_type id, char *text) { gui_status_bar_set_text_internal(bar, id, text, NULL); } void gui_status_bar_set_text_with_color(struct KryStatusBar *bar, enum status_type id, char *text, kryColor *color) { gui_status_bar_set_text_internal(bar, id, text, color); } gboolean gui_main_status_update_timeout(struct KryStatusBar *bar) { if(!bar->status_info_stack) { bar->update_timeout_id = 0; return FALSE; } struct KryStatusBarInfo *info = (struct KryStatusBarInfo *) bar->status_info_stack->data; double secs = g_timer_elapsed(info->timer, NULL); if(secs < 1.5) return TRUE; g_timer_destroy(info->timer); kry_free(info); bar->status_info_stack = bar->status_info_stack->next; if(bar->status_info_stack) { struct KryStatusBarInfo *info = (struct KryStatusBarInfo *) bar->status_info_stack->data; info->timer = g_timer_new(); gdk_threads_enter(); gui_status_bar_set_text_from_info_internal(bar, info); gdk_threads_leave(); return TRUE; } gdk_threads_enter(); gui_status_bar_set_text_from_info_internal(bar, bar->status_info_perm_text); gdk_threads_leave(); bar->update_timeout_id = 0; return FALSE; } void gui_status_bar_push_text_internal(struct KryStatusBar *bar, enum status_type id, char *text, kryColor *color) { if(bar->status_info_stack) { struct KryStatusBarInfo *info_top = (struct KryStatusBarInfo *) bar->status_info_stack->data; if(info_top->id == id) { g_timer_start(info_top->timer); return; } } struct KryStatusBarInfo *info = kry_new0(struct KryStatusBarInfo); info->id = id; info->text = text; info->color = color; bar->status_info_current = info; bar->status_info_stack = g_list_append(bar->status_info_stack, info); if(!bar->update_timeout_id) { info->timer = g_timer_new(); gui_status_bar_set_text_from_info_internal(bar, info); bar->update_timeout_id = g_timeout_add(500, (GSourceFunc) gui_main_status_update_timeout, bar); } } void gui_status_bar_push_text(struct KryStatusBar *bar, enum status_type id, char *text) { gui_status_bar_push_text_internal(bar, id, text, NULL); } void gui_status_bar_push_text_with_color(struct KryStatusBar *bar, enum status_type id, char *text, kryColor *color) { gui_status_bar_push_text_internal(bar, id, text, color); } void gui_status_bar_free_stack(struct KryStatusBar *bar) { GList *ptr; for(ptr = bar->status_info_stack; ptr; ptr = ptr->next) { struct KryStatusBarInfo *info = (struct KryStatusBarInfo *) ptr->data; if(info->timer) g_timer_destroy(info->timer); kry_free(info); } bar->status_info_stack = NULL; } void gui_status_bar_text_and_progress_mode(struct KryStatusBar *bar, char *title) { bar->progress_bar_mode = TRUE; gui_status_bar_free_stack(bar); gtk_widget_show(GTK_WIDGET(bar->progress_bar)); gui_status_bar_set_text_from_string_internal(bar, title); } void gui_status_bar_set_progress(struct KryStatusBar *bar, double progress, gboolean update) { gtk_progress_bar_set_fraction(bar->progress_bar, progress); if(update) while (gtk_events_pending ()) gtk_main_iteration (); } void gui_status_bar_text_only_mode(struct KryStatusBar *bar) { bar->progress_bar_mode = FALSE; gui_status_bar_set_progress(bar, 0); gtk_widget_hide(GTK_WIDGET(bar->progress_bar)); gui_status_bar_set_text_from_info_internal(bar, bar->status_info_perm_text); } GtkWidget *gui_status_bar_get_widget(struct KryStatusBar *bar) { return GTK_WIDGET(bar->hbox_status); } void gui_status_bar_hide_progress_bar(struct KryStatusBar *bar) { gtk_widget_hide(GTK_WIDGET(bar->progress_bar)); } gboolean gui_status_bar_clicked_cb(GtkWidget widget, GdkEventButton *event, gpointer user_data) { return TRUE; } void gui_status_bar_color_changed_cb(kryColor *color, void *param, struct KryStatusBar *bar) { if(bar->status_info_current->color == color) gui_status_bar_set_color(bar, color); } struct KryStatusBar *gui_status_bar_new() { struct KryStatusBar *bar = kry_new0(struct KryStatusBar); bar->hbox_status = GTK_HBOX(gtk_hbox_new(FALSE, 0)); bar->progress_bar = GTK_PROGRESS_BAR(gtk_progress_bar_new()); bar->status_label = GTK_LABEL(gtk_label_new("")); gtk_widget_set_sensitive(GTK_WIDGET(bar->progress_bar), FALSE); bar->status_label_border = GTK_EVENT_BOX(gtk_event_box_new()); bar->status_label_frame = GTK_FRAME(gtk_frame_new(NULL)); gtk_misc_set_padding(GTK_MISC(bar->status_label), 0, 3); gtk_container_add(GTK_CONTAINER(bar->status_label_border), GTK_WIDGET(bar->status_label_frame)); gtk_container_add(GTK_CONTAINER(bar->status_label_frame), GTK_WIDGET(bar->status_label)); gtk_box_pack_start(GTK_BOX(bar->hbox_status), GTK_WIDGET(bar->status_label_border), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(bar->hbox_status), GTK_WIDGET(bar->progress_bar), TRUE, TRUE, 0); gtk_widget_show_all(GTK_WIDGET(bar->status_label_border)); g_signal_connect(G_OBJECT(bar->status_label_border), "button-press-event", G_CALLBACK(gui_status_bar_clicked_cb), NULL); bar->status_bar_color_changed_signal_id[0] = app.ui.status_bar_color_table->Get(STATUS_COLOR_UNSAVED) ->ConnectSignal(kryColor::SIGNAL_CHANGED, (krySignalFunc1) gui_status_bar_color_changed_cb, bar); bar->status_bar_color_changed_signal_id[1] = app.ui.status_bar_color_table->Get(STATUS_COLOR_SUCCESS) ->ConnectSignal(kryColor::SIGNAL_CHANGED, (krySignalFunc1) gui_status_bar_color_changed_cb, bar); return bar; } void gui_status_bar_free(struct KryStatusBar *bar) { app.ui.status_bar_color_table->Get(STATUS_COLOR_UNSAVED) ->DisconnectSignal(kryColor::SIGNAL_CHANGED, bar->status_bar_color_changed_signal_id[0]); app.ui.status_bar_color_table->Get(STATUS_COLOR_SUCCESS) ->DisconnectSignal(kryColor::SIGNAL_CHANGED, bar->status_bar_color_changed_signal_id[1]); }