/* Copyright (C) 2001-2006, William Joseph. All Rights Reserved. This file is part of GtkRadiant. GtkRadiant 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 of the License, or (at your option) any later version. GtkRadiant 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 GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #if !defined(INCLUDED_GTKUTIL_WIDGET_H) #define INCLUDED_GTKUTIL_WIDGET_H #include #include #include "generic/callback.h" #include "warnings.h" #include "debugging/debugging.h" inline void widget_set_visible(GtkWidget* widget, bool shown) { if(shown) { gtk_widget_show(widget); } else { gtk_widget_hide(widget); } } inline bool widget_is_visible(GtkWidget* widget) { return GTK_WIDGET_VISIBLE(widget) != FALSE; } inline void widget_toggle_visible(GtkWidget* widget) { widget_set_visible(widget, !widget_is_visible(widget)); } class ToggleItem { BoolExportCallback m_exportCallback; typedef std::list ImportCallbacks; ImportCallbacks m_importCallbacks; public: ToggleItem(const BoolExportCallback& exportCallback) : m_exportCallback(exportCallback) { } void update() { for(ImportCallbacks::iterator i = m_importCallbacks.begin(); i != m_importCallbacks.end(); ++i) { m_exportCallback(*i); } } void addCallback(const BoolImportCallback& callback) { m_importCallbacks.push_back(callback); m_exportCallback(callback); } typedef MemberCaller1 AddCallbackCaller; }; class ToggleShown { bool m_shownDeferred; ToggleShown(const ToggleShown& other); // NOT COPYABLE ToggleShown& operator=(const ToggleShown& other); // NOT ASSIGNABLE static gboolean notify_visible(GtkWidget* widget, gpointer dummy, ToggleShown* self) { self->update(); return FALSE; } static gboolean destroy(GtkWidget* widget, ToggleShown* self) { self->m_shownDeferred = GTK_WIDGET_VISIBLE(self->m_widget) != FALSE; self->m_widget = 0; return FALSE; } public: GtkWidget* m_widget; ToggleItem m_item; ToggleShown(bool shown) : m_shownDeferred(shown), m_widget(0), m_item(ActiveCaller(*this)) { } void update() { m_item.update(); } bool active() const { if(m_widget == 0) { return m_shownDeferred; } else { return GTK_WIDGET_VISIBLE(m_widget) != FALSE; } } void exportActive(const BoolImportCallback& importCallback) { importCallback(active()); } typedef MemberCaller1 ActiveCaller; void set(bool shown) { if(m_widget == 0) { m_shownDeferred = shown; } else { widget_set_visible(m_widget, shown); } } void toggle() { widget_toggle_visible(m_widget); } typedef MemberCaller ToggleCaller; void connect(GtkWidget* widget) { m_widget = widget; widget_set_visible(m_widget, m_shownDeferred); g_signal_connect(G_OBJECT(m_widget), "notify::visible", G_CALLBACK(notify_visible), this); g_signal_connect(G_OBJECT(m_widget), "destroy", G_CALLBACK(destroy), this); update(); } }; inline void widget_queue_draw(GtkWidget& widget) { gtk_widget_queue_draw(&widget); } typedef ReferenceCaller WidgetQueueDrawCaller; inline void widget_make_default(GtkWidget* widget) { GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_DEFAULT); gtk_widget_grab_default(widget); } class WidgetFocusPrinter { const char* m_name; static gboolean focus_in(GtkWidget *widget, GdkEventFocus *event, WidgetFocusPrinter* self) { globalOutputStream() << self->m_name << " takes focus\n"; return FALSE; } static gboolean focus_out(GtkWidget *widget, GdkEventFocus *event, WidgetFocusPrinter* self) { globalOutputStream() << self->m_name << " loses focus\n"; return FALSE; } public: WidgetFocusPrinter(const char* name) : m_name(name) { } void connect(GtkWidget* widget) { g_signal_connect(G_OBJECT(widget), "focus_in_event", G_CALLBACK(focus_in), this); g_signal_connect(G_OBJECT(widget), "focus_out_event", G_CALLBACK(focus_out), this); } }; #endif