Code

Block "special" solid gradients from gradient F&S dialog.
[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         }
121         
122         _d->set_opacity(current - ((current - goal) / 2));
123         _steps--;
124         return true;
127 #endif
129 FloatingBehavior::~FloatingBehavior() 
130
131     delete _d;
134 Behavior *
135 FloatingBehavior::create(Dialog &dialog)
137     return new FloatingBehavior(dialog);
140 inline FloatingBehavior::operator Gtk::Widget &()                          { return *_d; }
141 inline GtkWidget *FloatingBehavior::gobj()                                { return GTK_WIDGET(_d->gobj()); }
142 inline Gtk::VBox* FloatingBehavior::get_vbox()                            { return _d->get_vbox(); }
143 inline void FloatingBehavior::present()                                   { _d->present(); }
144 inline void FloatingBehavior::hide()                                      { _d->hide(); }
145 inline void FloatingBehavior::show()                                      { _d->show(); }
146 inline void FloatingBehavior::show_all_children()                         { _d->show_all_children(); }
147 inline void FloatingBehavior::resize(int width, int height)               { _d->resize(width, height); }
148 inline void FloatingBehavior::move(int x, int y)                          { _d->move(x, y); }
149 inline void FloatingBehavior::set_position(Gtk::WindowPosition position)  { _d->set_position(position); }
150 inline void FloatingBehavior::set_size_request(int width, int height)     { _d->set_size_request(width, height); }
151 inline void FloatingBehavior::size_request(Gtk::Requisition &requisition) { _d->size_request(requisition); }
152 inline void FloatingBehavior::get_position(int &x, int &y)                { _d->get_position(x, y); }
153 inline void FloatingBehavior::get_size(int &width, int &height)           { _d->get_size(width, height); }
154 inline void FloatingBehavior::set_title(Glib::ustring title)              { _d->set_title(title); }
155 inline void FloatingBehavior::set_sensitive(bool sensitive)               { _d->set_sensitive(sensitive); }
157 Glib::SignalProxy0<void> FloatingBehavior::signal_show() { return _d->signal_show(); }
158 Glib::SignalProxy0<void> FloatingBehavior::signal_hide() { return _d->signal_hide(); }
159 Glib::SignalProxy1<bool, GdkEventAny *> FloatingBehavior::signal_delete_event () { return _d->signal_delete_event(); }
162 void
163 FloatingBehavior::onHideF12()
165     _dialog.save_geometry();
166     hide();
169 void
170 FloatingBehavior::onShowF12()
172     show();
173     _dialog.read_geometry();
176 void
177 FloatingBehavior::onShutdown() {}
179 void
180 FloatingBehavior::onDesktopActivated (SPDesktop *desktop)
182     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
183     gint transient_policy = prefs->getIntLimited("/options/transientpolicy/value", 1, 0, 2);
185 #ifdef WIN32 // Win32 special code to enable transient dialogs
186     transient_policy = 2;
187 #endif        
189     if (!transient_policy) 
190         return;
192     GtkWindow *dialog_win = GTK_WINDOW(_d->gobj());
194     if (_dialog.retransientize_suppress) {
195          /* if retransientizing of this dialog is still forbidden after
196           * previous call warning turned off because it was confusingly fired
197           * when loading many files from command line
198           */
200          // g_warning("Retranzientize aborted! You're switching windows too fast!");
201         return;
202     }
204     if (dialog_win)
205     {
206         _dialog.retransientize_suppress = true; // disallow other attempts to retranzientize this dialog
208         desktop->setWindowTransient (dialog_win);
210         /*
211          * This enables "aggressive" transientization,
212          * i.e. dialogs always emerging on top when you switch documents. Note
213          * however that this breaks "click to raise" policy of a window
214          * manager because the switched-to document will be raised at once
215          * (so that its transients also could raise)
216          */
217         if (transient_policy == 2 && ! _dialog._hiddenF12 && !_dialog._user_hidden) {
218             // without this, a transient window not always emerges on top
219             gtk_window_present (dialog_win);
220         }
221     }
223     // we're done, allow next retransientizing not sooner than after 120 msec
224     gtk_timeout_add (120, (GtkFunction) sp_retransientize_again, (gpointer) _d);
228 } // namespace Behavior
229 } // namespace Dialog
230 } // namespace UI
231 } // namespace Inkscape
233 /*
234   Local Variables:
235   mode:c++
236   c-file-style:"stroustrup"
237   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
238   indent-tabs-mode:nil
239   fill-column:99
240   End:
241 */
242 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :