~centralelyon2010/inkscape/imagelinks2

« back to all changes in this revision

Viewing changes to src/ui/widget/dock-item.cpp

  • Committer: gustav_b
  • Date: 2007-08-29 21:27:07 UTC
  • Revision ID: gustav_b@users.sourceforge.net-20070829212707-xvg87a2oqejqioxv
Dockable dialogs patch applied 
(https://sourceforge.net/tracker/?func=detail&atid=604308&aid=1688508&group_id=93438)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * \brief A custom Inkscape wrapper around gdl_dock_item
 
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 "dock-item.h"
 
13
#include "desktop.h"
 
14
#include "inkscape.h"
 
15
#include "ui/widget/dock.h"
 
16
#include "widgets/icon.h"
 
17
 
 
18
#include <gtk/gtk.h>
 
19
 
 
20
#include <gtkmm/invisible.h>
 
21
#include <gtkmm/stock.h>
 
22
 
 
23
namespace Inkscape {
 
24
namespace UI {
 
25
namespace Widget {
 
26
 
 
27
DockItem::DockItem(Dock& dock, const Glib::ustring& name, const Glib::ustring& long_name,
 
28
                   const Glib::ustring& icon_name, State state) :
 
29
    _dock (dock),
 
30
    _prev_state (state),
 
31
    _window (NULL),
 
32
    _dock_item_action_area (NULL)
 
33
{
 
34
    /* Add a "signal_response" signal to the GdlDockItem, make sure it is
 
35
     * only done once for the class.
 
36
     */
 
37
    static guint response_signal = 0;
 
38
 
 
39
    if (response_signal == 0) {
 
40
        response_signal = g_signal_new ("signal_response",
 
41
                                        GDL_TYPE_DOCK_ITEM,
 
42
                                        G_SIGNAL_RUN_FIRST,
 
43
                                        0,
 
44
                                        NULL, NULL,
 
45
                                        g_cclosure_marshal_VOID__INT,
 
46
                                        G_TYPE_NONE, 1, G_TYPE_INT);
 
47
    }
 
48
 
 
49
 
 
50
    if (!icon_name.empty()) {
 
51
        Gtk::Widget *icon = sp_icon_get_icon(icon_name, Inkscape::ICON_SIZE_MENU);
 
52
        if (icon) {
 
53
            // check icon type (inkscape, gtk, none) 
 
54
            if ( SP_IS_ICON(icon->gobj()) ) { 
 
55
                SPIcon* sp_icon = SP_ICON(icon->gobj());
 
56
                sp_icon_fetch_pixbuf(sp_icon);
 
57
                _icon_pixbuf = Glib::wrap(sp_icon->pb, true);
 
58
            } else if ( GTK_IS_IMAGE(icon->gobj()) ) {
 
59
                _icon_pixbuf = Gtk::Invisible().render_icon(Gtk::StockID(icon_name),
 
60
                                                            Gtk::ICON_SIZE_MENU);
 
61
            }
 
62
            delete icon;
 
63
 
 
64
            _gdl_dock_item = 
 
65
                gdl_dock_item_new_with_pixbuf_icon(name.c_str(), long_name.c_str(), _icon_pixbuf->gobj(),
 
66
                                                   GDL_DOCK_ITEM_BEH_NORMAL);
 
67
        }
 
68
    } else {
 
69
        _gdl_dock_item = 
 
70
            gdl_dock_item_new(name.c_str(), long_name.c_str(), GDL_DOCK_ITEM_BEH_NORMAL);
 
71
    }
 
72
 
 
73
    _frame.set_shadow_type(Gtk::SHADOW_IN);
 
74
    gtk_container_add (GTK_CONTAINER (_gdl_dock_item), GTK_WIDGET (_frame.gobj()));
 
75
    _frame.add(_dock_item_box);
 
76
    _dock_item_box.set_border_width(3);
 
77
 
 
78
    signal_drag_begin().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onDragBegin));
 
79
    signal_drag_end().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onDragEnd));
 
80
    signal_hide().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onHide), false);
 
81
    signal_show().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onShow), false);
 
82
    signal_state_changed().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onStateChanged));
 
83
    signal_delete_event().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onDeleteEvent));
 
84
 
 
85
    _dock.addItem(*this, (_prev_state == FLOATING_STATE ? FLOATING : TOP));
 
86
 
 
87
    show_all();
 
88
}
 
89
 
 
90
DockItem::~DockItem()
 
91
{
 
92
    g_free(_gdl_dock_item);
 
93
}
 
94
 
 
95
Gtk::Widget&
 
96
DockItem::getWidget()
 
97
{
 
98
    return *Glib::wrap(GTK_WIDGET(_gdl_dock_item));
 
99
}
 
100
 
 
101
GtkWidget *
 
102
DockItem::gobj()
 
103
{
 
104
    return _gdl_dock_item;
 
105
}
 
106
 
 
107
Gtk::VBox *
 
108
DockItem::get_vbox()
 
109
{
 
110
    return &_dock_item_box;
 
111
}
 
112
 
 
113
 
 
114
bool
 
115
DockItem::isAttached() const
 
116
{
 
117
    return GDL_DOCK_OBJECT_ATTACHED (_gdl_dock_item);
 
118
}
 
119
 
 
120
 
 
121
bool
 
122
DockItem::isFloating() const
 
123
{
 
124
    gboolean floating = FALSE;
 
125
    if (GDL_IS_DOCK (gdl_dock_object_get_parent_object (GDL_DOCK_OBJECT (_gdl_dock_item)))) {
 
126
        GdlDock* dock = GDL_DOCK (gdl_dock_object_get_parent_object (GDL_DOCK_OBJECT (_gdl_dock_item)));
 
127
        g_object_get (dock,
 
128
                      "floating", &floating,
 
129
                      NULL);
 
130
    }
 
131
    return floating;
 
132
}
 
133
 
 
134
bool
 
135
DockItem::isIconified() const
 
136
{
 
137
    return GDL_DOCK_ITEM_ICONIFIED (_gdl_dock_item);
 
138
}
 
139
 
 
140
DockItem::State
 
141
DockItem::getState() const
 
142
{
 
143
    return (isAttached() ? (isFloating() ? FLOATING_STATE : DOCKED_STATE) : UNATTACHED);
 
144
}
 
145
 
 
146
DockItem::State
 
147
DockItem::getPrevState() const
 
148
{
 
149
    return _prev_state;
 
150
}
 
151
 
 
152
DockItem::Placement
 
153
DockItem::getPlacement() const
 
154
{
 
155
    GdlDockPlacement placement = (GdlDockPlacement)NONE;
 
156
    gdl_dock_object_child_placement(gdl_dock_object_get_parent_object (GDL_DOCK_OBJECT(_gdl_dock_item)),
 
157
                                    GDL_DOCK_OBJECT(_gdl_dock_item),
 
158
                                    &placement);
 
159
    return (Placement)placement;
 
160
}
 
161
 
 
162
 
 
163
void
 
164
DockItem::addButton(Gtk::Button* button, int response_id)
 
165
{
 
166
    // Create a button box for the response buttons if it's the first button to be added
 
167
    if (!_dock_item_action_area) {
 
168
        _dock_item_action_area = new Gtk::HButtonBox(Gtk::BUTTONBOX_END, 6);
 
169
        _dock_item_box.pack_end(*_dock_item_action_area, Gtk::PACK_SHRINK, 0);
 
170
        _dock_item_action_area->set_border_width(6);
 
171
    }
 
172
 
 
173
    _dock_item_action_area->pack_start(*button);
 
174
}
 
175
 
 
176
void
 
177
DockItem::hide()
 
178
{
 
179
    gdl_dock_item_hide_item (GDL_DOCK_ITEM(_gdl_dock_item));
 
180
}
 
181
 
 
182
void
 
183
DockItem::show()
 
184
{
 
185
    gdl_dock_item_show_item (GDL_DOCK_ITEM(_gdl_dock_item));
 
186
}
 
187
 
 
188
void
 
189
DockItem::show_all()
 
190
{
 
191
    gtk_widget_show_all(_gdl_dock_item);
 
192
}
 
193
 
 
194
void
 
195
DockItem::present()
 
196
{
 
197
    // iconified
 
198
    if (isIconified()) {
 
199
        show();
 
200
        return;
 
201
    }
 
202
    
 
203
    // unattached
 
204
    if (!isAttached()) {
 
205
        gdl_dock_item_show_item (GDL_DOCK_ITEM(_gdl_dock_item));
 
206
        return;
 
207
    }
 
208
 
 
209
    // tabbed
 
210
    if (getPlacement() == CENTER) {
 
211
        int i = gtk_notebook_page_num (GTK_NOTEBOOK (_gdl_dock_item->parent),
 
212
                                       GTK_WIDGET (_gdl_dock_item));
 
213
        if (i >= 0)
 
214
            gtk_notebook_set_current_page (GTK_NOTEBOOK (_gdl_dock_item->parent), i);
 
215
        return;
 
216
    }
 
217
 
 
218
    // we're already present, do nothing
 
219
}
 
220
 
 
221
 
 
222
void 
 
223
DockItem::get_position(int& x, int& y)
 
224
 
225
    if (_getWindow()) {
 
226
        _getWindow()->get_position(x, y);
 
227
    } else {
 
228
        x = _x;
 
229
        y = _y;
 
230
    }
 
231
}
 
232
 
 
233
void 
 
234
DockItem::get_size(int& width, int& height)
 
235
 
236
    if (_window) {
 
237
        _window->get_size(width, height);
 
238
    } else {
 
239
        width = get_vbox()->get_width();
 
240
        height = get_vbox()->get_height();
 
241
    }
 
242
}
 
243
 
 
244
 
 
245
void
 
246
DockItem::resize(int width, int height) 
 
247
{
 
248
    if (_window)
 
249
        _window->resize(width, height);
 
250
}
 
251
 
 
252
 
 
253
void
 
254
DockItem::move(int x, int y)
 
255
{
 
256
    if (_window)
 
257
        _window->move(x, y);
 
258
}
 
259
 
 
260
void
 
261
DockItem::set_position(Gtk::WindowPosition position)
 
262
{
 
263
    if (_window)
 
264
        _window->set_position(position);
 
265
}
 
266
 
 
267
void
 
268
DockItem::set_size_request(int width, int height)
 
269
{
 
270
    getWidget().set_size_request(width, height);
 
271
}
 
272
 
 
273
void 
 
274
DockItem::size_request(Gtk::Requisition& requisition)
 
275
 
276
    getWidget().size_request(requisition);
 
277
}
 
278
 
 
279
 
 
280
void
 
281
DockItem::set_title(Glib::ustring title)
 
282
{
 
283
    g_object_set (_gdl_dock_item,
 
284
                  "long-name", title.c_str(),
 
285
                  NULL);
 
286
 
 
287
    gdl_dock_item_set_tablabel(GDL_DOCK_ITEM(_gdl_dock_item),
 
288
                               gtk_label_new (title.c_str()));
 
289
}
 
290
 
 
291
/* Signal wrappers */
 
292
 
 
293
Glib::SignalProxy0<void>
 
294
DockItem::signal_show()
 
295
 
296
    return Glib::SignalProxy0<void>(Glib::wrap(GTK_WIDGET(_gdl_dock_item)), 
 
297
                                    &_signal_show_proxy);
 
298
}
 
299
 
 
300
Glib::SignalProxy0<void>
 
301
DockItem::signal_hide()
 
302
 
303
    return Glib::SignalProxy0<void>(Glib::wrap(GTK_WIDGET(_gdl_dock_item)), 
 
304
                                    &_signal_hide_proxy);
 
305
}
 
306
 
 
307
Glib::SignalProxy1<bool, GdkEventAny *>
 
308
DockItem::signal_delete_event()
 
309
{
 
310
    return Glib::SignalProxy1<bool, GdkEventAny *>(Glib::wrap(GTK_WIDGET(_gdl_dock_item)),
 
311
                                                  &_signal_delete_event_proxy);
 
312
}
 
313
 
 
314
Glib::SignalProxy1<void, int>
 
315
DockItem::signal_response()
 
316
{
 
317
    return Glib::SignalProxy1<void, int>(Glib::wrap(GTK_WIDGET(_gdl_dock_item)), 
 
318
                                         &_signal_response_proxy);
 
319
}
 
320
 
 
321
Glib::SignalProxy0<void>
 
322
DockItem::signal_drag_begin()
 
323
{
 
324
    return Glib::SignalProxy0<void>(Glib::wrap(GTK_WIDGET(_gdl_dock_item)),
 
325
                                    &_signal_drag_begin_proxy);
 
326
}
 
327
 
 
328
Glib::SignalProxy1<void, bool>
 
329
DockItem::signal_drag_end()
 
330
{
 
331
    return Glib::SignalProxy1<void, bool>(Glib::wrap(GTK_WIDGET(_gdl_dock_item)),
 
332
                                          &_signal_drag_end_proxy);
 
333
}
 
334
 
 
335
sigc::signal<void, DockItem::State, DockItem::State>
 
336
DockItem::signal_state_changed()
 
337
{
 
338
    return _signal_state_changed;
 
339
}
 
340
 
 
341
void
 
342
DockItem::_onHideWindow()
 
343
{
 
344
    if (_window)
 
345
        _window->get_position(_x, _y);
 
346
}
 
347
 
 
348
void
 
349
DockItem::_onHide()
 
350
{
 
351
    _signal_state_changed.emit(UNATTACHED, getState());
 
352
}
 
353
 
 
354
void
 
355
DockItem::_onShow()
 
356
{
 
357
    _signal_state_changed.emit(UNATTACHED, getState());
 
358
}
 
359
 
 
360
void
 
361
DockItem::_onDragBegin()
 
362
{
 
363
    _prev_state = getState();
 
364
    if (_prev_state == FLOATING_STATE)
 
365
        _dock.toggleDockable(getWidget().get_width(), getWidget().get_height());
 
366
}
 
367
 
 
368
void
 
369
DockItem::_onDragEnd(bool)
 
370
{
 
371
    State state = getState();
 
372
 
 
373
    if (state != _prev_state)
 
374
        _signal_state_changed.emit(_prev_state, state);
 
375
 
 
376
    if (state == FLOATING_STATE) {
 
377
        if (_prev_state == FLOATING_STATE)
 
378
            _dock.toggleDockable();
 
379
    }
 
380
 
 
381
    _prev_state = state;
 
382
}
 
383
 
 
384
bool
 
385
DockItem::_onKeyPress(GdkEventKey *event)
 
386
{
 
387
    gboolean return_value;
 
388
    g_signal_emit_by_name (_gdl_dock_item, "key_press_event", event, &return_value);
 
389
    return return_value;
 
390
}
 
391
 
 
392
void
 
393
DockItem::_onStateChanged(State prev_state, State new_state)
 
394
{
 
395
    _window = _getWindow();
 
396
 
 
397
    if (new_state == FLOATING_STATE) {
 
398
        _window->signal_hide().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onHideWindow));
 
399
        _signal_key_press_event_connection = 
 
400
            _window->signal_key_press_event().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onKeyPress));
 
401
    }
 
402
}
 
403
 
 
404
 
 
405
bool
 
406
DockItem::_onDeleteEvent(GdkEventAny *event)
 
407
{
 
408
    hide();
 
409
    return false;
 
410
}
 
411
 
 
412
 
 
413
Gtk::Window *
 
414
DockItem::_getWindow()
 
415
{
 
416
    g_return_val_if_fail(_gdl_dock_item, 0);
 
417
    Gtk::Container *parent = getWidget().get_parent();
 
418
    parent = (parent ? parent->get_parent() : 0);
 
419
    return (parent ? dynamic_cast<Gtk::Window *>(parent) : 0);
 
420
}
 
421
 
 
422
const Glib::SignalProxyInfo
 
423
DockItem::_signal_show_proxy = 
 
424
{
 
425
    "show",
 
426
    (GCallback) &Glib::SignalProxyNormal::slot0_void_callback,
 
427
    (GCallback) &Glib::SignalProxyNormal::slot0_void_callback
 
428
};
 
429
 
 
430
const Glib::SignalProxyInfo
 
431
DockItem::_signal_hide_proxy = 
 
432
{
 
433
    "hide",
 
434
    (GCallback) &Glib::SignalProxyNormal::slot0_void_callback,
 
435
    (GCallback) &Glib::SignalProxyNormal::slot0_void_callback
 
436
};
 
437
 
 
438
 
 
439
const Glib::SignalProxyInfo
 
440
DockItem::_signal_delete_event_proxy = 
 
441
{
 
442
    "delete_event",
 
443
    (GCallback) &_signal_delete_event_callback,
 
444
    (GCallback) &_signal_delete_event_callback
 
445
};
 
446
 
 
447
 
 
448
const Glib::SignalProxyInfo
 
449
DockItem::_signal_response_proxy = 
 
450
{
 
451
    "signal_response",
 
452
    (GCallback) &_signal_response_callback,
 
453
    (GCallback) &_signal_response_callback
 
454
};
 
455
 
 
456
const Glib::SignalProxyInfo
 
457
DockItem::_signal_drag_begin_proxy = 
 
458
{
 
459
    "dock-drag-begin",
 
460
    (GCallback) &Glib::SignalProxyNormal::slot0_void_callback,
 
461
    (GCallback) &Glib::SignalProxyNormal::slot0_void_callback
 
462
};
 
463
 
 
464
 
 
465
const Glib::SignalProxyInfo
 
466
DockItem::_signal_drag_end_proxy = 
 
467
{
 
468
    "dock_drag_end",
 
469
    (GCallback) &_signal_drag_end_callback,
 
470
    (GCallback) &_signal_drag_end_callback
 
471
};
 
472
 
 
473
 
 
474
gboolean
 
475
DockItem::_signal_delete_event_callback(GtkWidget *self, GdkEventAny *event, void *data)
 
476
{
 
477
    using namespace Gtk;
 
478
    typedef sigc::slot<bool, GdkEventAny *> SlotType;
 
479
 
 
480
    if (Glib::ObjectBase::_get_current_wrapper((GObject *) self)) {
 
481
        try {
 
482
            if(sigc::slot_base *const slot = Glib::SignalProxyNormal::data_to_slot(data))
 
483
                return static_cast<int>( (*static_cast<SlotType*>(slot))(event) );
 
484
        } catch(...) {
 
485
            Glib::exception_handlers_invoke();
 
486
        }
 
487
    }
 
488
 
 
489
    typedef gboolean RType;
 
490
    return RType();
 
491
}
 
492
 
 
493
void 
 
494
DockItem::_signal_response_callback(GtkWidget *self, gint response_id, void *data)
 
495
{
 
496
    using namespace Gtk;
 
497
    typedef sigc::slot<void, int> SlotType;
 
498
 
 
499
    if (Glib::ObjectBase::_get_current_wrapper((GObject *) self)) {
 
500
        try {
 
501
            if(sigc::slot_base *const slot = Glib::SignalProxyNormal::data_to_slot(data))
 
502
                (*static_cast<SlotType *>(slot))(response_id);
 
503
        } catch(...) {
 
504
            Glib::exception_handlers_invoke();
 
505
        }
 
506
    }
 
507
}
 
508
 
 
509
void 
 
510
DockItem::_signal_drag_end_callback(GtkWidget *self, gboolean cancelled, void *data)
 
511
{
 
512
    using namespace Gtk;
 
513
    typedef sigc::slot<void, bool> SlotType;
 
514
 
 
515
    if (Glib::ObjectBase::_get_current_wrapper((GObject *) self)) {
 
516
        try {
 
517
            if(sigc::slot_base *const slot = Glib::SignalProxyNormal::data_to_slot(data))
 
518
                (*static_cast<SlotType *>(slot))(cancelled);
 
519
        } catch(...) {
 
520
            Glib::exception_handlers_invoke();
 
521
        }
 
522
    }
 
523
}
 
524
 
 
525
 
 
526
} // namespace Widget
 
527
} // namespace UI
 
528
} // namespace Inkscape
 
529
 
 
530
/*
 
531
  Local Variables:
 
532
  mode:c++
 
533
  c-file-style:"stroustrup"
 
534
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
 
535
  indent-tabs-mode:nil
 
536
  fill-column:99
 
537
  End:
 
538
*/
 
539
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :