~valavanisalex/ubuntu/precise/inkscape/fix-943984

« back to all changes in this revision

Viewing changes to inkscape-0.47pre1/src/ui/widget/dock.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Bryce Harrington
  • Date: 2009-07-02 17:09:45 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20090702170945-nn6d6zswovbwju1t
Tags: 0.47~pre1-0ubuntu1
* New upstream release.
  - Don't constrain maximization on small resolution devices (pre0)
    (LP: #348842)
  - Fixes segfault on startup (pre0)
    (LP: #391149)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
 * @brief A desktop dock pane to dock dialogs.
 
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
 */
 
11
 
 
12
#include "inkscape.h"
 
13
#include "preferences.h"
 
14
#include "desktop.h"
 
15
 
 
16
#include "dock.h"
 
17
 
 
18
#include <gtkmm/adjustment.h>
 
19
 
 
20
namespace Inkscape {
 
21
namespace UI {
 
22
namespace Widget {
 
23
 
 
24
namespace {
 
25
 
 
26
void hideCallback(GtkObject */*object*/, gpointer dock_ptr)
 
27
{
 
28
    g_return_if_fail( dock_ptr != NULL );
 
29
 
 
30
    Dock *dock = (Dock *)dock_ptr;
 
31
    dock->hide();
 
32
}
 
33
 
 
34
void unhideCallback(GtkObject */*object*/, gpointer dock_ptr)
 
35
{
 
36
    g_return_if_fail( dock_ptr != NULL );
 
37
 
 
38
    Dock *dock = (Dock *)dock_ptr;
 
39
    dock->show();
 
40
}
 
41
 
 
42
}
 
43
 
 
44
const int Dock::_default_empty_width = 0;
 
45
const int Dock::_default_dock_bar_width = 36;
 
46
 
 
47
 
 
48
Dock::Dock(Gtk::Orientation orientation)
 
49
    : _gdl_dock (GDL_DOCK (gdl_dock_new())),
 
50
      _gdl_dock_bar (GDL_DOCK_BAR (gdl_dock_bar_new(GDL_DOCK(_gdl_dock)))),
 
51
      _scrolled_window (Gtk::manage(new Gtk::ScrolledWindow))
 
52
{
 
53
    gdl_dock_bar_set_orientation(_gdl_dock_bar, static_cast<GtkOrientation>(orientation));
 
54
 
 
55
    switch (orientation) {
 
56
        case Gtk::ORIENTATION_VERTICAL:
 
57
            _dock_box = Gtk::manage(new Gtk::HBox());
 
58
            _paned = Gtk::manage(new Gtk::VPaned());
 
59
            break;
 
60
        case Gtk::ORIENTATION_HORIZONTAL:
 
61
            _dock_box = Gtk::manage(new Gtk::VBox());
 
62
            _paned = Gtk::manage(new Gtk::HPaned());
 
63
    }
 
64
 
 
65
    _scrolled_window->add(*_dock_box);
 
66
    _scrolled_window->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
 
67
 
 
68
    _paned->pack1(*Glib::wrap(GTK_WIDGET(_gdl_dock)), false, false);
 
69
    _paned->pack2(_filler, true, false);
 
70
 
 
71
    _dock_box->pack_start(*_paned, Gtk::PACK_EXPAND_WIDGET);
 
72
    _dock_box->pack_end(*Gtk::manage(Glib::wrap(GTK_WIDGET(_gdl_dock_bar))), Gtk::PACK_SHRINK);
 
73
    _dock_box->get_parent()->set_resize_mode(Gtk::RESIZE_PARENT);
 
74
 
 
75
    _scrolled_window->set_size_request(0);
 
76
 
 
77
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
 
78
    GdlSwitcherStyle gdl_switcher_style =
 
79
        static_cast<GdlSwitcherStyle>(prefs->getIntLimited("/options/dock/switcherstyle",
 
80
                                                                      GDL_SWITCHER_STYLE_BOTH, 0, 4));
 
81
 
 
82
    g_object_set (GDL_DOCK_OBJECT(_gdl_dock)->master,
 
83
                  "switcher-style", gdl_switcher_style,
 
84
                  "expand-direction", GDL_DOCK_EXPANSION_DIRECTION_DOWN,
 
85
                  NULL);
 
86
 
 
87
    GdlDockBarStyle gdl_dock_bar_style =
 
88
        static_cast<GdlDockBarStyle>(prefs->getIntLimited("/options/dock/dockbarstyle",
 
89
                                                                     GDL_DOCK_BAR_BOTH, 0, 3));
 
90
 
 
91
    gdl_dock_bar_set_style(_gdl_dock_bar, gdl_dock_bar_style);
 
92
 
 
93
    g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_hide", G_CALLBACK(hideCallback), (void *)this);
 
94
    g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_unhide", G_CALLBACK(unhideCallback), (void *)this);
 
95
 
 
96
    g_signal_connect(_paned->gobj(), "button-press-event", G_CALLBACK(_on_paned_button_event), (void *)this);
 
97
    g_signal_connect(_paned->gobj(), "button-release-event", G_CALLBACK(_on_paned_button_event), (void *)this);
 
98
 
 
99
    signal_layout_changed().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::Dock::_onLayoutChanged));
 
100
}
 
101
 
 
102
Dock::~Dock()
 
103
{
 
104
    g_free(_gdl_dock);
 
105
    g_free(_gdl_dock_bar);
 
106
}
 
107
 
 
108
void
 
109
Dock::addItem(DockItem& item, DockItem::Placement placement)
 
110
{
 
111
    _dock_items.push_back(&item);
 
112
    gdl_dock_add_item(_gdl_dock, GDL_DOCK_ITEM(item.gobj()), (GdlDockPlacement)placement);
 
113
 
 
114
    // FIXME: This is a hack to prevent the dock from expanding the main window, this can't be done
 
115
    // initially as the paned doesn't exist.
 
116
    if (Gtk::Paned *paned = getParentPaned()) {
 
117
        paned->set_resize_mode(Gtk::RESIZE_QUEUE);
 
118
    }
 
119
}
 
120
 
 
121
Gtk::Widget&
 
122
Dock::getWidget()
 
123
{
 
124
     return *_scrolled_window;
 
125
}
 
126
 
 
127
Gtk::Paned *
 
128
Dock::getParentPaned()
 
129
{
 
130
    g_return_val_if_fail(_dock_box, 0);
 
131
    Gtk::Container *parent = getWidget().get_parent();
 
132
    return (parent != 0 ? dynamic_cast<Gtk::Paned *>(parent) : 0);
 
133
}
 
134
 
 
135
 
 
136
Gtk::Paned *
 
137
Dock::getPaned()
 
138
{
 
139
    return _paned;
 
140
}
 
141
 
 
142
GtkWidget *
 
143
Dock::getGdlWidget()
 
144
{
 
145
    return GTK_WIDGET(_gdl_dock);
 
146
}
 
147
 
 
148
bool
 
149
Dock::isEmpty() const
 
150
{
 
151
    std::list<const DockItem *>::const_iterator
 
152
        i = _dock_items.begin(),
 
153
        e = _dock_items.end();
 
154
 
 
155
    for (; i != e; ++i) {
 
156
        if ((*i)->getState() == DockItem::DOCKED_STATE) {
 
157
            return false;
 
158
        }
 
159
    }
 
160
 
 
161
    return true;
 
162
}
 
163
 
 
164
bool
 
165
Dock::hasIconifiedItems() const
 
166
{
 
167
    std::list<const DockItem *>::const_iterator
 
168
        i = _dock_items.begin(),
 
169
        e = _dock_items.end();
 
170
 
 
171
    for (; i != e; ++i) {
 
172
        if ((*i)->isIconified()) {
 
173
            return true;
 
174
        }
 
175
    }
 
176
 
 
177
    return false;
 
178
}
 
179
 
 
180
void
 
181
Dock::hide()
 
182
{
 
183
    getWidget().hide();
 
184
}
 
185
 
 
186
void
 
187
Dock::show()
 
188
{
 
189
    getWidget().show();
 
190
}
 
191
 
 
192
void
 
193
Dock::toggleDockable(int width, int height)
 
194
{
 
195
    static int prev_horizontal_position, prev_vertical_position;
 
196
 
 
197
    Gtk::Paned *parent_paned = getParentPaned();
 
198
 
 
199
    if (width > 0 && height > 0) {
 
200
        prev_horizontal_position = parent_paned->get_position();
 
201
        prev_vertical_position = _paned->get_position();
 
202
 
 
203
        if (getWidget().get_width() < width)
 
204
            parent_paned->set_position(parent_paned->get_width() - width);
 
205
 
 
206
        if (_paned->get_position() < height)
 
207
            _paned->set_position(height);
 
208
 
 
209
    } else {
 
210
        parent_paned->set_position(prev_horizontal_position);
 
211
        _paned->set_position(prev_vertical_position);
 
212
    }
 
213
 
 
214
}
 
215
 
 
216
void
 
217
Dock::scrollToItem(DockItem& item)
 
218
{
 
219
    int item_x, item_y;
 
220
    item.getWidget().translate_coordinates(getWidget(), 0, 0, item_x, item_y);
 
221
 
 
222
    int dock_height = getWidget().get_height(), item_height = item.getWidget().get_height();
 
223
    double vadjustment = _scrolled_window->get_vadjustment()->get_value();
 
224
 
 
225
    if (item_y < 0)
 
226
        _scrolled_window->get_vadjustment()->set_value(vadjustment + item_y);
 
227
    else if (item_y + item_height > dock_height)
 
228
        _scrolled_window->get_vadjustment()->set_value(
 
229
            vadjustment + ((item_y + item_height) - dock_height));
 
230
}
 
231
 
 
232
Glib::SignalProxy0<void>
 
233
Dock::signal_layout_changed()
 
234
{
 
235
    return Glib::SignalProxy0<void>(Glib::wrap(GTK_WIDGET(_gdl_dock)),
 
236
                                    &_signal_layout_changed_proxy);
 
237
}
 
238
 
 
239
void
 
240
Dock::_onLayoutChanged()
 
241
{
 
242
    if (isEmpty()) {
 
243
        if (hasIconifiedItems()) {
 
244
            _scrolled_window->set_size_request(_default_dock_bar_width);
 
245
        } else {
 
246
            _scrolled_window->set_size_request(_default_empty_width);
 
247
        }
 
248
 
 
249
        getParentPaned()->set_position(INT_MAX);
 
250
    } else {
 
251
        // unset any forced size requests
 
252
        _paned->get_child1()->set_size_request(-1, -1);
 
253
        _scrolled_window->set_size_request(-1);
 
254
    }
 
255
}
 
256
 
 
257
void
 
258
Dock::_onPanedButtonEvent(GdkEventButton *event)
 
259
{
 
260
    if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
 
261
        /* unset size request when starting a drag */
 
262
        _paned->get_child1()->set_size_request(-1, -1);
 
263
}
 
264
 
 
265
gboolean
 
266
Dock::_on_paned_button_event(GtkWidget */*widget*/, GdkEventButton *event, gpointer user_data)
 
267
{
 
268
    if (Dock *dock = static_cast<Dock *>(user_data))
 
269
        dock->_onPanedButtonEvent(event);
 
270
 
 
271
    return FALSE;
 
272
}
 
273
 
 
274
const Glib::SignalProxyInfo
 
275
Dock::_signal_layout_changed_proxy =
 
276
{
 
277
    "layout-changed",
 
278
    (GCallback) &Glib::SignalProxyNormal::slot0_void_callback,
 
279
    (GCallback) &Glib::SignalProxyNormal::slot0_void_callback
 
280
};
 
281
 
 
282
 
 
283
} // namespace Widget
 
284
} // namespace UI
 
285
} // namespace Inkscape
 
286
 
 
287
 
 
288
/*
 
289
  Local Variables:
 
290
  mode:c++
 
291
  c-file-style:"stroustrup"
 
292
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
 
293
  indent-tabs-mode:nil
 
294
  fill-column:99
 
295
  End:
 
296
*/
 
297
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99