summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-07-12 15:43:46 +0100
committerCaolán McNamara <caolanm@redhat.com>2020-07-12 20:54:15 +0200
commit0b05a04f978688aedce90e259a31873de82a2d2a (patch)
treec825911468c0647cace4a2a266f832ff8be757ba
parentbcea211b66910ee6cf6a51e4baa950b3f897e310 (diff)
clarify what WantMouseEvent is for
and add tristate machine support that we also need WantMouseEvent is if the first click in a browse cell that activates it should be passed to the control that appears on click as if it was itself clicked on primarily for the the CheckBoxController to toggle it immediately. Rework to explicitly toggle the checkbox in that implementation rather than rely on passing fake mouse click/release/tracking events. seeing as the main dbaccess table design view doesn't auto-launch its listboxes on clicking in a cell, but the sub create index dialog does, drop the auto-launch in the index dialog to match the main table design rathern than add a feature to weld::ComboBox to auto-launch the popup for that one solitary case Change-Id: Ie3d3f2ecf55d3d5b0b02b85ca09a6ca64bb800e9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98603 Tested-by: Caolán McNamara <caolanm@redhat.com> Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--dbaccess/source/ui/dlg/indexfieldscontrol.cxx1
-rw-r--r--include/svtools/editbrowsebox.hxx13
-rw-r--r--svtools/source/brwbox/ebbcontrols.cxx43
-rw-r--r--svtools/source/brwbox/editbrowsebox.cxx56
-rw-r--r--svx/source/fmcomp/gridcell.cxx9
5 files changed, 56 insertions, 66 deletions
diff --git a/dbaccess/source/ui/dlg/indexfieldscontrol.cxx b/dbaccess/source/ui/dlg/indexfieldscontrol.cxx
index e0613e02ac17..dd959a05dda8 100644
--- a/dbaccess/source/ui/dlg/indexfieldscontrol.cxx
+++ b/dbaccess/source/ui/dlg/indexfieldscontrol.cxx
@@ -53,7 +53,6 @@ constexpr auto BROWSER_STANDARD_FLAGS = BrowserMode::COLUMNSELECTION | BrowserMo
void SetAdditionalModifyHdl(const Link<DbaMouseDownListBoxController&,void>& _rHdl);
protected:
- virtual bool WantMouseEvent() const override { return true; }
virtual void callModifyHdl() override;
};
diff --git a/include/svtools/editbrowsebox.hxx b/include/svtools/editbrowsebox.hxx
index 3b21aaea53c4..fde44b38d136 100644
--- a/include/svtools/editbrowsebox.hxx
+++ b/include/svtools/editbrowsebox.hxx
@@ -105,7 +105,7 @@ namespace svt
protected:
virtual bool MoveAllowed(const KeyEvent& rEvt) const;
void SetModifyHdl(const Link<LinkParamNone*,void>& rLink) { maModifyHdl = rLink; }
- virtual bool WantMouseEvent() const;
+ virtual void ActivatingMouseEvent(const BrowserMouseEvent& rEvt, bool bUp);
virtual void callModifyHdl() { maModifyHdl.Call(nullptr); }
};
@@ -581,10 +581,10 @@ namespace svt
class SVT_DLLPUBLIC CheckBoxControl final : public ControlBase
{
std::unique_ptr<weld::CheckButton> m_xBox;
+ weld::TriStateEnabled m_aModeState;
Link<weld::Button&,void> m_aClickLink;
Link<LinkParamNone*,void> m_aModify1Hdl;
Link<LinkParamNone*,void> m_aModify2Hdl;
- bool m_bTriState;
public:
CheckBoxControl(BrowserDataWin* pParent);
@@ -612,8 +612,13 @@ namespace svt
weld::CheckButton& GetBox() {return *m_xBox;};
+ // for pseudo-click when initially clicking in a cell activates
+ // the cell and performs a state change on the button as if
+ // it was clicked on
+ void Clicked();
+
private:
- DECL_LINK(OnClick, weld::Button&, void);
+ DECL_LINK(OnToggle, weld::ToggleButton&, void);
void CallModifyHdls()
{
@@ -634,7 +639,7 @@ namespace svt
virtual void SaveValue() override;
private:
- virtual bool WantMouseEvent() const override;
+ virtual void ActivatingMouseEvent(const BrowserMouseEvent& rEvt, bool bUp) override;
DECL_LINK(ModifyHdl, LinkParamNone*, void);
};
diff --git a/svtools/source/brwbox/ebbcontrols.cxx b/svtools/source/brwbox/ebbcontrols.cxx
index 911063b82d4e..cd65d3ed0264 100644
--- a/svtools/source/brwbox/ebbcontrols.cxx
+++ b/svtools/source/brwbox/ebbcontrols.cxx
@@ -168,28 +168,29 @@ namespace svt
CheckBoxControl::CheckBoxControl(BrowserDataWin* pParent)
: ControlBase(pParent, "svt/ui/checkboxcontrol.ui", "CheckBoxControl")
, m_xBox(m_xBuilder->weld_check_button("checkbox"))
- , m_bTriState(true)
{
+ m_aModeState.bTriStateEnabled = true;
InitControlBase(m_xBox.get());
m_xBox->connect_key_press(LINK(this, ControlBase, KeyInputHdl));
- m_xBox->connect_clicked(LINK(this, CheckBoxControl, OnClick));
+ m_xBox->connect_toggled(LINK(this, CheckBoxControl, OnToggle));
}
void CheckBoxControl::EnableTriState( bool bTriState )
{
- if (m_bTriState != bTriState)
+ if (m_aModeState.bTriStateEnabled != bTriState)
{
- m_bTriState = bTriState;
+ m_aModeState.bTriStateEnabled = bTriState;
- if (!m_bTriState && GetState() == TRISTATE_INDET)
+ if (!m_aModeState.bTriStateEnabled && GetState() == TRISTATE_INDET)
SetState(TRISTATE_FALSE);
}
}
void CheckBoxControl::SetState(TriState eState)
{
- if (!m_bTriState && (eState == TRISTATE_INDET))
+ if (!m_aModeState.bTriStateEnabled && (eState == TRISTATE_INDET))
eState = TRISTATE_FALSE;
+ m_aModeState.eState = eState;
m_xBox->set_state(eState);
}
@@ -204,8 +205,18 @@ namespace svt
ControlBase::dispose();
}
- IMPL_LINK_NOARG(CheckBoxControl, OnClick, weld::Button&, void)
+ void CheckBoxControl::Clicked()
{
+ // if tristate is enabled, m_aModeState will take care of setting the
+ // next state in the sequence via TriStateEnabled::ButtonToggled
+ if (!m_aModeState.bTriStateEnabled)
+ m_xBox->set_active(!m_xBox->get_active());
+ OnToggle(*m_xBox);
+ }
+
+ IMPL_LINK_NOARG(CheckBoxControl, OnToggle, weld::ToggleButton&, void)
+ {
+ m_aModeState.ButtonToggled(*m_xBox);
m_aClickLink.Call(*m_xBox);
CallModifyHdls();
}
@@ -217,9 +228,23 @@ namespace svt
static_cast<CheckBoxControl &>(GetWindow()).SetModifyHdl( LINK(this, CheckBoxCellController, ModifyHdl) );
}
- bool CheckBoxCellController::WantMouseEvent() const
+ void CheckBoxCellController::ActivatingMouseEvent(const BrowserMouseEvent& rEvt, bool /*bUp*/)
{
- return true;
+ CheckBoxControl& rControl = static_cast<CheckBoxControl&>(GetWindow());
+ rControl.GrabFocus();
+
+ // we have to adjust the position of the event relative to the controller's window
+ Point aPos = rEvt.GetPosPixel() - rEvt.GetRect().TopLeft();
+
+ Size aControlSize = rControl.GetSizePixel();
+ Size aBoxSize = rControl.GetBox().get_preferred_size();
+ tools::Rectangle aHotRect(Point((aControlSize.Width() - aBoxSize.Width()) / 2,
+ (aControlSize.Height() - aBoxSize.Height()) / 2),
+ aBoxSize);
+
+ // we want the initial mouse event to act as if it was performed on the checkbox
+ if (aHotRect.IsInside(aPos))
+ rControl.Clicked();
}
weld::CheckButton& CheckBoxCellController::GetCheckBox() const
diff --git a/svtools/source/brwbox/editbrowsebox.cxx b/svtools/source/brwbox/editbrowsebox.cxx
index b9249ccd9ebc..a5c13f067400 100644
--- a/svtools/source/brwbox/editbrowsebox.cxx
+++ b/svtools/source/brwbox/editbrowsebox.cxx
@@ -481,50 +481,13 @@ namespace svt
else if (IsEditing() && !ControlHasFocus())
AsynchGetFocus();
- if (!(IsEditing() && aController->GetWindow().IsEnabled() && aController->WantMouseEvent()))
+ if (!IsEditing() || !aController->GetWindow().IsEnabled())
return;
-// forwards the event to the control
-
- // If the field has been moved previously, we have to adjust the position
-
- aController->GetWindow().GrabFocus();
-
- // the position of the event relative to the controller's window
- Point aPos = _rEvt.GetPosPixel() - _rEvt.GetRect().TopLeft();
- // the (child) window which should really get the event
- vcl::Window* pRealHandler = aController->GetWindow().FindWindow(aPos);
- if (pRealHandler)
- // the coords relative to this real handler
- aPos -= pRealHandler->GetPosPixel();
- else
- pRealHandler = &aController->GetWindow();
-
- // the faked event
- MouseEvent aEvent(aPos, _rEvt.GetClicks(), _rEvt.GetMode(),
- _rEvt.GetButtons(),
- _rEvt.GetModifier());
-
- pRealHandler->MouseButtonDown(aEvent);
- if (_bUp)
- pRealHandler->MouseButtonUp(aEvent);
-
- vcl::Window *pWin = &aController->GetWindow();
- if (!pWin->IsTracking())
- {
- for (pWin = pWin->GetWindow(GetWindowType::FirstChild);
- pWin && !pWin->IsTracking();
- pWin = pWin->GetWindow(GetWindowType::Next))
- {
- }
- if (!pWin)
- pWin = pRealHandler;
- }
- if (pWin && pWin->IsTracking())
- pWin->EndTracking();
+ // forwards the event to the control
+ aController->ActivatingMouseEvent(_rEvt, _bUp);
}
-
void EditBrowseBox::Dispatch( sal_uInt16 _nId )
{
if ( _nId == BROWSER_ENHANCESELECTION )
@@ -1222,11 +1185,10 @@ namespace svt
pCheckBoxPaint->GetBox().set_sensitive(_bEnabled);
- auto nWidth = pCheckBoxPaint->GetBox().get_preferred_size().Width();
- auto nHeight = pCheckBoxPaint->GetBox().get_preferred_size().Height();
- tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - nWidth) / 2),
- rRect.Top() + ((rRect.GetHeight() - nHeight) / 2)),
- Size(nWidth, nHeight));
+ Size aBoxSize = pCheckBoxPaint->GetBox().get_preferred_size();
+ tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - aBoxSize.Width()) / 2),
+ rRect.Top() + ((rRect.GetHeight() - aBoxSize.Height()) / 2)),
+ aBoxSize);
pCheckBoxPaint->SetPosSizePixel(aRect.TopLeft(), aRect.GetSize());
pCheckBoxPaint->Draw(&GetDataWindow(), aRect.TopLeft(), DrawFlags::NONE);
@@ -1305,9 +1267,9 @@ namespace svt
// nothing to do in this base class
}
- bool CellController::WantMouseEvent() const
+ void CellController::ActivatingMouseEvent(const BrowserMouseEvent& /*rEvt*/, bool /*bUp*/)
{
- return false;
+ // nothing to do in this base class
}
bool CellController::MoveAllowed(const KeyEvent&) const
diff --git a/svx/source/fmcomp/gridcell.cxx b/svx/source/fmcomp/gridcell.cxx
index 67137720d18b..a813e7710a99 100644
--- a/svx/source/fmcomp/gridcell.cxx
+++ b/svx/source/fmcomp/gridcell.cxx
@@ -1696,11 +1696,10 @@ void DbCheckBox::PaintFieldToCell(OutputDevice& rDev, const tools::Rectangle& rR
CheckBoxControl* pControl = static_cast<CheckBoxControl*>(m_pPainter.get());
lcl_setCheckBoxState( _rxField, pControl );
- auto nWidth = pControl->GetBox().get_preferred_size().Width();
- auto nHeight = pControl->GetBox().get_preferred_size().Height();
- tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - nWidth) / 2),
- rRect.Top() + ((rRect.GetHeight() - nHeight) / 2)),
- Size(nWidth, nHeight));
+ Size aBoxSize = pControl->GetBox().get_preferred_size();
+ tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - aBoxSize.Width()) / 2),
+ rRect.Top() + ((rRect.GetHeight() - aBoxSize.Height()) / 2)),
+ aBoxSize);
DbCellControl::PaintFieldToCell(rDev, aRect, _rxField, xFormatter);
}