1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 #include <gdk/gdkkeysyms.h>
16 #include <LibreOfficeKit/LibreOfficeKitGtk.h>
17 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
19 #include "gtv-application-window.hxx"
20 #include "gtv-lok-dialog.hxx"
22 #include <com/sun/star/awt/Key.hpp>
24 #include <o3tl/unit_conversion.hxx>
25 #include <vcl/event.hxx>
29 struct GtvLokDialogPrivate
31 LOKDocView
* lokdocview
;
32 GtkWidget
* pDialogDrawingArea
;
33 GtkWidget
* pFloatingWin
;
36 guint32 m_nLastButtonPressTime
;
37 guint32 m_nLastButtonReleaseTime
;
38 guint32 m_nKeyModifier
;
39 guint32 m_nLastButtonPressed
;
43 // state for child floating windows
45 guint32 m_nChildWidth
;
46 guint32 m_nChildHeight
;
47 guint32 m_nChildLastButtonPressTime
;
48 guint32 m_nChildLastButtonReleaseTime
;
49 guint32 m_nChildKeyModifier
;
50 guint32 m_nChildLastButtonPressed
;
58 #if __has_warning("-Wdeprecated-volatile")
59 #pragma clang diagnostic push
60 #pragma clang diagnostic ignored "-Wdeprecated-volatile"
63 G_DEFINE_TYPE_WITH_PRIVATE(GtvLokDialog
, gtv_lok_dialog
, GTK_TYPE_DIALOG
);
65 #if __has_warning("-Wdeprecated-volatile")
66 #pragma clang diagnostic pop
73 PROP_LOKDOCVIEW_CONTEXT
,
80 static GParamSpec
* properties
[PROP_LAST
];
82 static GtvLokDialogPrivate
*
83 getPrivate(GtvLokDialog
* dialog
)
85 return static_cast<GtvLokDialogPrivate
*>(gtv_lok_dialog_get_instance_private(dialog
));
89 gtv_lok_dialog_draw(GtkWidget
* pDialogDrawingArea
, cairo_t
* pCairo
, gpointer
)
91 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea
));
92 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
95 gdk_cairo_get_clip_rectangle(pCairo
, &aRect
);
96 g_info("Painting dialog region: %d, %d, %d, %d", aRect
.x
, aRect
.y
, aRect
.width
, aRect
.height
);
98 int nWidth
= priv
->m_nWidth
;
99 int nHeight
= priv
->m_nHeight
;
100 if (aRect
.width
!= 0 && aRect
.height
!= 0)
102 nWidth
= aRect
.width
;
103 nHeight
= aRect
.height
;
106 cairo_surface_t
* pSurface
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32
, nWidth
, nHeight
);
107 unsigned char* pBuffer
= cairo_image_surface_get_data(pSurface
);
108 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(priv
->lokdocview
));
109 pDocument
->pClass
->paintWindow(pDocument
, priv
->dialogid
, pBuffer
, aRect
.x
, aRect
.y
, nWidth
, nHeight
);
111 gtk_widget_set_size_request(GTK_WIDGET(pDialogDrawingArea
), priv
->m_nWidth
, priv
->m_nHeight
);
113 cairo_surface_flush(pSurface
);
114 cairo_surface_mark_dirty(pSurface
);
116 cairo_set_source_surface(pCairo
, pSurface
, aRect
.x
, aRect
.y
);
117 // paint the dialog image
120 // debug red-colored border around the painted region
121 cairo_set_source_rgb(pCairo
, 1.0, 0, 0);
122 cairo_rectangle(pCairo
, aRect
.x
, aRect
.y
, nWidth
, nHeight
);
123 cairo_stroke(pCairo
);
127 gtv_lok_dialog_signal_button(GtkWidget
* pDialogDrawingArea
, GdkEventButton
* pEvent
)
129 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea
));
130 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
132 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
133 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
135 std::string aEventType
= "unknown";
136 if (pEvent
->type
== GDK_BUTTON_PRESS
)
137 aEventType
= "BUTTON_PRESS";
138 else if (pEvent
->type
== GDK_BUTTON_RELEASE
)
139 aEventType
= "BUTTON_RELEASE";
141 g_info("lok_dialog_signal_button (type: %s): %d, %d",
143 static_cast<int>(pEvent
->x
), static_cast<int>(pEvent
->y
));
144 gtk_widget_grab_focus(pDialogDrawingArea
);
146 switch (pEvent
->type
)
148 case GDK_BUTTON_PRESS
:
151 if ((pEvent
->time
- priv
->m_nLastButtonPressTime
) < 250)
153 priv
->m_nLastButtonPressTime
= pEvent
->time
;
154 int nEventButton
= 0;
155 switch (pEvent
->button
)
158 nEventButton
= MOUSE_LEFT
;
161 nEventButton
= MOUSE_MIDDLE
;
164 nEventButton
= MOUSE_RIGHT
;
167 priv
->m_nLastButtonPressed
= nEventButton
;
168 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
170 LOK_MOUSEEVENT_MOUSEBUTTONDOWN
,
175 priv
->m_nKeyModifier
);
179 case GDK_BUTTON_RELEASE
:
182 if ((pEvent
->time
- priv
->m_nLastButtonReleaseTime
) < 250)
184 priv
->m_nLastButtonReleaseTime
= pEvent
->time
;
185 int nEventButton
= 0;
186 switch (pEvent
->button
)
189 nEventButton
= MOUSE_LEFT
;
192 nEventButton
= MOUSE_MIDDLE
;
195 nEventButton
= MOUSE_RIGHT
;
198 priv
->m_nLastButtonPressed
= nEventButton
;
199 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
201 LOK_MOUSEEVENT_MOUSEBUTTONUP
,
206 priv
->m_nKeyModifier
);
216 gtv_lok_dialog_signal_motion(GtkWidget
* pDialogDrawingArea
, GdkEventButton
* pEvent
)
218 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea
));
219 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
221 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
222 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
224 g_info("lok_dialog_signal_motion: %d, %d (in twips: %d, %d)",
225 static_cast<int>(pEvent
->x
), static_cast<int>(pEvent
->y
),
226 static_cast<int>(o3tl::toTwips(pEvent
->x
, o3tl::Length::px
)),
227 static_cast<int>(o3tl::toTwips(pEvent
->y
, o3tl::Length::px
)));
229 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
231 LOK_MOUSEEVENT_MOUSEMOVE
,
235 priv
->m_nLastButtonPressed
,
236 priv
->m_nKeyModifier
);
242 gtv_lok_dialog_signal_key(GtkWidget
* pDialogDrawingArea
, GdkEventKey
* pEvent
)
244 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea
));
245 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
246 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
247 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
249 g_info("lok_dialog_signal_key");
252 priv
->m_nKeyModifier
&= KEY_MOD2
;
253 switch (pEvent
->keyval
)
255 case GDK_KEY_BackSpace
:
256 nKeyCode
= com::sun::star::awt::Key::BACKSPACE
;
259 nKeyCode
= com::sun::star::awt::Key::DELETE
;
262 case GDK_KEY_KP_Enter
:
263 nKeyCode
= com::sun::star::awt::Key::RETURN
;
266 nKeyCode
= com::sun::star::awt::Key::ESCAPE
;
269 nKeyCode
= com::sun::star::awt::Key::TAB
;
272 nKeyCode
= com::sun::star::awt::Key::DOWN
;
275 nKeyCode
= com::sun::star::awt::Key::UP
;
278 nKeyCode
= com::sun::star::awt::Key::LEFT
;
281 nKeyCode
= com::sun::star::awt::Key::RIGHT
;
283 case GDK_KEY_Page_Down
:
284 nKeyCode
= com::sun::star::awt::Key::PAGEDOWN
;
286 case GDK_KEY_Page_Up
:
287 nKeyCode
= com::sun::star::awt::Key::PAGEUP
;
290 nKeyCode
= com::sun::star::awt::Key::INSERT
;
292 case GDK_KEY_Shift_L
:
293 case GDK_KEY_Shift_R
:
294 if (pEvent
->type
== GDK_KEY_PRESS
)
295 priv
->m_nKeyModifier
|= KEY_SHIFT
;
297 case GDK_KEY_Control_L
:
298 case GDK_KEY_Control_R
:
299 if (pEvent
->type
== GDK_KEY_PRESS
)
300 priv
->m_nKeyModifier
|= KEY_MOD1
;
304 if (pEvent
->type
== GDK_KEY_PRESS
)
305 priv
->m_nKeyModifier
|= KEY_MOD2
;
307 priv
->m_nKeyModifier
&= ~KEY_MOD2
;
310 if (pEvent
->keyval
>= GDK_KEY_F1
&& pEvent
->keyval
<= GDK_KEY_F26
)
311 nKeyCode
= com::sun::star::awt::Key::F1
+ (pEvent
->keyval
- GDK_KEY_F1
);
313 nCharCode
= gdk_keyval_to_unicode(pEvent
->keyval
);
316 // rsc is not public API, but should be good enough for debugging purposes.
317 // If this is needed for real, then probably a new param of type
318 // css::awt::KeyModifier is needed in postKeyEvent().
319 if (pEvent
->state
& GDK_SHIFT_MASK
)
320 nKeyCode
|= KEY_SHIFT
;
322 if (pEvent
->state
& GDK_CONTROL_MASK
)
323 nKeyCode
|= KEY_MOD1
;
325 if (priv
->m_nKeyModifier
& KEY_MOD2
)
326 nKeyCode
|= KEY_MOD2
;
328 if (nKeyCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
)) {
329 if (pEvent
->keyval
>= GDK_KEY_a
&& pEvent
->keyval
<= GDK_KEY_z
)
331 nKeyCode
|= 512 + (pEvent
->keyval
- GDK_KEY_a
);
333 else if (pEvent
->keyval
>= GDK_KEY_A
&& pEvent
->keyval
<= GDK_KEY_Z
) {
334 nKeyCode
|= 512 + (pEvent
->keyval
- GDK_KEY_A
);
336 else if (pEvent
->keyval
>= GDK_KEY_0
&& pEvent
->keyval
<= GDK_KEY_9
) {
337 nKeyCode
|= 256 + (pEvent
->keyval
- GDK_KEY_0
);
341 std::stringstream ss
;
342 ss
<< "gtv_lok_dialog::postKey(" << pEvent
->type
<< ", " << nCharCode
<< ", " << nKeyCode
<< ")";
343 g_info("%s", ss
.str().c_str());
345 pDocument
->pClass
->postWindowKeyEvent(pDocument
,
347 pEvent
->type
== GDK_KEY_RELEASE
? LOK_KEYEVENT_KEYUP
: LOK_KEYEVENT_KEYINPUT
,
355 gtv_lok_dialog_init(GtvLokDialog
* dialog
)
357 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
359 GtkWidget
* pContentArea
= gtk_dialog_get_content_area(GTK_DIALOG(dialog
));
360 priv
->pDialogDrawingArea
= gtk_drawing_area_new();
361 priv
->pFloatingWin
= nullptr;
362 priv
->m_nChildId
= 0;
363 priv
->m_nChildWidth
= 0;
364 priv
->m_nChildHeight
= 0;
366 priv
->m_nLastButtonPressTime
= 0;
367 priv
->m_nLastButtonReleaseTime
= 0;
368 priv
->m_nKeyModifier
= 0;
369 priv
->m_nLastButtonPressed
= 0;
371 gtk_widget_add_events(priv
->pDialogDrawingArea
,
372 GDK_BUTTON_PRESS_MASK
373 |GDK_BUTTON_RELEASE_MASK
374 |GDK_BUTTON_MOTION_MASK
376 |GDK_KEY_RELEASE_MASK
);
377 // This is required to be able to capture key events on the drawing area
378 gtk_widget_set_can_focus(priv
->pDialogDrawingArea
, true);
380 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "draw", G_CALLBACK(gtv_lok_dialog_draw
), nullptr);
381 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "button-press-event", G_CALLBACK(gtv_lok_dialog_signal_button
), nullptr);
382 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "button-release-event", G_CALLBACK(gtv_lok_dialog_signal_button
), nullptr);
383 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "motion-notify-event", G_CALLBACK(gtv_lok_dialog_signal_motion
), nullptr);
384 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "key-press-event", G_CALLBACK(gtv_lok_dialog_signal_key
), nullptr);
385 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "key-release-event", G_CALLBACK(gtv_lok_dialog_signal_key
), nullptr);
386 gtk_container_add(GTK_CONTAINER(pContentArea
), priv
->pDialogDrawingArea
);
390 gtv_lok_dialog_set_property(GObject
* object
, guint propId
, const GValue
* value
, GParamSpec
* pspec
)
392 GtvLokDialog
* self
= GTV_LOK_DIALOG(object
);
393 GtvLokDialogPrivate
* priv
= getPrivate(self
);
397 case PROP_LOKDOCVIEW_CONTEXT
:
398 priv
->lokdocview
= LOK_DOC_VIEW(g_value_get_object(value
));
401 priv
->dialogid
= g_value_get_uint(value
);
403 case PROP_DIALOG_WIDTH
:
404 priv
->m_nWidth
= g_value_get_uint(value
);
406 case PROP_DIALOG_HEIGHT
:
407 priv
->m_nHeight
= g_value_get_uint(value
);
410 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, propId
, pspec
);
413 //if (propId == PROP_DIALOG_WIDTH || propId == PROP_DIALOG_HEIGHT)
414 // gtk_widget_set_size_request(GTK_WIDGET(priv->pDialogDrawingArea), priv->m_nWidth, priv->m_nHeight);
418 gtv_lok_dialog_get_property(GObject
* object
, guint propId
, GValue
* value
, GParamSpec
* pspec
)
420 GtvLokDialog
* self
= GTV_LOK_DIALOG(object
);
421 GtvLokDialogPrivate
* priv
= getPrivate(self
);
425 case PROP_LOKDOCVIEW_CONTEXT
:
426 g_value_set_object(value
, priv
->lokdocview
);
429 g_value_set_uint(value
, priv
->dialogid
);
431 case PROP_DIALOG_WIDTH
:
432 g_value_set_uint(value
, priv
->m_nWidth
);
434 case PROP_DIALOG_HEIGHT
:
435 g_value_set_uint(value
, priv
->m_nHeight
);
438 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, propId
, pspec
);
443 gtv_lok_dialog_class_init(GtvLokDialogClass
* klass
)
445 G_OBJECT_CLASS(klass
)->get_property
= gtv_lok_dialog_get_property
;
446 G_OBJECT_CLASS(klass
)->set_property
= gtv_lok_dialog_set_property
;
448 properties
[PROP_LOKDOCVIEW_CONTEXT
] = g_param_spec_object("lokdocview",
449 "LOKDocView Context",
450 "The LOKDocView context object to be used for dialog rendering",
452 static_cast<GParamFlags
>(G_PARAM_READWRITE
|
453 G_PARAM_CONSTRUCT_ONLY
|
454 G_PARAM_STATIC_STRINGS
));
456 properties
[PROP_DIALOG_ID
] = g_param_spec_uint("dialogid",
458 "Unique dialog identifier",
460 static_cast<GParamFlags
>(G_PARAM_READWRITE
|
461 G_PARAM_CONSTRUCT_ONLY
|
462 G_PARAM_STATIC_STRINGS
));
464 properties
[PROP_DIALOG_WIDTH
] = g_param_spec_uint("width",
468 static_cast<GParamFlags
>(G_PARAM_READWRITE
|
469 G_PARAM_STATIC_STRINGS
));
471 properties
[PROP_DIALOG_HEIGHT
] = g_param_spec_uint("height",
475 static_cast<GParamFlags
>(G_PARAM_READWRITE
|
476 G_PARAM_STATIC_STRINGS
));
478 g_object_class_install_properties (G_OBJECT_CLASS(klass
), PROP_LAST
, properties
);
482 gtv_lok_dialog_floating_win_draw(GtkWidget
* pDrawingArea
, cairo_t
* pCairo
, gpointer userdata
)
484 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(userdata
);
485 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
487 g_info("gtv_lok_dialog_floating_win_draw triggered");
488 cairo_surface_t
* pSurface
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32
, priv
->m_nChildWidth
, priv
->m_nChildHeight
);
489 unsigned char* pBuffer
= cairo_image_surface_get_data(pSurface
);
490 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(priv
->lokdocview
));
491 pDocument
->pClass
->paintWindow(pDocument
, priv
->m_nChildId
, pBuffer
, 0, 0, priv
->m_nChildWidth
, priv
->m_nChildHeight
);
493 gtk_widget_set_size_request(GTK_WIDGET(pDrawingArea
), priv
->m_nChildWidth
, priv
->m_nChildHeight
);
494 //gtk_widget_set_size_request(GTK_WIDGET(pDialog), nWidth, nHeight);
495 //gtk_window_resize(GTK_WINDOW(pDialog), nWidth, nHeight);
497 cairo_surface_flush(pSurface
);
498 cairo_surface_mark_dirty(pSurface
);
500 cairo_set_source_surface(pCairo
, pSurface
, 0, 0);
505 gtv_lok_dialog_floating_win_signal_button(GtkWidget
* /*pDialogChildDrawingArea*/, GdkEventButton
* pEvent
, gpointer userdata
)
507 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(userdata
);
508 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
510 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
511 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
513 std::string aEventType
= "unknown";
514 if (pEvent
->type
== GDK_BUTTON_PRESS
)
515 aEventType
= "BUTTON_PRESS";
516 else if (pEvent
->type
== GDK_BUTTON_RELEASE
)
517 aEventType
= "BUTTON_RELEASE";
519 g_info("lok_dialog_floating_win_signal_button (type: %s): %d, %d (in twips: %d, %d)",
521 static_cast<int>(pEvent
->x
), static_cast<int>(pEvent
->y
),
522 static_cast<int>(o3tl::toTwips(pEvent
->x
, o3tl::Length::px
)),
523 static_cast<int>(o3tl::toTwips(pEvent
->y
, o3tl::Length::px
)));
525 switch (pEvent
->type
)
527 case GDK_BUTTON_PRESS
:
530 if ((pEvent
->time
- priv
->m_nChildLastButtonPressTime
) < 250)
532 priv
->m_nChildLastButtonPressTime
= pEvent
->time
;
533 int nEventButton
= 0;
534 switch (pEvent
->button
)
537 nEventButton
= MOUSE_LEFT
;
540 nEventButton
= MOUSE_MIDDLE
;
543 nEventButton
= MOUSE_RIGHT
;
546 priv
->m_nChildLastButtonPressed
= nEventButton
;
547 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
549 LOK_MOUSEEVENT_MOUSEBUTTONDOWN
,
554 priv
->m_nChildKeyModifier
);
558 case GDK_BUTTON_RELEASE
:
561 if ((pEvent
->time
- priv
->m_nChildLastButtonReleaseTime
) < 250)
563 priv
->m_nChildLastButtonReleaseTime
= pEvent
->time
;
564 int nEventButton
= 0;
565 switch (pEvent
->button
)
568 nEventButton
= MOUSE_LEFT
;
571 nEventButton
= MOUSE_MIDDLE
;
574 nEventButton
= MOUSE_RIGHT
;
577 priv
->m_nChildLastButtonPressed
= nEventButton
;
578 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
580 LOK_MOUSEEVENT_MOUSEBUTTONUP
,
585 priv
->m_nChildKeyModifier
);
595 gtv_lok_dialog_floating_win_signal_motion(GtkWidget
* /*pDialogDrawingArea*/, GdkEventButton
* pEvent
, gpointer userdata
)
597 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(userdata
);
598 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
600 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
601 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
603 g_info("lok_dialog_floating_win_signal_motion: %d, %d (in twips: %d, %d)",
604 static_cast<int>(pEvent
->x
), static_cast<int>(pEvent
->y
),
605 static_cast<int>(o3tl::toTwips(pEvent
->x
, o3tl::Length::px
)),
606 static_cast<int>(o3tl::toTwips(pEvent
->y
, o3tl::Length::px
)));
608 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
610 LOK_MOUSEEVENT_MOUSEMOVE
,
614 priv
->m_nChildLastButtonPressed
,
615 priv
->m_nChildKeyModifier
);
620 // Public methods below
622 void gtv_lok_dialog_invalidate(GtvLokDialog
* dialog
, const GdkRectangle
& aRectangle
)
624 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
625 if (aRectangle
.width
!= 0 && aRectangle
.height
!= 0)
626 gtk_widget_queue_draw_area(priv
->pDialogDrawingArea
, aRectangle
.x
, aRectangle
.y
, aRectangle
.width
, aRectangle
.height
);
628 gtk_widget_queue_draw(priv
->pDialogDrawingArea
);
631 // checks if we are the parent of given childId
632 gboolean
gtv_lok_dialog_is_parent_of(GtvLokDialog
* dialog
, guint childId
)
634 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
636 return priv
->m_nChildId
== childId
;
639 void gtv_lok_dialog_child_create(GtvLokDialog
* dialog
, guint childId
, guint nX
, guint nY
, guint width
, guint height
)
641 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
643 g_debug("Dialog [ %d ] child window [ %d] being created, with dimensions [%dx%d]@(%d,%d)", priv
->dialogid
, childId
, width
, height
, nX
, nY
);
644 priv
->pFloatingWin
= gtk_window_new(GTK_WINDOW_POPUP
);
645 priv
->m_nChildId
= childId
;
646 priv
->m_nChildWidth
= width
;
647 priv
->m_nChildHeight
= height
;
648 GtkWidget
* pDrawingArea
= gtk_drawing_area_new();
649 gtk_container_add(GTK_CONTAINER(priv
->pFloatingWin
), pDrawingArea
);
651 gtk_window_set_transient_for(GTK_WINDOW(priv
->pFloatingWin
), GTK_WINDOW(dialog
));
652 gtk_window_set_destroy_with_parent(GTK_WINDOW(priv
->pFloatingWin
), true);
654 gtk_widget_add_events(pDrawingArea
,
655 GDK_BUTTON_PRESS_MASK
656 |GDK_POINTER_MOTION_MASK
657 |GDK_BUTTON_RELEASE_MASK
658 |GDK_BUTTON_MOTION_MASK
);
660 g_signal_connect(G_OBJECT(pDrawingArea
), "draw", G_CALLBACK(gtv_lok_dialog_floating_win_draw
), dialog
);
661 g_signal_connect(G_OBJECT(pDrawingArea
), "button-press-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button
), dialog
);
662 g_signal_connect(G_OBJECT(pDrawingArea
), "button-release-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button
), dialog
);
663 g_signal_connect(G_OBJECT(pDrawingArea
), "motion-notify-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_motion
), dialog
);
665 gtk_widget_set_size_request(priv
->pFloatingWin
, 1, 1);
666 gtk_window_set_type_hint(GTK_WINDOW(priv
->pFloatingWin
), GDK_WINDOW_TYPE_HINT_POPUP_MENU
);
667 gtk_window_set_screen(GTK_WINDOW(priv
->pFloatingWin
), gtk_window_get_screen(GTK_WINDOW(dialog
)));
669 gtk_widget_show_all(priv
->pFloatingWin
);
670 gtk_window_present(GTK_WINDOW(priv
->pFloatingWin
));
671 gtk_widget_grab_focus(pDrawingArea
);
673 // Get the root coords of our new floating window
674 GdkWindow
* pGdkWin
= gtk_widget_get_window(GTK_WIDGET(dialog
));
677 gdk_window_get_root_coords(pGdkWin
, nX
, nY
, &nrX
, &nrY
);
678 gtk_window_move(GTK_WINDOW(priv
->pFloatingWin
), nrX
, nrY
);
681 void gtv_lok_dialog_child_invalidate(GtvLokDialog
* dialog
)
683 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
684 g_debug("Dialog [ %d ] child invalidate request", priv
->dialogid
);
685 gtk_widget_queue_draw(priv
->pFloatingWin
);
688 void gtv_lok_dialog_child_close(GtvLokDialog
* dialog
)
690 g_info("Dialog's floating window close");
692 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
693 if (priv
->pFloatingWin
)
695 gtk_widget_destroy(priv
->pFloatingWin
);
696 priv
->pFloatingWin
= nullptr;
697 priv
->m_nChildId
= 0;
698 priv
->m_nChildWidth
= 0;
699 priv
->m_nChildHeight
= 0;
703 GtkWidget
* gtv_lok_dialog_new(LOKDocView
* pDocView
, guint dialogId
, guint width
, guint height
)
705 g_debug("Dialog [ %d ] of size: %d x %d created", dialogId
, width
, height
);
706 GtkWindow
* pWindow
= GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView
)));
707 return GTK_WIDGET(g_object_new(GTV_TYPE_LOK_DIALOG
,
708 "lokdocview", pDocView
,
709 "dialogid", dialogId
,
712 "title", "LOK Dialog",
714 "transient-for", pWindow
,
718 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */