From c524e1935668f40415927a365e39a0a1c75d91c5 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 2 Nov 2011 23:44:00 -0400 Subject: Calculate window size and geometries of controls based on menu items. This makes the popup window more flexible and adjust to a varying number of menu items. This is necessary now that we use this popup in two different places (autofilter and pivot table field popup) with different menu item configurations. --- sc/source/ui/cctrl/checklistmenu.cxx | 185 ++++++++++++++++++++--------------- sc/source/ui/inc/checklistmenu.hxx | 10 +- sc/source/ui/view/gridwin.cxx | 2 +- sc/source/ui/view/gridwin2.cxx | 2 +- 4 files changed, 115 insertions(+), 84 deletions(-) (limited to 'sc') diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx index 63a0f3063b34..ed32c8f42bb3 100644 --- a/sc/source/ui/cctrl/checklistmenu.cxx +++ b/sc/source/ui/cctrl/checklistmenu.cxx @@ -261,6 +261,25 @@ ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText return aItem.mpSubMenuWin.get(); } +Size ScMenuFloatingWindow::getMenuSize() const +{ + if (maMenuItems.empty()) + return Size(); + + vector::const_iterator itr = maMenuItems.begin(), itrEnd = maMenuItems.end(); + long nTextWidth = 0; + for (; itr != itrEnd; ++itr) + nTextWidth = ::std::max(GetTextWidth(itr->maText), nTextWidth); + + size_t nLastPos = maMenuItems.size()-1; + Point aPos; + Size aSize; + getMenuItemPosSize(nLastPos, aPos, aSize); + aPos.X() += nTextWidth + 15; + aPos.Y() += aSize.Height() + 5; + return Size(aPos.X(), aPos.Y()); +} + void ScMenuFloatingWindow::drawMenuItem(size_t nPos) { if (nPos >= maMenuItems.size()) @@ -471,21 +490,7 @@ ScDocument* ScMenuFloatingWindow::getDoc() void ScMenuFloatingWindow::resizeToFitMenuItems() { - if (maMenuItems.empty()) - return; - - vector::const_iterator itr = maMenuItems.begin(), itrEnd = maMenuItems.end(); - long nTextWidth = 0; - for (; itr != itrEnd; ++itr) - nTextWidth = ::std::max(GetTextWidth(itr->maText), nTextWidth); - - size_t nLastPos = maMenuItems.size()-1; - Point aPos; - Size aSize; - getMenuItemPosSize(nLastPos, aPos, aSize); - aPos.X() += nTextWidth + 15; - aPos.Y() += aSize.Height() + 5; - SetOutputSizePixel(Size(aPos.X(), aPos.Y())); + SetOutputSizePixel(getMenuSize()); } void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer) @@ -768,7 +773,7 @@ ScCheckListMenuWindow::ScCheckListMenuWindow(Window* pParent, ScDocument* pDoc) mnCurTabStop(0), mpExtendedData(NULL), mpOKAction(NULL), - maWndSize(240, 330), + maWndSize(200, 330), mePrevToggleAllState(STATE_DONTKNOW) { maTabStopCtrls.reserve(7); @@ -779,80 +784,34 @@ ScCheckListMenuWindow::ScCheckListMenuWindow(Window* pParent, ScDocument* pDoc) maTabStopCtrls.push_back(&maBtnUnselectSingle); maTabStopCtrls.push_back(&maBtnOk); maTabStopCtrls.push_back(&maBtnCancel); - - const StyleSettings& rStyle = GetSettings().GetStyleSettings(); - - Point aPos; - Size aSize; - getSectionPosSize(aPos, aSize, WHOLE); - SetOutputSizePixel(aSize); - - getSectionPosSize(aPos, aSize, BTN_OK); - maBtnOk.SetPosSizePixel(aPos, aSize); - maBtnOk.SetFont(getLabelFont()); - maBtnOk.SetClickHdl( LINK(this, ScCheckListMenuWindow, ButtonHdl) ); - maBtnOk.Show(); - - getSectionPosSize(aPos, aSize, BTN_CANCEL); - maBtnCancel.SetPosSizePixel(aPos, aSize); - maBtnCancel.SetFont(getLabelFont()); - maBtnCancel.Show(); - - getSectionPosSize(aPos, aSize, LISTBOX_AREA_INNER); - maChecks.SetPosSizePixel(aPos, aSize); - maChecks.SetFont(getLabelFont()); - maChecks.SetCheckButtonHdl( LINK(this, ScCheckListMenuWindow, CheckHdl) ); - maChecks.Show(); - - getSectionPosSize(aPos, aSize, CHECK_TOGGLE_ALL); - maChkToggleAll.SetPosSizePixel(aPos, aSize); - maChkToggleAll.SetFont(getLabelFont()); - maChkToggleAll.SetText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_TOGGLE_ALL).GetString()); - maChkToggleAll.SetTextColor(rStyle.GetMenuTextColor()); - maChkToggleAll.SetControlBackground(rStyle.GetMenuColor()); - maChkToggleAll.SetClickHdl( LINK(this, ScCheckListMenuWindow, TriStateHdl) ); - maChkToggleAll.Show(); - - getSectionPosSize(aPos, aSize, BTN_SINGLE_SELECT); - maBtnSelectSingle.SetPosSizePixel(aPos, aSize); - maBtnSelectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_SELECT_CURRENT).GetString()); - maBtnSelectSingle.SetModeImage(Image(ScResId(RID_IMG_SELECT_CURRENT))); - maBtnSelectSingle.SetClickHdl( LINK(this, ScCheckListMenuWindow, ButtonHdl) ); - maBtnSelectSingle.Show(); - - getSectionPosSize(aPos, aSize, BTN_SINGLE_UNSELECT); - maBtnUnselectSingle.SetPosSizePixel(aPos, aSize); - maBtnUnselectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_UNSELECT_CURRENT).GetString()); - maBtnUnselectSingle.SetModeImage(Image(ScResId(RID_IMG_UNSELECT_CURRENT))); - maBtnUnselectSingle.SetClickHdl( LINK(this, ScCheckListMenuWindow, ButtonHdl) ); - maBtnUnselectSingle.Show(); } ScCheckListMenuWindow::~ScCheckListMenuWindow() { } -void ScCheckListMenuWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const +void ScCheckListMenuWindow::getSectionPosSize( + Point& rPos, Size& rSize, SectionType eType) const { // constant parameters. - const sal_uInt16 nListBoxMargin = 5; // horizontal distance from the side of the dialog to the listbox border. - const sal_uInt16 nListBoxInnerPadding = 5; - const sal_uInt16 nTopMargin = 5; - const sal_uInt16 nMenuHeight = 60; - const sal_uInt16 nSingleItemBtnAreaHeight = 32; // height of the middle area below the list box where the single-action buttons are. - const sal_uInt16 nBottomBtnAreaHeight = 50; // height of the bottom area where the OK and Cancel buttons are. - const sal_uInt16 nBtnWidth = 90; - const sal_uInt16 nLabelHeight = static_cast< sal_uInt16 >( getLabelFont().GetHeight() ); - const sal_uInt16 nBtnHeight = nLabelHeight*2; - const sal_uInt16 nBottomMargin = 10; - const sal_uInt16 nMenuListMargin = 20; + const long nListBoxMargin = 5; // horizontal distance from the side of the dialog to the listbox border. + const long nListBoxInnerPadding = 5; + const long nTopMargin = 5; + const long nMenuHeight = maMenuSize.getHeight(); + const long nSingleItemBtnAreaHeight = 32; // height of the middle area below the list box where the single-action buttons are. + const long nBottomBtnAreaHeight = 50; // height of the bottom area where the OK and Cancel buttons are. + const long nBtnWidth = 90; + const long nLabelHeight = getLabelFont().GetHeight(); + const long nBtnHeight = nLabelHeight*2; + const long nBottomMargin = 10; + const long nMenuListMargin = 5; // parameters calculated from constants. - const sal_uInt16 nListBoxWidth = static_cast< sal_uInt16 >( maWndSize.Width() - nListBoxMargin*2 ); - const sal_uInt16 nListBoxHeight = static_cast< sal_uInt16 >( maWndSize.Height() - nTopMargin - nMenuHeight - - nMenuListMargin - nSingleItemBtnAreaHeight - nBottomBtnAreaHeight ); + const long nListBoxWidth = maWndSize.Width() - nListBoxMargin*2; + const long nListBoxHeight = maWndSize.Height() - nTopMargin - nMenuHeight - + nMenuListMargin - nSingleItemBtnAreaHeight - nBottomBtnAreaHeight; - const sal_uInt16 nSingleBtnAreaY = nTopMargin + nMenuHeight + nListBoxHeight + nMenuListMargin - 1; + const long nSingleBtnAreaY = nTopMargin + nMenuHeight + nListBoxHeight + nMenuListMargin - 1; switch (eType) { @@ -898,7 +857,7 @@ void ScCheckListMenuWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionT { long h = 26; rPos = Point(nListBoxMargin, nSingleBtnAreaY); - rPos.X() += 150; + rPos.X() += nListBoxWidth - h - 10 - h - 10; rPos.Y() += (nSingleItemBtnAreaHeight - h)/2; rSize = Size(h, h); } @@ -907,7 +866,7 @@ void ScCheckListMenuWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionT { long h = 26; rPos = Point(nListBoxMargin, nSingleBtnAreaY); - rPos.X() += 150 + h + 10; + rPos.X() += nListBoxWidth - h - 10; rPos.Y() += (nSingleItemBtnAreaHeight - h)/2; rSize = Size(h, h); } @@ -933,6 +892,64 @@ void ScCheckListMenuWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionT } } +void ScCheckListMenuWindow::packWindow() +{ + maMenuSize = getMenuSize(); + + if (maWndSize.Width() < maMenuSize.Width()) + // Widen the window to fit the menu items. + maWndSize.Width() = maMenuSize.Width(); + + SetOutputSizePixel(maWndSize); + + const StyleSettings& rStyle = GetSettings().GetStyleSettings(); + + Point aPos; + Size aSize; + getSectionPosSize(aPos, aSize, WHOLE); + SetOutputSizePixel(aSize); + + getSectionPosSize(aPos, aSize, BTN_OK); + maBtnOk.SetPosSizePixel(aPos, aSize); + maBtnOk.SetFont(getLabelFont()); + maBtnOk.SetClickHdl( LINK(this, ScCheckListMenuWindow, ButtonHdl) ); + maBtnOk.Show(); + + getSectionPosSize(aPos, aSize, BTN_CANCEL); + maBtnCancel.SetPosSizePixel(aPos, aSize); + maBtnCancel.SetFont(getLabelFont()); + maBtnCancel.Show(); + + getSectionPosSize(aPos, aSize, LISTBOX_AREA_INNER); + maChecks.SetPosSizePixel(aPos, aSize); + maChecks.SetFont(getLabelFont()); + maChecks.SetCheckButtonHdl( LINK(this, ScCheckListMenuWindow, CheckHdl) ); + maChecks.Show(); + + getSectionPosSize(aPos, aSize, CHECK_TOGGLE_ALL); + maChkToggleAll.SetPosSizePixel(aPos, aSize); + maChkToggleAll.SetFont(getLabelFont()); + maChkToggleAll.SetText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_TOGGLE_ALL).GetString()); + maChkToggleAll.SetTextColor(rStyle.GetMenuTextColor()); + maChkToggleAll.SetControlBackground(rStyle.GetMenuColor()); + maChkToggleAll.SetClickHdl( LINK(this, ScCheckListMenuWindow, TriStateHdl) ); + maChkToggleAll.Show(); + + getSectionPosSize(aPos, aSize, BTN_SINGLE_SELECT); + maBtnSelectSingle.SetPosSizePixel(aPos, aSize); + maBtnSelectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_SELECT_CURRENT).GetString()); + maBtnSelectSingle.SetModeImage(Image(ScResId(RID_IMG_SELECT_CURRENT))); + maBtnSelectSingle.SetClickHdl( LINK(this, ScCheckListMenuWindow, ButtonHdl) ); + maBtnSelectSingle.Show(); + + getSectionPosSize(aPos, aSize, BTN_SINGLE_UNSELECT); + maBtnUnselectSingle.SetPosSizePixel(aPos, aSize); + maBtnUnselectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_UNSELECT_CURRENT).GetString()); + maBtnUnselectSingle.SetModeImage(Image(ScResId(RID_IMG_UNSELECT_CURRENT))); + maBtnUnselectSingle.SetClickHdl( LINK(this, ScCheckListMenuWindow, ButtonHdl) ); + maBtnUnselectSingle.Show(); +} + void ScCheckListMenuWindow::setAllMemberState(bool bSet) { size_t n = maMembers.size(); @@ -1174,6 +1191,12 @@ void ScCheckListMenuWindow::getResult(boost::unordered_map& rResult); + void launch(const Rectangle& rRect); void close(bool bOK); /** @@ -278,6 +280,11 @@ private: }; void getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const; + /** + * Calculate the appropriate window size, the position and size of each + * control based on the menu items. + */ + void packWindow(); void setAllMemberState(bool bSet); void selectCurrentMemberOnly(bool bSet); void cycleFocus(bool bReverse = false); @@ -303,7 +310,8 @@ private: ::std::auto_ptr mpExtendedData; ::std::auto_ptr mpOKAction; - const Size maWndSize; /// hard-coded window size. + Size maWndSize; /// whole window size. + Size maMenuSize; /// size of all menu items combined. TriState mePrevToggleAllState; }; diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index e38386c2db2d..02486ccc3abf 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -628,7 +628,7 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow) mpAutoFilterPopup->addMenuItem(ScResId::toString(ScResId(SCSTR_NOTEMPTY)), true, new PopupAction); mpAutoFilterPopup->SetPopupModeEndHdl( LINK(this, ScGridWindow, PopupModeEndHdl) ); - mpAutoFilterPopup->StartPopupMode(aCellRect, (FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_GRABFOCUS)); + mpAutoFilterPopup->launch(aCellRect); } void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow ) diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index aa0ecc5d49ec..f791a44a35cc 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -539,7 +539,7 @@ void ScGridWindow::DPLaunchFieldPopupMenu( aCellRect.SetPos(Point(rScrPos.X() + nXOffset, rScrPos.Y())); } mpDPFieldPopup->SetPopupModeEndHdl( LINK(this, ScGridWindow, PopupModeEndHdl) ); - mpDPFieldPopup->StartPopupMode(aCellRect, (FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_GRABFOCUS)); + mpDPFieldPopup->launch(aCellRect); } void ScGridWindow::UpdateDPFromFieldPopupMenu() -- cgit