Kaydet (Commit) 77bb77ae authored tarafından Pranav Kant's avatar Pranav Kant

lokdialog: Mouse events for dialog floating child windows

Change-Id: I06a081835d246f752e57f8cc289162ed31fc91d4
üst cce5bdbe
...@@ -564,6 +564,14 @@ static void doc_postDialogMouseEvent (LibreOfficeKitDocument* pThis, ...@@ -564,6 +564,14 @@ static void doc_postDialogMouseEvent (LibreOfficeKitDocument* pThis,
int nCount, int nCount,
int nButtons, int nButtons,
int nModifier); int nModifier);
static void doc_postDialogChildMouseEvent (LibreOfficeKitDocument* pThis,
const char* pDialogId,
int nType,
int nX,
int nY,
int nCount,
int nButtons,
int nModifier);
static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, static void doc_postUnoCommand(LibreOfficeKitDocument* pThis,
const char* pCommand, const char* pCommand,
const char* pArguments, const char* pArguments,
...@@ -636,6 +644,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone ...@@ -636,6 +644,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone
m_pDocumentClass->postDialogKeyEvent = doc_postDialogKeyEvent; m_pDocumentClass->postDialogKeyEvent = doc_postDialogKeyEvent;
m_pDocumentClass->postMouseEvent = doc_postMouseEvent; m_pDocumentClass->postMouseEvent = doc_postMouseEvent;
m_pDocumentClass->postDialogMouseEvent = doc_postDialogMouseEvent; m_pDocumentClass->postDialogMouseEvent = doc_postDialogMouseEvent;
m_pDocumentClass->postDialogChildMouseEvent = doc_postDialogChildMouseEvent;
m_pDocumentClass->postUnoCommand = doc_postUnoCommand; m_pDocumentClass->postUnoCommand = doc_postUnoCommand;
m_pDocumentClass->setTextSelection = doc_setTextSelection; m_pDocumentClass->setTextSelection = doc_setTextSelection;
m_pDocumentClass->getTextSelection = doc_getTextSelection; m_pDocumentClass->getTextSelection = doc_getTextSelection;
...@@ -2323,6 +2332,21 @@ static void doc_postDialogMouseEvent(LibreOfficeKitDocument* pThis, const char* ...@@ -2323,6 +2332,21 @@ static void doc_postDialogMouseEvent(LibreOfficeKitDocument* pThis, const char*
pDoc->postDialogMouseEvent(aDialogID, nType, nX, nY, nCount, nButtons, nModifier); pDoc->postDialogMouseEvent(aDialogID, nType, nX, nY, nCount, nButtons, nModifier);
} }
static void doc_postDialogChildMouseEvent(LibreOfficeKitDocument* pThis, const char* pDialogId, int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
{
SolarMutexGuard aGuard;
IDialogRenderable* pDoc = getDialogRenderable(pThis);
if (!pDoc)
{
gImpl->maLastExceptionMsg = "Document doesn't support dialog rendering";
return;
}
vcl::DialogID aDialogID = OUString::createFromAscii(pDialogId);
pDoc->postDialogChildMouseEvent(aDialogID, nType, nX, nY, nCount, nButtons, nModifier);
}
static void doc_setTextSelection(LibreOfficeKitDocument* pThis, int nType, int nX, int nY) static void doc_setTextSelection(LibreOfficeKitDocument* pThis, int nType, int nX, int nY)
{ {
SolarMutexGuard aGuard; SolarMutexGuard aGuard;
......
...@@ -288,6 +288,16 @@ struct _LibreOfficeKitDocumentClass ...@@ -288,6 +288,16 @@ struct _LibreOfficeKitDocumentClass
int nButtons, int nButtons,
int nModifier); int nModifier);
/// WIP
void (*postDialogChildMouseEvent) (LibreOfficeKitDocument* pThis,
const char* pDialogId,
int nType,
int nX,
int nY,
int nCount,
int nButtons,
int nModifier);
#endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
}; };
......
...@@ -42,6 +42,9 @@ public: ...@@ -42,6 +42,9 @@ public:
virtual void postDialogMouseEvent(const DialogID& rDialogID, int nType, int nX, int nY, virtual void postDialogMouseEvent(const DialogID& rDialogID, int nType, int nX, int nY,
int nCount, int nButtons, int nModifier) = 0; int nCount, int nButtons, int nModifier) = 0;
virtual void postDialogChildMouseEvent(const DialogID& rDialogID, int nType, int nX, int nY,
int nCount, int nButtons, int nModifier) = 0;
// Callbacks // Callbacks
virtual void notifyDialogInvalidation(const DialogID& rDialogID) = 0; virtual void notifyDialogInvalidation(const DialogID& rDialogID) = 0;
......
...@@ -91,6 +91,9 @@ public: ...@@ -91,6 +91,9 @@ public:
void LogicMouseButtonDown(const MouseEvent& rMouseEvent); void LogicMouseButtonDown(const MouseEvent& rMouseEvent);
void LogicMouseButtonUp(const MouseEvent& rMouseEvent); void LogicMouseButtonUp(const MouseEvent& rMouseEvent);
void LogicMouseMove(const MouseEvent& rMouseEvent); void LogicMouseMove(const MouseEvent& rMouseEvent);
void LogicMouseButtonDownChild(const MouseEvent& rMouseEvent);
void LogicMouseButtonUpChild(const MouseEvent& rMouseEvent);
void LogicMouseMoveChild(const MouseEvent& rMouseEvent);
void LOKKeyInput(const KeyEvent& rKeyEvent); void LOKKeyInput(const KeyEvent& rKeyEvent);
void LOKKeyUp(const KeyEvent& rKeyEvent); void LOKKeyUp(const KeyEvent& rKeyEvent);
......
...@@ -129,6 +129,7 @@ public: ...@@ -129,6 +129,7 @@ public:
SAL_DLLPRIVATE tools::Rectangle& ImplGetItemEdgeClipRect(); SAL_DLLPRIVATE tools::Rectangle& ImplGetItemEdgeClipRect();
SAL_DLLPRIVATE bool ImplIsInPrivatePopupMode() const { return mbInPopupMode; } SAL_DLLPRIVATE bool ImplIsInPrivatePopupMode() const { return mbInPopupMode; }
virtual void doDeferredInit(WinBits nBits) override; virtual void doDeferredInit(WinBits nBits) override;
virtual void LogicInvalidate(const tools::Rectangle* pRectangle) override;
public: public:
explicit FloatingWindow(vcl::Window* pParent, WinBits nStyle); explicit FloatingWindow(vcl::Window* pParent, WinBits nStyle);
......
...@@ -34,11 +34,18 @@ struct GtvLokDialogPrivate ...@@ -34,11 +34,18 @@ struct GtvLokDialogPrivate
GtkWidget* pDialogDrawingArea; GtkWidget* pDialogDrawingArea;
GtkWidget* pFloatingWin; GtkWidget* pFloatingWin;
// state for dialog
guint32 m_nLastButtonPressTime; guint32 m_nLastButtonPressTime;
guint32 m_nLastButtonReleaseTime; guint32 m_nLastButtonReleaseTime;
guint32 m_nKeyModifier; guint32 m_nKeyModifier;
guint32 m_nLastButtonPressed; guint32 m_nLastButtonPressed;
// state for child floating windows
guint32 m_nChildLastButtonPressTime;
guint32 m_nChildLastButtonReleaseTime;
guint32 m_nChildKeyModifier;
guint32 m_nChildLastButtonPressed;
gchar* dialogid; gchar* dialogid;
}; };
...@@ -462,6 +469,115 @@ gtv_lok_dialog_invalidate(GtvLokDialog* dialog) ...@@ -462,6 +469,115 @@ gtv_lok_dialog_invalidate(GtvLokDialog* dialog)
gtk_widget_queue_draw(priv->pDialogDrawingArea); gtk_widget_queue_draw(priv->pDialogDrawingArea);
} }
static gboolean
gtv_lok_dialog_floating_win_signal_button(GtkWidget* /*pDialogChildDrawingArea*/, GdkEventButton* pEvent, gpointer userdata)
{
GtvLokDialog* pDialog = GTV_LOK_DIALOG(userdata);
GtvLokDialogPrivate* priv = getPrivate(pDialog);
GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog)));
LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(window->lokdocview));
g_info("lok_dialog_floating_win_signal_button: %d, %d (in twips: %d, %d)",
(int)pEvent->x, (int)pEvent->y,
(int)pixelToTwip(pEvent->x),
(int)pixelToTwip(pEvent->y));
switch (pEvent->type)
{
case GDK_BUTTON_PRESS:
{
int nCount = 1;
if ((pEvent->time - priv->m_nChildLastButtonPressTime) < 250)
nCount++;
priv->m_nChildLastButtonPressTime = pEvent->time;
int nEventButton = 0;
switch (pEvent->button)
{
case 1:
nEventButton = MOUSE_LEFT;
break;
case 2:
nEventButton = MOUSE_MIDDLE;
break;
case 3:
nEventButton = MOUSE_RIGHT;
break;
}
priv->m_nChildLastButtonPressed = nEventButton;
pDocument->pClass->postDialogChildMouseEvent(pDocument,
priv->dialogid,
LOK_MOUSEEVENT_MOUSEBUTTONDOWN,
(pEvent->x),
(pEvent->y),
nCount,
nEventButton,
priv->m_nChildKeyModifier);
break;
}
case GDK_BUTTON_RELEASE:
{
int nCount = 1;
if ((pEvent->time - priv->m_nChildLastButtonReleaseTime) < 250)
nCount++;
priv->m_nChildLastButtonReleaseTime = pEvent->time;
int nEventButton = 0;
switch (pEvent->button)
{
case 1:
nEventButton = MOUSE_LEFT;
break;
case 2:
nEventButton = MOUSE_MIDDLE;
break;
case 3:
nEventButton = MOUSE_RIGHT;
break;
}
priv->m_nChildLastButtonPressed = nEventButton;
pDocument->pClass->postDialogChildMouseEvent(pDocument,
priv->dialogid,
LOK_MOUSEEVENT_MOUSEBUTTONUP,
(pEvent->x),
(pEvent->y),
nCount,
nEventButton,
priv->m_nChildKeyModifier);
break;
}
default:
break;
}
return FALSE;
}
static gboolean
gtv_lok_dialog_floating_win_signal_motion(GtkWidget* /*pDialogDrawingArea*/, GdkEventButton* pEvent, gpointer userdata)
{
GtvLokDialog* pDialog = GTV_LOK_DIALOG(userdata);
GtvLokDialogPrivate* priv = getPrivate(pDialog);
GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog)));
LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(window->lokdocview));
g_info("lok_dialog_floating_win_signal_motion: %d, %d (in twips: %d, %d)",
(int)pEvent->x, (int)pEvent->y,
(int)pixelToTwip(pEvent->x),
(int)pixelToTwip(pEvent->y));
pDocument->pClass->postDialogChildMouseEvent(pDocument,
priv->dialogid,
LOK_MOUSEEVENT_MOUSEMOVE,
(pEvent->x),
(pEvent->y),
1,
priv->m_nChildLastButtonPressed,
priv->m_nChildKeyModifier);
return FALSE;
}
void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY) void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
{ {
g_info("Dialog's floating window invalidate"); g_info("Dialog's floating window invalidate");
...@@ -477,7 +593,17 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY) ...@@ -477,7 +593,17 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
gtk_window_set_transient_for(GTK_WINDOW(priv->pFloatingWin), GTK_WINDOW(dialog)); gtk_window_set_transient_for(GTK_WINDOW(priv->pFloatingWin), GTK_WINDOW(dialog));
gtk_window_set_destroy_with_parent(GTK_WINDOW(priv->pFloatingWin), true); gtk_window_set_destroy_with_parent(GTK_WINDOW(priv->pFloatingWin), true);
gtk_widget_add_events(pDrawingArea,
GDK_BUTTON_PRESS_MASK
|GDK_POINTER_MOTION_MASK
|GDK_BUTTON_RELEASE_MASK
|GDK_BUTTON_MOTION_MASK);
g_signal_connect(G_OBJECT(pDrawingArea), "draw", G_CALLBACK(gtv_lok_dialog_floating_win_draw), dialog); g_signal_connect(G_OBJECT(pDrawingArea), "draw", G_CALLBACK(gtv_lok_dialog_floating_win_draw), dialog);
g_signal_connect(G_OBJECT(pDrawingArea), "button-press-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button), dialog);
g_signal_connect(G_OBJECT(pDrawingArea), "button-release-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button), dialog);
g_signal_connect(G_OBJECT(pDrawingArea), "motion-notify-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_motion), dialog);
gtk_widget_set_size_request(priv->pFloatingWin, 1, 1); gtk_widget_set_size_request(priv->pFloatingWin, 1, 1);
gtk_window_set_type_hint(GTK_WINDOW(priv->pFloatingWin), GDK_WINDOW_TYPE_HINT_POPUP_MENU); gtk_window_set_type_hint(GTK_WINDOW(priv->pFloatingWin), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
...@@ -485,6 +611,7 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY) ...@@ -485,6 +611,7 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
gtk_widget_show_all(priv->pFloatingWin); gtk_widget_show_all(priv->pFloatingWin);
gtk_window_present(GTK_WINDOW(priv->pFloatingWin)); gtk_window_present(GTK_WINDOW(priv->pFloatingWin));
gtk_widget_grab_focus(pDrawingArea);
// Get the root coords of our new floating window // Get the root coords of our new floating window
GdkWindow* pGdkWin = gtk_widget_get_window(GTK_WIDGET(dialog)); GdkWindow* pGdkWin = gtk_widget_get_window(GTK_WIDGET(dialog));
......
...@@ -439,6 +439,9 @@ public: ...@@ -439,6 +439,9 @@ public:
void postDialogMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY, void postDialogMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
int nCount, int nButtons, int nModifier) override; int nCount, int nButtons, int nModifier) override;
void postDialogChildMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
int nCount, int nButtons, int nModifier) override;
void notifyDialogInvalidation(const vcl::DialogID& rDialogID) override; void notifyDialogInvalidation(const vcl::DialogID& rDialogID) override;
void notifyDialogChild(const vcl::DialogID& rDialogID, const OUString& rAction, const Point& rPos) override; void notifyDialogChild(const vcl::DialogID& rDialogID, const OUString& rAction, const Point& rPos) override;
......
...@@ -3743,6 +3743,46 @@ void SwXTextDocument::postDialogMouseEvent(const vcl::DialogID& rDialogID, int n ...@@ -3743,6 +3743,46 @@ void SwXTextDocument::postDialogMouseEvent(const vcl::DialogID& rDialogID, int n
} }
} }
void SwXTextDocument::postDialogChildMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
int nCount, int nButtons, int nModifier)
{
SolarMutexGuard aGuard;
// check if dialog is already open
SfxViewFrame* pViewFrame = pDocShell->GetView()->GetViewFrame();
SfxSlotPool* pSlotPool = SW_MOD()->GetSlotPool();
const SfxSlot* pSlot = pSlotPool->GetUnoSlot(rDialogID);
if (!pSlot)
{
SAL_WARN("lok.dialog", "No slot found for " << rDialogID);
return;
}
SfxChildWindow* pChild = pViewFrame->GetChildWindow(pSlot->GetSlotId());
if (pChild)
{
Dialog* pDialog = static_cast<Dialog*>(pChild->GetWindow());
Point aPos(nX , nY);
MouseEvent aEvent(aPos, nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier);
switch (nType)
{
case LOK_MOUSEEVENT_MOUSEBUTTONDOWN:
pDialog->LogicMouseButtonDownChild(aEvent);
break;
case LOK_MOUSEEVENT_MOUSEBUTTONUP:
pDialog->LogicMouseButtonUpChild(aEvent);
break;
case LOK_MOUSEEVENT_MOUSEMOVE:
pDialog->LogicMouseMoveChild(aEvent);
break;
default:
assert(false);
break;
}
}
}
void SwXTextDocument::notifyDialogInvalidation(const vcl::DialogID& rDialogID) void SwXTextDocument::notifyDialogInvalidation(const vcl::DialogID& rDialogID)
{ {
SfxLokHelper::notifyDialogInvalidation(rDialogID); SfxLokHelper::notifyDialogInvalidation(rDialogID);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <vcl/svapp.hxx> #include <vcl/svapp.hxx>
#include <vcl/event.hxx> #include <vcl/event.hxx>
#include <vcl/ctrl.hxx> #include <vcl/ctrl.hxx>
#include <vcl/floatwin.hxx>
#include <vcl/decoview.hxx> #include <vcl/decoview.hxx>
#include <vcl/dialog.hxx> #include <vcl/dialog.hxx>
#include <vcl/salnativewidgets.hxx> #include <vcl/salnativewidgets.hxx>
...@@ -420,7 +421,20 @@ void Control::LogicInvalidate(const tools::Rectangle* /*pRectangle*/) ...@@ -420,7 +421,20 @@ void Control::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
// ignore all of those // ignore all of those
if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isDialogPainting()) if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isDialogPainting())
{ {
// For now just invalidate the whole dialog // If parent is a floating window, trigger an invalidate there
vcl::Window* pWindow = this;
while (pWindow)
{
if (pWindow->ImplIsFloatingWindow())
{
dynamic_cast<FloatingWindow*>(pWindow)->LogicInvalidate(nullptr);
return;
}
pWindow = pWindow->GetParent();
}
// otherwise, for now, just invalidate the whole dialog
Dialog* pParentDlg = GetParentDialog(); Dialog* pParentDlg = GetParentDialog();
if (pParentDlg) if (pParentDlg)
pParentDlg->LogicInvalidate(nullptr); pParentDlg->LogicInvalidate(nullptr);
......
...@@ -906,6 +906,42 @@ Size Dialog::PaintActiveFloatingWindow(VirtualDevice& rDevice) ...@@ -906,6 +906,42 @@ Size Dialog::PaintActiveFloatingWindow(VirtualDevice& rDevice)
return aRet; return aRet;
} }
void Dialog::LogicMouseButtonDownChild(const MouseEvent& rMouseEvent)
{
assert(comphelper::LibreOfficeKit::isActive());
ImplSVData* pSVData = ImplGetSVData();
FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
{
ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseButtonDown, &rMouseEvent);
}
}
void Dialog::LogicMouseButtonUpChild(const MouseEvent& rMouseEvent)
{
assert(comphelper::LibreOfficeKit::isActive());
ImplSVData* pSVData = ImplGetSVData();
FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
{
ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseButtonUp, &rMouseEvent);
}
}
void Dialog::LogicMouseMoveChild(const MouseEvent& rMouseEvent)
{
assert(comphelper::LibreOfficeKit::isActive());
ImplSVData* pSVData = ImplGetSVData();
FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
{
ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseMove, &rMouseEvent);
}
}
void Dialog::InvalidateFloatingWindow(const Point& rPos) void Dialog::InvalidateFloatingWindow(const Point& rPos)
{ {
if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable && !maID.isEmpty()) if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable && !maID.isEmpty())
......
...@@ -585,6 +585,15 @@ bool FloatingWindow::EventNotify( NotifyEvent& rNEvt ) ...@@ -585,6 +585,15 @@ bool FloatingWindow::EventNotify( NotifyEvent& rNEvt )
return bRet; return bRet;
} }
void FloatingWindow::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
{
Dialog* pParentDlg = GetParentDialog();
if (pParentDlg)
{
pParentDlg->InvalidateFloatingWindow(mpImplData->maPos);
}
}
void FloatingWindow::StateChanged( StateChangedType nType ) void FloatingWindow::StateChanged( StateChangedType nType )
{ {
if (nType == StateChangedType::InitShow) if (nType == StateChangedType::InitShow)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment