diff options
author | Caolán McNamara <caolanm@redhat.com> | 2020-07-12 15:43:46 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2020-07-12 20:54:15 +0200 |
commit | 0b05a04f978688aedce90e259a31873de82a2d2a (patch) | |
tree | c825911468c0647cace4a2a266f832ff8be757ba | |
parent | bcea211b66910ee6cf6a51e4baa950b3f897e310 (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.cxx | 1 | ||||
-rw-r--r-- | include/svtools/editbrowsebox.hxx | 13 | ||||
-rw-r--r-- | svtools/source/brwbox/ebbcontrols.cxx | 43 | ||||
-rw-r--r-- | svtools/source/brwbox/editbrowsebox.cxx | 56 | ||||
-rw-r--r-- | svx/source/fmcomp/gridcell.cxx | 9 |
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); } |