Code

zero out pointers to deleted members. might expose problems if a stail pointer is...
[inkscape.git] / src / ui / dialog / floating-behavior.cpp
1 /** @file
2  * @brief Floating dialog implementation.
3  */
4 /* Author:
5  *   Gustav Broberg <broberg@kth.se>
6  *
7  * Copyright (C) 2007 Authors
8  *
9  * Released under GNU GPL.  Read the file 'COPYING' for more information.
10  */
12 #include <gtkmm/stock.h>
13 #include <gtk/gtk.h>
15 #include "floating-behavior.h"
16 #include "dialog.h"
18 #include "application/application.h"
19 #include "application/editor.h"
20 #include "inkscape.h"
21 #include "desktop.h"
22 #include "dialogs/dialog-events.h"
23 #include "interface.h"
24 #include "preferences.h"
25 #include "verbs.h"
27 namespace Inkscape {
28 namespace UI {
29 namespace Dialog {
30 namespace Behavior {
32 FloatingBehavior::FloatingBehavior(Dialog &dialog) :
33     Behavior(dialog),
34     _d (new Gtk::Dialog(_dialog._title))
35 #if GTK_VERSION_GE(2, 12)
36     ,_dialog_active(_d->property_is_active())
37     ,_steps(0)
38     ,_trans_focus(Inkscape::Preferences::get()->getDoubleLimited("/dialogs/transparency/on-focus", 0.95, 0.0, 1.0))
39     ,_trans_blur(Inkscape::Preferences::get()->getDoubleLimited("/dialogs/transparency/on-blur", 0.50, 0.0, 1.0))
40     ,_trans_time(Inkscape::Preferences::get()->getIntLimited("/dialogs/transparency/animate-time", 100, 0, 5000))
41 #endif
42 {
43     hide();
44     _d->set_has_separator(false);
46     signal_delete_event().connect(sigc::mem_fun(_dialog, &Inkscape::UI::Dialog::Dialog::_onDeleteEvent));
48     sp_transientize(GTK_WIDGET(_d->gobj()));
49     _dialog.retransientize_suppress = false;
51 #if GTK_VERSION_GE(2, 12)
52     _focus_event();
53     _dialog_active.signal_changed().connect(sigc::mem_fun(this, &FloatingBehavior::_focus_event));
54 #endif
56 }
58 #if GTK_VERSION_GE(2, 12)
59 /** \brief  A function called when the window gets focus
61     This function gets called on a focus event.  It figures out how much
62     time is required for a transition, and the number of steps that'll take,
63     and sets up the _trans_timer function to do the work.  If the transition
64     time is set to 0 ms it just calls _trans_timer once with _steps equal to
65     zero so that the transition happens instantaneously.  This occurs on
66     windows as opacity changes cause flicker there.
67 */
68 void FloatingBehavior::_focus_event (void)
69 {
70     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
71     _steps = 0;
72     _trans_focus = prefs->getDoubleLimited("/dialogs/transparency/on-focus", 0.95, 0.0, 1.0);
73     _trans_blur = prefs->getDoubleLimited("/dialogs/transparency/on-blur", 0.50, 0.0, 1.0);
74     _trans_time = prefs->getIntLimited("/dialogs/transparency/animate-time", 100, 0, 5000);
76     if (_trans_time != 0) {
77         float diff = _trans_focus - _trans_blur;
78         if (diff < 0.0) diff *= -1.0;
80         while (diff > 0.05) {
81             _steps++;
82             diff = diff / 2.0;
83         }
85         if (_steps != 0) {
86             Glib::signal_timeout().connect(sigc::mem_fun(this, &FloatingBehavior::_trans_timer), _trans_time / _steps);
87         }
88     }
89     _trans_timer();
91     return;
92 }
94 /** \brief  Move the opacity of a window towards our goal
96     This is a timer function that is set up by _focus_event to slightly
97     move the opacity of the window along in an animated fashion.  It moves
98     the opacity half way to the goal until it runs out of steps, and then
99     it just forces the goal.
100 */
101 bool FloatingBehavior::_trans_timer (void) {
102     // printf("Go go gadget timer: %d\n", _steps);
103     if (_steps == 0) {
104         if (_dialog_active.get_value()) {
105             _d->set_opacity(_trans_focus);
106         } else {
107             _d->set_opacity(_trans_blur);
108         }
110         return false;
111     }
113     float goal, current;
114     goal = current = _d->get_opacity();
116     if (_dialog_active.get_value()) {
117         goal = _trans_focus;
118     } else {
119         goal = _trans_blur;
120     }
122     _d->set_opacity(current - ((current - goal) / 2));
123     _steps--;
124     return true;
127 #endif
129 FloatingBehavior::~FloatingBehavior()
131     delete _d;
132     _d = 0;
135 Behavior *
136 FloatingBehavior::create(Dialog &dialog)
138     return new FloatingBehavior(dialog);
141 inline FloatingBehavior::operator Gtk::Widget &()                          { return *_d; }
142 inline GtkWidget *FloatingBehavior::gobj()                                { return GTK_WIDGET(_d->gobj()); }
143 inline Gtk::VBox* FloatingBehavior::get_vbox()                            { return _d->get_vbox(); }
144 inline void FloatingBehavior::present()                                   { _d->present(); }
145 inline void FloatingBehavior::hide()                                      { _d->hide(); }
146 inline void FloatingBehavior::show()                                      { _d->show(); }
147 inline void FloatingBehavior::show_all_children()                         { _d->show_all_children(); }
148 inline void FloatingBehavior::resize(int width, int height)               { _d->resize(width, height); }
149 inline void FloatingBehavior::move(int x, int y)                          { _d->move(x, y); }
150 inline void FloatingBehavior::set_position(Gtk::WindowPosition position)  { _d->set_position(position); }
151 inline void FloatingBehavior::set_size_request(int width, int height)     { _d->set_size_request(width, height); }
152 inline void FloatingBehavior::size_request(Gtk::Requisition &requisition) { _d->size_request(requisition); }
153 inline void FloatingBehavior::get_position(int &x, int &y)                { _d->get_position(x, y); }
154 inline void FloatingBehavior::get_size(int &width, int &height)           { _d->get_size(width, height); }
155 inline void FloatingBehavior::set_title(Glib::ustring title)              { _d->set_title(title); }
156 inline void FloatingBehavior::set_sensitive(bool sensitive)               { _d->set_sensitive(sensitive); }
158 Glib::SignalProxy0<void> FloatingBehavior::signal_show() { return _d->signal_show(); }
159 Glib::SignalProxy0<void> FloatingBehavior::signal_hide() { return _d->signal_hide(); }
160 Glib::SignalProxy1<bool, GdkEventAny *> FloatingBehavior::signal_delete_event () { return _d->signal_delete_event(); }
163 void
164 FloatingBehavior::onHideF12()
166     _dialog.save_geometry();
167     hide();
170 void
171 FloatingBehavior::onShowF12()
173     show();
174     _dialog.read_geometry();
177 void
178 FloatingBehavior::onShutdown() {}
180 void
181 FloatingBehavior::onDesktopActivated (SPDesktop *desktop)
183     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
184     gint transient_policy = prefs->getIntLimited("/options/transientpolicy/value", 1, 0, 2);
186 #ifdef WIN32 // Win32 special code to enable transient dialogs
187     transient_policy = 2;
188 #endif
190     if (!transient_policy)
191         return;
193     GtkWindow *dialog_win = GTK_WINDOW(_d->gobj());
195     if (_dialog.retransientize_suppress) {
196          /* if retransientizing of this dialog is still forbidden after
197           * previous call warning turned off because it was confusingly fired
198           * when loading many files from command line
199           */
201          // g_warning("Retranzientize aborted! You're switching windows too fast!");
202         return;
203     }
205     if (dialog_win)
206     {
207         _dialog.retransientize_suppress = true; // disallow other attempts to retranzientize this dialog
209         desktop->setWindowTransient (dialog_win);
211         /*
212          * This enables "aggressive" transientization,
213          * i.e. dialogs always emerging on top when you switch documents. Note
214          * however that this breaks "click to raise" policy of a window
215          * manager because the switched-to document will be raised at once
216          * (so that its transients also could raise)
217          */
218         if (transient_policy == 2 && ! _dialog._hiddenF12 && !_dialog._user_hidden) {
219             // without this, a transient window not always emerges on top
220             gtk_window_present (dialog_win);
221         }
222     }
224     // we're done, allow next retransientizing not sooner than after 120 msec
225     gtk_timeout_add (120, (GtkFunction) sp_retransientize_again, (gpointer) _d);
229 } // namespace Behavior
230 } // namespace Dialog
231 } // namespace UI
232 } // namespace Inkscape
234 /*
235   Local Variables:
236   mode:c++
237   c-file-style:"stroustrup"
238   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
239   indent-tabs-mode:nil
240   fill-column:99
241   End:
242 */
243 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :