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>
15 #include <LibreOfficeKit/LibreOfficeKitGtk.h>
16 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
18 #include "gtv-application-window.hxx"
19 #include "gtv-lok-dialog.hxx"
21 #include <com/sun/star/awt/Key.hpp>
23 #include <o3tl/unit_conversion.hxx>
24 #include <vcl/event.hxx>
28 struct GtvLokDialogPrivate
30 LOKDocView
* lokdocview
;
31 GtkWidget
* pDialogDrawingArea
;
32 GtkWidget
* pFloatingWin
;
35 guint32 m_nLastButtonPressTime
;
36 guint32 m_nLastButtonReleaseTime
;
37 guint32 m_nKeyModifier
;
38 guint32 m_nLastButtonPressed
;
42 // state for child floating windows
44 guint32 m_nChildWidth
;
45 guint32 m_nChildHeight
;
46 guint32 m_nChildLastButtonPressTime
;
47 guint32 m_nChildLastButtonReleaseTime
;
48 guint32 m_nChildKeyModifier
;
49 guint32 m_nChildLastButtonPressed
;
57 #if __has_warning("-Wdeprecated-volatile")
58 #pragma clang diagnostic push
59 #pragma clang diagnostic ignored "-Wdeprecated-volatile"
62 G_DEFINE_TYPE_WITH_PRIVATE(GtvLokDialog
, gtv_lok_dialog
, GTK_TYPE_DIALOG
);
64 #if __has_warning("-Wdeprecated-volatile")
65 #pragma clang diagnostic pop
72 PROP_LOKDOCVIEW_CONTEXT
,
79 static GParamSpec
* properties
[PROP_LAST
];
81 static GtvLokDialogPrivate
*
82 getPrivate(GtvLokDialog
* dialog
)
84 return static_cast<GtvLokDialogPrivate
*>(gtv_lok_dialog_get_instance_private(dialog
));
88 gtv_lok_dialog_draw(GtkWidget
* pDialogDrawingArea
, cairo_t
* pCairo
, gpointer
)
90 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea
));
91 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
94 gdk_cairo_get_clip_rectangle(pCairo
, &aRect
);
95 g_info("Painting dialog region: %d, %d, %d, %d", aRect
.x
, aRect
.y
, aRect
.width
, aRect
.height
);
97 int nWidth
= priv
->m_nWidth
;
98 int nHeight
= priv
->m_nHeight
;
99 if (aRect
.width
!= 0 && aRect
.height
!= 0)
101 nWidth
= aRect
.width
;
102 nHeight
= aRect
.height
;
105 cairo_surface_t
* pSurface
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32
, nWidth
, nHeight
);
106 unsigned char* pBuffer
= cairo_image_surface_get_data(pSurface
);
107 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(priv
->lokdocview
));
108 pDocument
->pClass
->paintWindow(pDocument
, priv
->dialogid
, pBuffer
, aRect
.x
, aRect
.y
, nWidth
, nHeight
);
110 gtk_widget_set_size_request(GTK_WIDGET(pDialogDrawingArea
), priv
->m_nWidth
, priv
->m_nHeight
);
112 cairo_surface_flush(pSurface
);
113 cairo_surface_mark_dirty(pSurface
);
115 cairo_set_source_surface(pCairo
, pSurface
, aRect
.x
, aRect
.y
);
116 // paint the dialog image
119 // debug red-colored border around the painted region
120 cairo_set_source_rgb(pCairo
, 1.0, 0, 0);
121 cairo_rectangle(pCairo
, aRect
.x
, aRect
.y
, nWidth
, nHeight
);
122 cairo_stroke(pCairo
);
126 gtv_lok_dialog_signal_button(GtkWidget
* pDialogDrawingArea
, GdkEventButton
* pEvent
)
128 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea
));
129 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
131 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
132 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
134 std::string aEventType
= "unknown";
135 if (pEvent
->type
== GDK_BUTTON_PRESS
)
136 aEventType
= "BUTTON_PRESS";
137 else if (pEvent
->type
== GDK_BUTTON_RELEASE
)
138 aEventType
= "BUTTON_RELEASE";
140 g_info("lok_dialog_signal_button (type: %s): %d, %d",
142 static_cast<int>(pEvent
->x
), static_cast<int>(pEvent
->y
));
143 gtk_widget_grab_focus(pDialogDrawingArea
);
145 switch (pEvent
->type
)
147 case GDK_BUTTON_PRESS
:
150 if ((pEvent
->time
- priv
->m_nLastButtonPressTime
) < 250)
152 priv
->m_nLastButtonPressTime
= pEvent
->time
;
153 int nEventButton
= 0;
154 switch (pEvent
->button
)
157 nEventButton
= MOUSE_LEFT
;
160 nEventButton
= MOUSE_MIDDLE
;
163 nEventButton
= MOUSE_RIGHT
;
166 priv
->m_nLastButtonPressed
= nEventButton
;
167 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
169 LOK_MOUSEEVENT_MOUSEBUTTONDOWN
,
174 priv
->m_nKeyModifier
);
178 case GDK_BUTTON_RELEASE
:
181 if ((pEvent
->time
- priv
->m_nLastButtonReleaseTime
) < 250)
183 priv
->m_nLastButtonReleaseTime
= pEvent
->time
;
184 int nEventButton
= 0;
185 switch (pEvent
->button
)
188 nEventButton
= MOUSE_LEFT
;
191 nEventButton
= MOUSE_MIDDLE
;
194 nEventButton
= MOUSE_RIGHT
;
197 priv
->m_nLastButtonPressed
= nEventButton
;
198 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
200 LOK_MOUSEEVENT_MOUSEBUTTONUP
,
205 priv
->m_nKeyModifier
);
215 gtv_lok_dialog_signal_motion(GtkWidget
* pDialogDrawingArea
, GdkEventButton
* pEvent
)
217 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea
));
218 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
220 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
221 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
223 g_info("lok_dialog_signal_motion: %d, %d (in twips: %d, %d)",
224 static_cast<int>(pEvent
->x
), static_cast<int>(pEvent
->y
),
225 static_cast<int>(o3tl::toTwips(pEvent
->x
, o3tl::Length::px
)),
226 static_cast<int>(o3tl::toTwips(pEvent
->y
, o3tl::Length::px
)));
228 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
230 LOK_MOUSEEVENT_MOUSEMOVE
,
234 priv
->m_nLastButtonPressed
,
235 priv
->m_nKeyModifier
);
241 gtv_lok_dialog_signal_key(GtkWidget
* pDialogDrawingArea
, GdkEventKey
* pEvent
)
243 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea
));
244 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
245 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
246 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
248 g_info("lok_dialog_signal_key");
251 priv
->m_nKeyModifier
&= KEY_MOD2
;
252 switch (pEvent
->keyval
)
254 case GDK_KEY_BackSpace
:
255 nKeyCode
= com::sun::star::awt::Key::BACKSPACE
;
258 nKeyCode
= com::sun::star::awt::Key::DELETE
;
261 case GDK_KEY_KP_Enter
:
262 nKeyCode
= com::sun::star::awt::Key::RETURN
;
265 nKeyCode
= com::sun::star::awt::Key::ESCAPE
;
268 nKeyCode
= com::sun::star::awt::Key::TAB
;
271 nKeyCode
= com::sun::star::awt::Key::DOWN
;
274 nKeyCode
= com::sun::star::awt::Key::UP
;
277 nKeyCode
= com::sun::star::awt::Key::LEFT
;
280 nKeyCode
= com::sun::star::awt::Key::RIGHT
;
282 case GDK_KEY_Page_Down
:
283 nKeyCode
= com::sun::star::awt::Key::PAGEDOWN
;
285 case GDK_KEY_Page_Up
:
286 nKeyCode
= com::sun::star::awt::Key::PAGEUP
;
289 nKeyCode
= com::sun::star::awt::Key::INSERT
;
291 case GDK_KEY_Shift_L
:
292 case GDK_KEY_Shift_R
:
293 if (pEvent
->type
== GDK_KEY_PRESS
)
294 priv
->m_nKeyModifier
|= KEY_SHIFT
;
296 case GDK_KEY_Control_L
:
297 case GDK_KEY_Control_R
:
298 if (pEvent
->type
== GDK_KEY_PRESS
)
299 priv
->m_nKeyModifier
|= KEY_MOD1
;
303 if (pEvent
->type
== GDK_KEY_PRESS
)
304 priv
->m_nKeyModifier
|= KEY_MOD2
;
306 priv
->m_nKeyModifier
&= ~KEY_MOD2
;
309 if (pEvent
->keyval
>= GDK_KEY_F1
&& pEvent
->keyval
<= GDK_KEY_F26
)
310 nKeyCode
= com::sun::star::awt::Key::F1
+ (pEvent
->keyval
- GDK_KEY_F1
);
312 nCharCode
= gdk_keyval_to_unicode(pEvent
->keyval
);
315 // rsc is not public API, but should be good enough for debugging purposes.
316 // If this is needed for real, then probably a new param of type
317 // css::awt::KeyModifier is needed in postKeyEvent().
318 if (pEvent
->state
& GDK_SHIFT_MASK
)
319 nKeyCode
|= KEY_SHIFT
;
321 if (pEvent
->state
& GDK_CONTROL_MASK
)
322 nKeyCode
|= KEY_MOD1
;
324 if (priv
->m_nKeyModifier
& KEY_MOD2
)
325 nKeyCode
|= KEY_MOD2
;
327 if (nKeyCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
)) {
328 if (pEvent
->keyval
>= GDK_KEY_a
&& pEvent
->keyval
<= GDK_KEY_z
)
330 nKeyCode
|= 512 + (pEvent
->keyval
- GDK_KEY_a
);
332 else if (pEvent
->keyval
>= GDK_KEY_A
&& pEvent
->keyval
<= GDK_KEY_Z
) {
333 nKeyCode
|= 512 + (pEvent
->keyval
- GDK_KEY_A
);
335 else if (pEvent
->keyval
>= GDK_KEY_0
&& pEvent
->keyval
<= GDK_KEY_9
) {
336 nKeyCode
|= 256 + (pEvent
->keyval
- GDK_KEY_0
);
340 std::stringstream ss
;
341 ss
<< "gtv_lok_dialog::postKey(" << pEvent
->type
<< ", " << nCharCode
<< ", " << nKeyCode
<< ")";
342 g_info("%s", ss
.str().c_str());
344 pDocument
->pClass
->postWindowKeyEvent(pDocument
,
346 pEvent
->type
== GDK_KEY_RELEASE
? LOK_KEYEVENT_KEYUP
: LOK_KEYEVENT_KEYINPUT
,
354 gtv_lok_dialog_init(GtvLokDialog
* dialog
)
356 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
358 GtkWidget
* pContentArea
= gtk_dialog_get_content_area(GTK_DIALOG(dialog
));
359 priv
->pDialogDrawingArea
= gtk_drawing_area_new();
360 priv
->pFloatingWin
= nullptr;
361 priv
->m_nChildId
= 0;
362 priv
->m_nChildWidth
= 0;
363 priv
->m_nChildHeight
= 0;
365 priv
->m_nLastButtonPressTime
= 0;
366 priv
->m_nLastButtonReleaseTime
= 0;
367 priv
->m_nKeyModifier
= 0;
368 priv
->m_nLastButtonPressed
= 0;
370 gtk_widget_add_events(priv
->pDialogDrawingArea
,
371 GDK_BUTTON_PRESS_MASK
372 |GDK_BUTTON_RELEASE_MASK
373 |GDK_BUTTON_MOTION_MASK
375 |GDK_KEY_RELEASE_MASK
);
376 // This is required to be able to capture key events on the drawing area
377 gtk_widget_set_can_focus(priv
->pDialogDrawingArea
, true);
379 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "draw", G_CALLBACK(gtv_lok_dialog_draw
), nullptr);
380 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "button-press-event", G_CALLBACK(gtv_lok_dialog_signal_button
), nullptr);
381 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "button-release-event", G_CALLBACK(gtv_lok_dialog_signal_button
), nullptr);
382 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "motion-notify-event", G_CALLBACK(gtv_lok_dialog_signal_motion
), nullptr);
383 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "key-press-event", G_CALLBACK(gtv_lok_dialog_signal_key
), nullptr);
384 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "key-release-event", G_CALLBACK(gtv_lok_dialog_signal_key
), nullptr);
385 gtk_container_add(GTK_CONTAINER(pContentArea
), priv
->pDialogDrawingArea
);
389 gtv_lok_dialog_set_property(GObject
* object
, guint propId
, const GValue
* value
, GParamSpec
* pspec
)
391 GtvLokDialog
* self
= GTV_LOK_DIALOG(object
);
392 GtvLokDialogPrivate
* priv
= getPrivate(self
);
396 case PROP_LOKDOCVIEW_CONTEXT
:
397 priv
->lokdocview
= LOK_DOC_VIEW(g_value_get_object(value
));
400 priv
->dialogid
= g_value_get_uint(value
);
402 case PROP_DIALOG_WIDTH
:
403 priv
->m_nWidth
= g_value_get_uint(value
);
405 case PROP_DIALOG_HEIGHT
:
406 priv
->m_nHeight
= g_value_get_uint(value
);
409 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, propId
, pspec
);
412 //if (propId == PROP_DIALOG_WIDTH || propId == PROP_DIALOG_HEIGHT)
413 // gtk_widget_set_size_request(GTK_WIDGET(priv->pDialogDrawingArea), priv->m_nWidth, priv->m_nHeight);
417 gtv_lok_dialog_get_property(GObject
* object
, guint propId
, GValue
* value
, GParamSpec
* pspec
)
419 GtvLokDialog
* self
= GTV_LOK_DIALOG(object
);
420 GtvLokDialogPrivate
* priv
= getPrivate(self
);
424 case PROP_LOKDOCVIEW_CONTEXT
:
425 g_value_set_object(value
, priv
->lokdocview
);
428 g_value_set_uint(value
, priv
->dialogid
);
430 case PROP_DIALOG_WIDTH
:
431 g_value_set_uint(value
, priv
->m_nWidth
);
433 case PROP_DIALOG_HEIGHT
:
434 g_value_set_uint(value
, priv
->m_nHeight
);
437 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, propId
, pspec
);
442 gtv_lok_dialog_class_init(GtvLokDialogClass
* klass
)
444 G_OBJECT_CLASS(klass
)->get_property
= gtv_lok_dialog_get_property
;
445 G_OBJECT_CLASS(klass
)->set_property
= gtv_lok_dialog_set_property
;
447 properties
[PROP_LOKDOCVIEW_CONTEXT
] = g_param_spec_object("lokdocview",
448 "LOKDocView Context",
449 "The LOKDocView context object to be used for dialog rendering",
451 static_cast<GParamFlags
>(G_PARAM_READWRITE
|
452 G_PARAM_CONSTRUCT_ONLY
|
453 G_PARAM_STATIC_STRINGS
));
455 properties
[PROP_DIALOG_ID
] = g_param_spec_uint("dialogid",
457 "Unique dialog identifier",
459 static_cast<GParamFlags
>(G_PARAM_READWRITE
|
460 G_PARAM_CONSTRUCT_ONLY
|
461 G_PARAM_STATIC_STRINGS
));
463 properties
[PROP_DIALOG_WIDTH
] = g_param_spec_uint("width",
467 static_cast<GParamFlags
>(G_PARAM_READWRITE
|
468 G_PARAM_STATIC_STRINGS
));
470 properties
[PROP_DIALOG_HEIGHT
] = g_param_spec_uint("height",
474 static_cast<GParamFlags
>(G_PARAM_READWRITE
|
475 G_PARAM_STATIC_STRINGS
));
477 g_object_class_install_properties (G_OBJECT_CLASS(klass
), PROP_LAST
, properties
);
481 gtv_lok_dialog_floating_win_draw(GtkWidget
* pDrawingArea
, cairo_t
* pCairo
, gpointer userdata
)
483 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(userdata
);
484 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
486 g_info("gtv_lok_dialog_floating_win_draw triggered");
487 cairo_surface_t
* pSurface
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32
, priv
->m_nChildWidth
, priv
->m_nChildHeight
);
488 unsigned char* pBuffer
= cairo_image_surface_get_data(pSurface
);
489 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(priv
->lokdocview
));
490 pDocument
->pClass
->paintWindow(pDocument
, priv
->m_nChildId
, pBuffer
, 0, 0, priv
->m_nChildWidth
, priv
->m_nChildHeight
);
492 gtk_widget_set_size_request(GTK_WIDGET(pDrawingArea
), priv
->m_nChildWidth
, priv
->m_nChildHeight
);
493 //gtk_widget_set_size_request(GTK_WIDGET(pDialog), nWidth, nHeight);
494 //gtk_window_resize(GTK_WINDOW(pDialog), nWidth, nHeight);
496 cairo_surface_flush(pSurface
);
497 cairo_surface_mark_dirty(pSurface
);
499 cairo_set_source_surface(pCairo
, pSurface
, 0, 0);
504 gtv_lok_dialog_floating_win_signal_button(GtkWidget
* /*pDialogChildDrawingArea*/, GdkEventButton
* pEvent
, gpointer userdata
)
506 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(userdata
);
507 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
509 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
510 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
512 std::string aEventType
= "unknown";
513 if (pEvent
->type
== GDK_BUTTON_PRESS
)
514 aEventType
= "BUTTON_PRESS";
515 else if (pEvent
->type
== GDK_BUTTON_RELEASE
)
516 aEventType
= "BUTTON_RELEASE";
518 g_info("lok_dialog_floating_win_signal_button (type: %s): %d, %d (in twips: %d, %d)",
520 static_cast<int>(pEvent
->x
), static_cast<int>(pEvent
->y
),
521 static_cast<int>(o3tl::toTwips(pEvent
->x
, o3tl::Length::px
)),
522 static_cast<int>(o3tl::toTwips(pEvent
->y
, o3tl::Length::px
)));
524 switch (pEvent
->type
)
526 case GDK_BUTTON_PRESS
:
529 if ((pEvent
->time
- priv
->m_nChildLastButtonPressTime
) < 250)
531 priv
->m_nChildLastButtonPressTime
= pEvent
->time
;
532 int nEventButton
= 0;
533 switch (pEvent
->button
)
536 nEventButton
= MOUSE_LEFT
;
539 nEventButton
= MOUSE_MIDDLE
;
542 nEventButton
= MOUSE_RIGHT
;
545 priv
->m_nChildLastButtonPressed
= nEventButton
;
546 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
548 LOK_MOUSEEVENT_MOUSEBUTTONDOWN
,
553 priv
->m_nChildKeyModifier
);
557 case GDK_BUTTON_RELEASE
:
560 if ((pEvent
->time
- priv
->m_nChildLastButtonReleaseTime
) < 250)
562 priv
->m_nChildLastButtonReleaseTime
= pEvent
->time
;
563 int nEventButton
= 0;
564 switch (pEvent
->button
)
567 nEventButton
= MOUSE_LEFT
;
570 nEventButton
= MOUSE_MIDDLE
;
573 nEventButton
= MOUSE_RIGHT
;
576 priv
->m_nChildLastButtonPressed
= nEventButton
;
577 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
579 LOK_MOUSEEVENT_MOUSEBUTTONUP
,
584 priv
->m_nChildKeyModifier
);
594 gtv_lok_dialog_floating_win_signal_motion(GtkWidget
* /*pDialogDrawingArea*/, GdkEventButton
* pEvent
, gpointer userdata
)
596 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(userdata
);
597 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
599 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
600 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
602 g_info("lok_dialog_floating_win_signal_motion: %d, %d (in twips: %d, %d)",
603 static_cast<int>(pEvent
->x
), static_cast<int>(pEvent
->y
),
604 static_cast<int>(o3tl::toTwips(pEvent
->x
, o3tl::Length::px
)),
605 static_cast<int>(o3tl::toTwips(pEvent
->y
, o3tl::Length::px
)));
607 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
609 LOK_MOUSEEVENT_MOUSEMOVE
,
613 priv
->m_nChildLastButtonPressed
,
614 priv
->m_nChildKeyModifier
);
619 // Public methods below
621 void gtv_lok_dialog_invalidate(GtvLokDialog
* dialog
, const GdkRectangle
& aRectangle
)
623 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
624 if (aRectangle
.width
!= 0 && aRectangle
.height
!= 0)
625 gtk_widget_queue_draw_area(priv
->pDialogDrawingArea
, aRectangle
.x
, aRectangle
.y
, aRectangle
.width
, aRectangle
.height
);
627 gtk_widget_queue_draw(priv
->pDialogDrawingArea
);
630 // checks if we are the parent of given childId
631 gboolean
gtv_lok_dialog_is_parent_of(GtvLokDialog
* dialog
, guint childId
)
633 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
635 return priv
->m_nChildId
== childId
;
638 void gtv_lok_dialog_child_create(GtvLokDialog
* dialog
, guint childId
, guint nX
, guint nY
, guint width
, guint height
)
640 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
642 g_debug("Dialog [ %d ] child window [ %d] being created, with dimensions [%dx%d]@(%d,%d)", priv
->dialogid
, childId
, width
, height
, nX
, nY
);
643 priv
->pFloatingWin
= gtk_window_new(GTK_WINDOW_POPUP
);
644 priv
->m_nChildId
= childId
;
645 priv
->m_nChildWidth
= width
;
646 priv
->m_nChildHeight
= height
;
647 GtkWidget
* pDrawingArea
= gtk_drawing_area_new();
648 gtk_container_add(GTK_CONTAINER(priv
->pFloatingWin
), pDrawingArea
);
650 gtk_window_set_transient_for(GTK_WINDOW(priv
->pFloatingWin
), GTK_WINDOW(dialog
));
651 gtk_window_set_destroy_with_parent(GTK_WINDOW(priv
->pFloatingWin
), true);
653 gtk_widget_add_events(pDrawingArea
,
654 GDK_BUTTON_PRESS_MASK
655 |GDK_POINTER_MOTION_MASK
656 |GDK_BUTTON_RELEASE_MASK
657 |GDK_BUTTON_MOTION_MASK
);
659 g_signal_connect(G_OBJECT(pDrawingArea
), "draw", G_CALLBACK(gtv_lok_dialog_floating_win_draw
), dialog
);
660 g_signal_connect(G_OBJECT(pDrawingArea
), "button-press-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button
), dialog
);
661 g_signal_connect(G_OBJECT(pDrawingArea
), "button-release-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button
), dialog
);
662 g_signal_connect(G_OBJECT(pDrawingArea
), "motion-notify-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_motion
), dialog
);
664 gtk_widget_set_size_request(priv
->pFloatingWin
, 1, 1);
665 gtk_window_set_type_hint(GTK_WINDOW(priv
->pFloatingWin
), GDK_WINDOW_TYPE_HINT_POPUP_MENU
);
666 gtk_window_set_screen(GTK_WINDOW(priv
->pFloatingWin
), gtk_window_get_screen(GTK_WINDOW(dialog
)));
668 gtk_widget_show_all(priv
->pFloatingWin
);
669 gtk_window_present(GTK_WINDOW(priv
->pFloatingWin
));
670 gtk_widget_grab_focus(pDrawingArea
);
672 // Get the root coords of our new floating window
673 GdkWindow
* pGdkWin
= gtk_widget_get_window(GTK_WIDGET(dialog
));
676 gdk_window_get_root_coords(pGdkWin
, nX
, nY
, &nrX
, &nrY
);
677 gtk_window_move(GTK_WINDOW(priv
->pFloatingWin
), nrX
, nrY
);
680 void gtv_lok_dialog_child_invalidate(GtvLokDialog
* dialog
)
682 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
683 g_debug("Dialog [ %d ] child invalidate request", priv
->dialogid
);
684 gtk_widget_queue_draw(priv
->pFloatingWin
);
687 void gtv_lok_dialog_child_close(GtvLokDialog
* dialog
)
689 g_info("Dialog's floating window close");
691 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
692 if (priv
->pFloatingWin
)
694 gtk_widget_destroy(priv
->pFloatingWin
);
695 priv
->pFloatingWin
= nullptr;
696 priv
->m_nChildId
= 0;
697 priv
->m_nChildWidth
= 0;
698 priv
->m_nChildHeight
= 0;
702 GtkWidget
* gtv_lok_dialog_new(LOKDocView
* pDocView
, guint dialogId
, guint width
, guint height
)
704 g_debug("Dialog [ %d ] of size: %d x %d created", dialogId
, width
, height
);
705 GtkWindow
* pWindow
= GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView
)));
706 return GTK_WIDGET(g_object_new(GTV_TYPE_LOK_DIALOG
,
707 "lokdocview", pDocView
,
708 "dialogid", dialogId
,
711 "title", "LOK Dialog",
713 "transient-for", pWindow
,
717 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */