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>
22 #include <vcl/event.hxx>
26 struct GtvLokDialogPrivate
28 LOKDocView
* lokdocview
;
29 GtkWidget
* pDialogDrawingArea
;
30 GtkWidget
* pFloatingWin
;
33 guint32 m_nLastButtonPressTime
;
34 guint32 m_nLastButtonReleaseTime
;
35 guint32 m_nKeyModifier
;
36 guint32 m_nLastButtonPressed
;
40 // state for child floating windows
42 guint32 m_nChildWidth
;
43 guint32 m_nChildHeight
;
44 guint32 m_nChildLastButtonPressTime
;
45 guint32 m_nChildLastButtonReleaseTime
;
46 guint32 m_nChildKeyModifier
;
47 guint32 m_nChildLastButtonPressed
;
55 #if __has_warning("-Wdeprecated-volatile")
56 #pragma clang diagnostic push
57 #pragma clang diagnostic ignored "-Wdeprecated-volatile"
60 G_DEFINE_TYPE_WITH_PRIVATE(GtvLokDialog
, gtv_lok_dialog
, GTK_TYPE_DIALOG
);
62 #if __has_warning("-Wdeprecated-volatile")
63 #pragma clang diagnostic pop
70 PROP_LOKDOCVIEW_CONTEXT
,
77 static GParamSpec
* properties
[PROP_LAST
];
79 static GtvLokDialogPrivate
*
80 getPrivate(GtvLokDialog
* dialog
)
82 return static_cast<GtvLokDialogPrivate
*>(gtv_lok_dialog_get_instance_private(dialog
));
86 pixelToTwip(float fInput
)
88 return (fInput
/ 96 / 1.0 /* zoom */) * 1440.0f
;
93 twipToPixel(float fInput
)
95 return fInput
/ 1440.0f
* 96 * 1.0 /* zoom */;
100 gtv_lok_dialog_draw(GtkWidget
* pDialogDrawingArea
, cairo_t
* pCairo
, gpointer
)
102 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea
));
103 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
106 gdk_cairo_get_clip_rectangle(pCairo
, &aRect
);
107 g_info("Painting dialog region: %d, %d, %d, %d", aRect
.x
, aRect
.y
, aRect
.width
, aRect
.height
);
109 int nWidth
= priv
->m_nWidth
;
110 int nHeight
= priv
->m_nHeight
;
111 if (aRect
.width
!= 0 && aRect
.height
!= 0)
113 nWidth
= aRect
.width
;
114 nHeight
= aRect
.height
;
117 cairo_surface_t
* pSurface
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32
, nWidth
, nHeight
);
118 unsigned char* pBuffer
= cairo_image_surface_get_data(pSurface
);
119 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(priv
->lokdocview
));
120 pDocument
->pClass
->paintWindow(pDocument
, priv
->dialogid
, pBuffer
, aRect
.x
, aRect
.y
, nWidth
, nHeight
);
122 gtk_widget_set_size_request(GTK_WIDGET(pDialogDrawingArea
), priv
->m_nWidth
, priv
->m_nHeight
);
124 cairo_surface_flush(pSurface
);
125 cairo_surface_mark_dirty(pSurface
);
127 cairo_set_source_surface(pCairo
, pSurface
, aRect
.x
, aRect
.y
);
128 // paint the dialog image
131 // debug red-colored border around the painted region
132 cairo_set_source_rgb(pCairo
, 1.0, 0, 0);
133 cairo_rectangle(pCairo
, aRect
.x
, aRect
.y
, nWidth
, nHeight
);
134 cairo_stroke(pCairo
);
138 gtv_lok_dialog_signal_button(GtkWidget
* pDialogDrawingArea
, GdkEventButton
* pEvent
)
140 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea
));
141 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
143 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
144 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
146 std::string aEventType
= "unknown";
147 if (pEvent
->type
== GDK_BUTTON_PRESS
)
148 aEventType
= "BUTTON_PRESS";
149 else if (pEvent
->type
== GDK_BUTTON_RELEASE
)
150 aEventType
= "BUTTON_RELEASE";
152 g_info("lok_dialog_signal_button (type: %s): %d, %d",
154 static_cast<int>(pEvent
->x
), static_cast<int>(pEvent
->y
));
155 gtk_widget_grab_focus(pDialogDrawingArea
);
157 switch (pEvent
->type
)
159 case GDK_BUTTON_PRESS
:
162 if ((pEvent
->time
- priv
->m_nLastButtonPressTime
) < 250)
164 priv
->m_nLastButtonPressTime
= pEvent
->time
;
165 int nEventButton
= 0;
166 switch (pEvent
->button
)
169 nEventButton
= MOUSE_LEFT
;
172 nEventButton
= MOUSE_MIDDLE
;
175 nEventButton
= MOUSE_RIGHT
;
178 priv
->m_nLastButtonPressed
= nEventButton
;
179 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
181 LOK_MOUSEEVENT_MOUSEBUTTONDOWN
,
186 priv
->m_nKeyModifier
);
190 case GDK_BUTTON_RELEASE
:
193 if ((pEvent
->time
- priv
->m_nLastButtonReleaseTime
) < 250)
195 priv
->m_nLastButtonReleaseTime
= pEvent
->time
;
196 int nEventButton
= 0;
197 switch (pEvent
->button
)
200 nEventButton
= MOUSE_LEFT
;
203 nEventButton
= MOUSE_MIDDLE
;
206 nEventButton
= MOUSE_RIGHT
;
209 priv
->m_nLastButtonPressed
= nEventButton
;
210 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
212 LOK_MOUSEEVENT_MOUSEBUTTONUP
,
217 priv
->m_nKeyModifier
);
227 gtv_lok_dialog_signal_motion(GtkWidget
* pDialogDrawingArea
, GdkEventButton
* pEvent
)
229 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea
));
230 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
232 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
233 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
235 g_info("lok_dialog_signal_motion: %d, %d (in twips: %d, %d)",
236 static_cast<int>(pEvent
->x
), static_cast<int>(pEvent
->y
),
237 static_cast<int>(pixelToTwip(pEvent
->x
)),
238 static_cast<int>(pixelToTwip(pEvent
->y
)));
240 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
242 LOK_MOUSEEVENT_MOUSEMOVE
,
246 priv
->m_nLastButtonPressed
,
247 priv
->m_nKeyModifier
);
253 gtv_lok_dialog_signal_key(GtkWidget
* pDialogDrawingArea
, GdkEventKey
* pEvent
)
255 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea
));
256 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
257 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
258 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
260 g_info("lok_dialog_signal_key");
263 priv
->m_nKeyModifier
&= KEY_MOD2
;
264 switch (pEvent
->keyval
)
266 case GDK_KEY_BackSpace
:
267 nKeyCode
= com::sun::star::awt::Key::BACKSPACE
;
270 nKeyCode
= com::sun::star::awt::Key::DELETE
;
273 case GDK_KEY_KP_Enter
:
274 nKeyCode
= com::sun::star::awt::Key::RETURN
;
277 nKeyCode
= com::sun::star::awt::Key::ESCAPE
;
280 nKeyCode
= com::sun::star::awt::Key::TAB
;
283 nKeyCode
= com::sun::star::awt::Key::DOWN
;
286 nKeyCode
= com::sun::star::awt::Key::UP
;
289 nKeyCode
= com::sun::star::awt::Key::LEFT
;
292 nKeyCode
= com::sun::star::awt::Key::RIGHT
;
294 case GDK_KEY_Page_Down
:
295 nKeyCode
= com::sun::star::awt::Key::PAGEDOWN
;
297 case GDK_KEY_Page_Up
:
298 nKeyCode
= com::sun::star::awt::Key::PAGEUP
;
301 nKeyCode
= com::sun::star::awt::Key::INSERT
;
303 case GDK_KEY_Shift_L
:
304 case GDK_KEY_Shift_R
:
305 if (pEvent
->type
== GDK_KEY_PRESS
)
306 priv
->m_nKeyModifier
|= KEY_SHIFT
;
308 case GDK_KEY_Control_L
:
309 case GDK_KEY_Control_R
:
310 if (pEvent
->type
== GDK_KEY_PRESS
)
311 priv
->m_nKeyModifier
|= KEY_MOD1
;
315 if (pEvent
->type
== GDK_KEY_PRESS
)
316 priv
->m_nKeyModifier
|= KEY_MOD2
;
318 priv
->m_nKeyModifier
&= ~KEY_MOD2
;
321 if (pEvent
->keyval
>= GDK_KEY_F1
&& pEvent
->keyval
<= GDK_KEY_F26
)
322 nKeyCode
= com::sun::star::awt::Key::F1
+ (pEvent
->keyval
- GDK_KEY_F1
);
324 nCharCode
= gdk_keyval_to_unicode(pEvent
->keyval
);
327 // rsc is not public API, but should be good enough for debugging purposes.
328 // If this is needed for real, then probably a new param of type
329 // css::awt::KeyModifier is needed in postKeyEvent().
330 if (pEvent
->state
& GDK_SHIFT_MASK
)
331 nKeyCode
|= KEY_SHIFT
;
333 if (pEvent
->state
& GDK_CONTROL_MASK
)
334 nKeyCode
|= KEY_MOD1
;
336 if (priv
->m_nKeyModifier
& KEY_MOD2
)
337 nKeyCode
|= KEY_MOD2
;
339 if (nKeyCode
& (KEY_SHIFT
| KEY_MOD1
| KEY_MOD2
)) {
340 if (pEvent
->keyval
>= GDK_KEY_a
&& pEvent
->keyval
<= GDK_KEY_z
)
342 nKeyCode
|= 512 + (pEvent
->keyval
- GDK_KEY_a
);
344 else if (pEvent
->keyval
>= GDK_KEY_A
&& pEvent
->keyval
<= GDK_KEY_Z
) {
345 nKeyCode
|= 512 + (pEvent
->keyval
- GDK_KEY_A
);
347 else if (pEvent
->keyval
>= GDK_KEY_0
&& pEvent
->keyval
<= GDK_KEY_9
) {
348 nKeyCode
|= 256 + (pEvent
->keyval
- GDK_KEY_0
);
352 std::stringstream ss
;
353 ss
<< "gtv_lok_dialog::postKey(" << pEvent
->type
<< ", " << nCharCode
<< ", " << nKeyCode
<< ")";
354 g_info("%s", ss
.str().c_str());
356 pDocument
->pClass
->postWindowKeyEvent(pDocument
,
358 pEvent
->type
== GDK_KEY_RELEASE
? LOK_KEYEVENT_KEYUP
: LOK_KEYEVENT_KEYINPUT
,
366 gtv_lok_dialog_init(GtvLokDialog
* dialog
)
368 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
370 GtkWidget
* pContentArea
= gtk_dialog_get_content_area(GTK_DIALOG(dialog
));
371 priv
->pDialogDrawingArea
= gtk_drawing_area_new();
372 priv
->pFloatingWin
= nullptr;
373 priv
->m_nChildId
= 0;
374 priv
->m_nChildWidth
= 0;
375 priv
->m_nChildHeight
= 0;
377 priv
->m_nLastButtonPressTime
= 0;
378 priv
->m_nLastButtonReleaseTime
= 0;
379 priv
->m_nKeyModifier
= 0;
380 priv
->m_nLastButtonPressed
= 0;
382 gtk_widget_add_events(priv
->pDialogDrawingArea
,
383 GDK_BUTTON_PRESS_MASK
384 |GDK_BUTTON_RELEASE_MASK
385 |GDK_BUTTON_MOTION_MASK
387 |GDK_KEY_RELEASE_MASK
);
388 // This is required to be able to capture key events on the drawing area
389 gtk_widget_set_can_focus(priv
->pDialogDrawingArea
, true);
391 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "draw", G_CALLBACK(gtv_lok_dialog_draw
), nullptr);
392 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "button-press-event", G_CALLBACK(gtv_lok_dialog_signal_button
), nullptr);
393 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "button-release-event", G_CALLBACK(gtv_lok_dialog_signal_button
), nullptr);
394 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "motion-notify-event", G_CALLBACK(gtv_lok_dialog_signal_motion
), nullptr);
395 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "key-press-event", G_CALLBACK(gtv_lok_dialog_signal_key
), nullptr);
396 g_signal_connect(G_OBJECT(priv
->pDialogDrawingArea
), "key-release-event", G_CALLBACK(gtv_lok_dialog_signal_key
), nullptr);
397 gtk_container_add(GTK_CONTAINER(pContentArea
), priv
->pDialogDrawingArea
);
401 gtv_lok_dialog_set_property(GObject
* object
, guint propId
, const GValue
* value
, GParamSpec
* pspec
)
403 GtvLokDialog
* self
= GTV_LOK_DIALOG(object
);
404 GtvLokDialogPrivate
* priv
= getPrivate(self
);
408 case PROP_LOKDOCVIEW_CONTEXT
:
409 priv
->lokdocview
= LOK_DOC_VIEW(g_value_get_object(value
));
412 priv
->dialogid
= g_value_get_uint(value
);
414 case PROP_DIALOG_WIDTH
:
415 priv
->m_nWidth
= g_value_get_uint(value
);
417 case PROP_DIALOG_HEIGHT
:
418 priv
->m_nHeight
= g_value_get_uint(value
);
421 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, propId
, pspec
);
424 //if (propId == PROP_DIALOG_WIDTH || propId == PROP_DIALOG_HEIGHT)
425 // gtk_widget_set_size_request(GTK_WIDGET(priv->pDialogDrawingArea), priv->m_nWidth, priv->m_nHeight);
429 gtv_lok_dialog_get_property(GObject
* object
, guint propId
, GValue
* value
, GParamSpec
* pspec
)
431 GtvLokDialog
* self
= GTV_LOK_DIALOG(object
);
432 GtvLokDialogPrivate
* priv
= getPrivate(self
);
436 case PROP_LOKDOCVIEW_CONTEXT
:
437 g_value_set_object(value
, priv
->lokdocview
);
440 g_value_set_uint(value
, priv
->dialogid
);
442 case PROP_DIALOG_WIDTH
:
443 g_value_set_uint(value
, priv
->m_nWidth
);
445 case PROP_DIALOG_HEIGHT
:
446 g_value_set_uint(value
, priv
->m_nHeight
);
449 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, propId
, pspec
);
454 gtv_lok_dialog_class_init(GtvLokDialogClass
* klass
)
456 G_OBJECT_CLASS(klass
)->get_property
= gtv_lok_dialog_get_property
;
457 G_OBJECT_CLASS(klass
)->set_property
= gtv_lok_dialog_set_property
;
459 properties
[PROP_LOKDOCVIEW_CONTEXT
] = g_param_spec_object("lokdocview",
460 "LOKDocView Context",
461 "The LOKDocView context object to be used for dialog rendering",
463 static_cast<GParamFlags
>(G_PARAM_READWRITE
|
464 G_PARAM_CONSTRUCT_ONLY
|
465 G_PARAM_STATIC_STRINGS
));
467 properties
[PROP_DIALOG_ID
] = g_param_spec_uint("dialogid",
469 "Unique dialog identifier",
471 static_cast<GParamFlags
>(G_PARAM_READWRITE
|
472 G_PARAM_CONSTRUCT_ONLY
|
473 G_PARAM_STATIC_STRINGS
));
475 properties
[PROP_DIALOG_WIDTH
] = g_param_spec_uint("width",
479 static_cast<GParamFlags
>(G_PARAM_READWRITE
|
480 G_PARAM_STATIC_STRINGS
));
482 properties
[PROP_DIALOG_HEIGHT
] = g_param_spec_uint("height",
486 static_cast<GParamFlags
>(G_PARAM_READWRITE
|
487 G_PARAM_STATIC_STRINGS
));
489 g_object_class_install_properties (G_OBJECT_CLASS(klass
), PROP_LAST
, properties
);
493 gtv_lok_dialog_floating_win_draw(GtkWidget
* pDrawingArea
, cairo_t
* pCairo
, gpointer userdata
)
495 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(userdata
);
496 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
498 g_info("gtv_lok_dialog_floating_win_draw triggered");
499 cairo_surface_t
* pSurface
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32
, priv
->m_nChildWidth
, priv
->m_nChildHeight
);
500 unsigned char* pBuffer
= cairo_image_surface_get_data(pSurface
);
501 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(priv
->lokdocview
));
502 pDocument
->pClass
->paintWindow(pDocument
, priv
->m_nChildId
, pBuffer
, 0, 0, priv
->m_nChildWidth
, priv
->m_nChildHeight
);
504 gtk_widget_set_size_request(GTK_WIDGET(pDrawingArea
), priv
->m_nChildWidth
, priv
->m_nChildHeight
);
505 //gtk_widget_set_size_request(GTK_WIDGET(pDialog), nWidth, nHeight);
506 //gtk_window_resize(GTK_WINDOW(pDialog), nWidth, nHeight);
508 cairo_surface_flush(pSurface
);
509 cairo_surface_mark_dirty(pSurface
);
511 cairo_set_source_surface(pCairo
, pSurface
, 0, 0);
516 gtv_lok_dialog_floating_win_signal_button(GtkWidget
* /*pDialogChildDrawingArea*/, GdkEventButton
* pEvent
, gpointer userdata
)
518 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(userdata
);
519 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
521 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
522 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
524 std::string aEventType
= "unknown";
525 if (pEvent
->type
== GDK_BUTTON_PRESS
)
526 aEventType
= "BUTTON_PRESS";
527 else if (pEvent
->type
== GDK_BUTTON_RELEASE
)
528 aEventType
= "BUTTON_RELEASE";
530 g_info("lok_dialog_floating_win_signal_button (type: %s): %d, %d (in twips: %d, %d)",
532 static_cast<int>(pEvent
->x
), static_cast<int>(pEvent
->y
),
533 static_cast<int>(pixelToTwip(pEvent
->x
)),
534 static_cast<int>(pixelToTwip(pEvent
->y
)));
536 switch (pEvent
->type
)
538 case GDK_BUTTON_PRESS
:
541 if ((pEvent
->time
- priv
->m_nChildLastButtonPressTime
) < 250)
543 priv
->m_nChildLastButtonPressTime
= pEvent
->time
;
544 int nEventButton
= 0;
545 switch (pEvent
->button
)
548 nEventButton
= MOUSE_LEFT
;
551 nEventButton
= MOUSE_MIDDLE
;
554 nEventButton
= MOUSE_RIGHT
;
557 priv
->m_nChildLastButtonPressed
= nEventButton
;
558 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
560 LOK_MOUSEEVENT_MOUSEBUTTONDOWN
,
565 priv
->m_nChildKeyModifier
);
569 case GDK_BUTTON_RELEASE
:
572 if ((pEvent
->time
- priv
->m_nChildLastButtonReleaseTime
) < 250)
574 priv
->m_nChildLastButtonReleaseTime
= pEvent
->time
;
575 int nEventButton
= 0;
576 switch (pEvent
->button
)
579 nEventButton
= MOUSE_LEFT
;
582 nEventButton
= MOUSE_MIDDLE
;
585 nEventButton
= MOUSE_RIGHT
;
588 priv
->m_nChildLastButtonPressed
= nEventButton
;
589 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
591 LOK_MOUSEEVENT_MOUSEBUTTONUP
,
596 priv
->m_nChildKeyModifier
);
606 gtv_lok_dialog_floating_win_signal_motion(GtkWidget
* /*pDialogDrawingArea*/, GdkEventButton
* pEvent
, gpointer userdata
)
608 GtvLokDialog
* pDialog
= GTV_LOK_DIALOG(userdata
);
609 GtvLokDialogPrivate
* priv
= getPrivate(pDialog
);
611 GtvApplicationWindow
* window
= GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog
)));
612 LibreOfficeKitDocument
* pDocument
= lok_doc_view_get_document(LOK_DOC_VIEW(window
->lokdocview
));
614 g_info("lok_dialog_floating_win_signal_motion: %d, %d (in twips: %d, %d)",
615 static_cast<int>(pEvent
->x
), static_cast<int>(pEvent
->y
),
616 static_cast<int>(pixelToTwip(pEvent
->x
)),
617 static_cast<int>(pixelToTwip(pEvent
->y
)));
619 pDocument
->pClass
->postWindowMouseEvent(pDocument
,
621 LOK_MOUSEEVENT_MOUSEMOVE
,
625 priv
->m_nChildLastButtonPressed
,
626 priv
->m_nChildKeyModifier
);
631 // Public methods below
633 void gtv_lok_dialog_invalidate(GtvLokDialog
* dialog
, const GdkRectangle
& aRectangle
)
635 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
636 if (aRectangle
.width
!= 0 && aRectangle
.height
!= 0)
637 gtk_widget_queue_draw_area(priv
->pDialogDrawingArea
, aRectangle
.x
, aRectangle
.y
, aRectangle
.width
, aRectangle
.height
);
639 gtk_widget_queue_draw(priv
->pDialogDrawingArea
);
642 // checks if we are the parent of given childId
643 gboolean
gtv_lok_dialog_is_parent_of(GtvLokDialog
* dialog
, guint childId
)
645 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
647 return priv
->m_nChildId
== childId
;
650 void gtv_lok_dialog_child_create(GtvLokDialog
* dialog
, guint childId
, guint nX
, guint nY
, guint width
, guint height
)
652 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
654 g_debug("Dialog [ %d ] child window [ %d] being created, with dimensions [%dx%d]@(%d,%d)", priv
->dialogid
, childId
, width
, height
, nX
, nY
);
655 priv
->pFloatingWin
= gtk_window_new(GTK_WINDOW_POPUP
);
656 priv
->m_nChildId
= childId
;
657 priv
->m_nChildWidth
= width
;
658 priv
->m_nChildHeight
= height
;
659 GtkWidget
* pDrawingArea
= gtk_drawing_area_new();
660 gtk_container_add(GTK_CONTAINER(priv
->pFloatingWin
), pDrawingArea
);
662 gtk_window_set_transient_for(GTK_WINDOW(priv
->pFloatingWin
), GTK_WINDOW(dialog
));
663 gtk_window_set_destroy_with_parent(GTK_WINDOW(priv
->pFloatingWin
), true);
665 gtk_widget_add_events(pDrawingArea
,
666 GDK_BUTTON_PRESS_MASK
667 |GDK_POINTER_MOTION_MASK
668 |GDK_BUTTON_RELEASE_MASK
669 |GDK_BUTTON_MOTION_MASK
);
671 g_signal_connect(G_OBJECT(pDrawingArea
), "draw", G_CALLBACK(gtv_lok_dialog_floating_win_draw
), dialog
);
672 g_signal_connect(G_OBJECT(pDrawingArea
), "button-press-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button
), dialog
);
673 g_signal_connect(G_OBJECT(pDrawingArea
), "button-release-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button
), dialog
);
674 g_signal_connect(G_OBJECT(pDrawingArea
), "motion-notify-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_motion
), dialog
);
676 gtk_widget_set_size_request(priv
->pFloatingWin
, 1, 1);
677 gtk_window_set_type_hint(GTK_WINDOW(priv
->pFloatingWin
), GDK_WINDOW_TYPE_HINT_POPUP_MENU
);
678 gtk_window_set_screen(GTK_WINDOW(priv
->pFloatingWin
), gtk_window_get_screen(GTK_WINDOW(dialog
)));
680 gtk_widget_show_all(priv
->pFloatingWin
);
681 gtk_window_present(GTK_WINDOW(priv
->pFloatingWin
));
682 gtk_widget_grab_focus(pDrawingArea
);
684 // Get the root coords of our new floating window
685 GdkWindow
* pGdkWin
= gtk_widget_get_window(GTK_WIDGET(dialog
));
688 gdk_window_get_root_coords(pGdkWin
, nX
, nY
, &nrX
, &nrY
);
689 gtk_window_move(GTK_WINDOW(priv
->pFloatingWin
), nrX
, nrY
);
692 void gtv_lok_dialog_child_invalidate(GtvLokDialog
* dialog
)
694 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
695 g_debug("Dialog [ %d ] child invalidate request", priv
->dialogid
);
696 gtk_widget_queue_draw(priv
->pFloatingWin
);
699 void gtv_lok_dialog_child_close(GtvLokDialog
* dialog
)
701 g_info("Dialog's floating window close");
703 GtvLokDialogPrivate
* priv
= getPrivate(dialog
);
704 if (priv
->pFloatingWin
)
706 gtk_widget_destroy(priv
->pFloatingWin
);
707 priv
->pFloatingWin
= nullptr;
708 priv
->m_nChildId
= 0;
709 priv
->m_nChildWidth
= 0;
710 priv
->m_nChildHeight
= 0;
714 GtkWidget
* gtv_lok_dialog_new(LOKDocView
* pDocView
, guint dialogId
, guint width
, guint height
)
716 g_debug("Dialog [ %d ] of size: %d x %d created", dialogId
, width
, height
);
717 GtkWindow
* pWindow
= GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView
)));
718 return GTK_WIDGET(g_object_new(GTV_TYPE_LOK_DIALOG
,
719 "lokdocview", pDocView
,
720 "dialogid", dialogId
,
723 "title", "LOK Dialog",
725 "transient-for", pWindow
,
729 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */