aa0657e298
create a separate .ui for the ltr-in-rtl scroll arrow region Change-Id: I2ec9099f7441ba82555270b5a99541cd7a989890 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106288 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
504 lines
22 KiB
C++
504 lines
22 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <svtools/svtdllapi.h>
|
|
#include <tools/link.hxx>
|
|
#include <vcl/window.hxx>
|
|
#include <o3tl/typed_flags_set.hxx>
|
|
#include <memory>
|
|
|
|
class StyleSettings;
|
|
|
|
/*
|
|
|
|
Allowed StylbeBits
|
|
------------------
|
|
|
|
WB_SCROLL - The tabs can be scrolled via an extra field
|
|
WB_MINSCROLL - The tabs can be scrolled via 2 additional buttons
|
|
WB_RANGESELECT - Connected ranges can be selected
|
|
WB_MULTISELECT - single tabs can be selected
|
|
WB_BORDER - a border is drawn in the top and in the bottom
|
|
WB_DRAG - A StartDrag handler is called by the TabBar, if drag
|
|
and drop should be started. In addition, drag and drop
|
|
is activated in the TabBar with EnableDrop().
|
|
WB_SIZEABLE - a Split handler is called by the TabBar, if the user
|
|
wants to change the width of the TabBar
|
|
WB_STDTABBAR - WB_BORDER
|
|
|
|
|
|
Allowed PageBits
|
|
-----------------
|
|
|
|
Setting page bits modify the display attributes of the tab name
|
|
|
|
TabBarPageBits::Blue
|
|
- Display tab name in light blue, used in draw for
|
|
invisible layers and in calc for scenario pages
|
|
TabBarPageBits::Italic
|
|
- Display tab name italic, used in draw for
|
|
locked layers
|
|
TabBarPageBits::Underline
|
|
- Display tab name underlined, used in draw for
|
|
non-printable layers
|
|
|
|
|
|
Handlers
|
|
-------
|
|
|
|
Select - is called when a tab is selected or unselected
|
|
DoubleClick - Is called when a DoubleClick has been fired in the
|
|
TabBar. Inside of the handler, GetCurPageId() returns
|
|
the clicked tab or 0, if no tab has been clicked.
|
|
ActivatePage - Is called, if another page is activated.
|
|
GetCurPageId() returns the activated page.
|
|
DeactivatePage - Is called, when a page is deactivated. If another page
|
|
may be activated, true must be returned; if another
|
|
page shall be excluded from the activation, false must
|
|
be returned. GetCurPageId() returns the page to be
|
|
deactivated.
|
|
|
|
|
|
Drag and Drop
|
|
-------------
|
|
|
|
For Drag and Drop, the WinBit WB_DRAG must be set. In addition, the
|
|
Command handler, the QueryDrop handler and the Drop handler must be overlaid.
|
|
In doing so, the following must be implemented in the handlers:
|
|
|
|
Command - If dragging should be started in this handler,
|
|
StartDrag() must be called. This method
|
|
then selects the respective entry or returns
|
|
false, if dragging cannot be carried out.
|
|
|
|
QueryDrop - This handler is always called by StarView, when the
|
|
mouse is pulled over the window while dragging
|
|
(s.a. SV documentation). In this handler, it must be
|
|
determined whether a drop is possible. The drop
|
|
position can be shown in TabBar using ShowDropPos().
|
|
When calling, the position of the Event must be passed.
|
|
If the position is at the left or right border,
|
|
scrolling automatically takes place in the TabBar.
|
|
This method also returns the respective drop position,
|
|
which is also needed for a drop. If the window is left
|
|
while dragging, the drop position can be taken back
|
|
using HideDropPos(). Thus, it is also possible to handle
|
|
a drag which was triggered from outside the TabBar.
|
|
|
|
Drop - In the Drop handler, the pages have to be moved, or
|
|
the new pages have to be inserted. The respective
|
|
drop position can be determined using ShowDropPos().
|
|
|
|
The following methods are needed for Drag and Drop and must be called
|
|
by the handlers:
|
|
|
|
StartDrag - Must be called from the Command handler. As parameters,
|
|
the CommandEvent and a reference to a Region must be
|
|
passed. This vcl::Region then must be passed in
|
|
ExecuteDrag(), if the return value indicates that
|
|
ExecuteDrag shall be carried out. If the entry is not
|
|
selected, it is set as the current entry beforehand.
|
|
Because of this, attention must be paid that the Select
|
|
handler can be called from this method.
|
|
|
|
ShowDropPos - This method must be called by the QueryDrop handler,
|
|
so that the TabBar shows where the Tabs are
|
|
inserted. This method can also be used in the Drop
|
|
handler, in order to determine the position at which
|
|
the Tabs shall be inserted. In the method, the
|
|
position of the Event must be passed. This method
|
|
returns the position, at which the Tabs shall be inserted.
|
|
|
|
HideDropPos - This method takes back the DropPosition previously
|
|
displayed using ShowDropPos(). This method should be
|
|
called, when the window is left in the QueryDrop()
|
|
handler or the drag process has been ended.
|
|
|
|
The following methods can be used if the pages should be switched
|
|
in the Drag and Drop:
|
|
|
|
SwitchPage - This method must be called by the QueryDrop handler
|
|
if the page, over which the mouse pointer resides,
|
|
should be switched. This method should be called
|
|
each time the QueryDrop-Handler is called.
|
|
Switching the page happens with a delay (500 ms) and
|
|
is automatically managed by this method.
|
|
The Position of the Event must be passed in the method.
|
|
This method returns true if the page has been switched.
|
|
|
|
EndSwitchPage - This method resets the data for the switching of the
|
|
page. This method should be called when the window
|
|
is left in QueryDrop() or the drag process has been
|
|
ended.
|
|
|
|
IsInSwitching - With this method, it can be queried in
|
|
ActivatePage()/DeactivatePage() whether this has been
|
|
caused by SwitchPage(). Thus, for example, switching
|
|
can be avoided in DeactivatePage() without an error
|
|
box.
|
|
|
|
|
|
Window Resize
|
|
--------------
|
|
|
|
If the window width can be changed by the user, the WinBit WB_SIZEABLE
|
|
must be set. In this case, the following handler must be overlaid:
|
|
|
|
Split - When this handler is called, the window should be
|
|
adapted to the width that is returned by GetSplitSize().
|
|
In doing so, no minimal or maximum width is taken into
|
|
account. A minimal size can be queried using
|
|
GetMinSize() and the maximum width must be calculated
|
|
by the application itself. As only Online Resize is
|
|
supported, the window width must be changed inside
|
|
this handler and possibly the width of dependent windows
|
|
as well. For this handler, a link can also be set using
|
|
SetSplitHdl().
|
|
|
|
The following methods deliver more information while Splitting:
|
|
|
|
GetSplitSize() - Returns the width of the TabBar, to which the user
|
|
wants to resize the window. No minimum or maximum
|
|
width is taken into account. However, a width < 5
|
|
is never returned. This method only returns valid
|
|
values as long as splitting is active.
|
|
|
|
GetMinSize() - With this method, a minimum window width can be
|
|
queried, so that at least something of a Tab is
|
|
visible. Still, the TabBar can be set more narrow
|
|
then the width that this method returns.
|
|
This method can also be called, when no splitting
|
|
is active.
|
|
|
|
|
|
Edit Mode
|
|
----------
|
|
|
|
The TabBar also offers the user the possibility to change the names
|
|
in the Tabs.
|
|
|
|
EnableEditMode - With this, it can be configured that on Alt+LeftClick,
|
|
StartEditMode() is automatically called by the TabBar.
|
|
In the StartRenaming() handler, the renaming can still
|
|
be rejected.
|
|
StartEditMode - With this method, the EditMode is started on a Tab.
|
|
false is returned, if the EditMode is already
|
|
active, the mode is rejected with StartRenaming()
|
|
or no space is available for editing.
|
|
EndEditMode - With this method, the EditMode is ended.
|
|
SetEditText - With this method, the text in the AllowRenaming()
|
|
handler can still be replaced by another text.
|
|
GetEditText - With this method, the text, which the user has typed
|
|
in, can be queried in the AllowRenaming() handler.
|
|
IsInEditMode - This method is used to query whether the EditMode
|
|
is active.
|
|
IsEditModeCanceled - This method can be used in the EndRenaming()
|
|
handler to query whether the renaming has
|
|
been canceled.
|
|
GetEditPageId - With this method, the tab that is being/has been
|
|
renamed is queried in the Renaming handlers.
|
|
|
|
StartRenaming() - This handler is called when the EditMode hast been
|
|
started using StartEditMode(). GetEditPageId()
|
|
can be used to query which Tab should be renamed.
|
|
false should be returned if the EditMod should
|
|
not be started.
|
|
AllowRenaming() - This handler is called when the EditMode is ended
|
|
(not in case of Cancel). Within this handler, it
|
|
can then be tested whether the text is OK.
|
|
The Tab which was renamed can be queried using
|
|
GetEditPageId().
|
|
One of the following values should be returned:
|
|
TAB_RENAMING_YES
|
|
The Tab is renamed.
|
|
TAB_RENAMING_NO
|
|
The Tab is not renamed, but the EditMode remains
|
|
active, so that the user can adapt the name
|
|
accordingly.
|
|
TAB_RENAMING_CANCEL
|
|
The EditMode was cancelled and the old text
|
|
is restored.
|
|
EndRenaming() - This handler is called when the EditMode has been
|
|
ended. The tab that has been renamed can be
|
|
queried using GetEditPageId(). Using
|
|
IsEditModeCanceled(), it can be queried whether
|
|
the mode has been cancelled and the name has
|
|
thus not been changed.
|
|
|
|
|
|
Maximum Page width
|
|
-------------------
|
|
|
|
The Page width of the tabs can be limited in order to make an easier
|
|
navigation by them possible. If then, the text cannot be displayed
|
|
completely, it is abbreviated with "..." and the whole text is
|
|
displayed in the Tip or in the active help (if no help text is set).
|
|
Using EnableAutoMaxPageWidth(), it can be configured whether the
|
|
maximum page width should be based on the currently visible width
|
|
(which is the default). Otherwise, the maximum page width can
|
|
also be set using SetMaxPageWidth() (in pixels) (in this case, the
|
|
AutoMaxPageWidth is ignored).
|
|
|
|
ContextMenu
|
|
-----------
|
|
|
|
If a context-sensitive PopupMenu should be displayed, the Command
|
|
handler must be overlaid. Using GetPageId() and when passing the
|
|
mouse position, it can be determined whether the mouse click has been
|
|
carried out over an item resp. over which item the mouse click has
|
|
been carried out.
|
|
*/
|
|
|
|
namespace weld {
|
|
class Button;
|
|
}
|
|
|
|
#define WB_RANGESELECT (WinBits(0x00200000))
|
|
#define WB_MULTISELECT (WinBits(0x00400000))
|
|
#define WB_MINSCROLL (WinBits(0x20000000))
|
|
#define WB_INSERTTAB (WinBits(0x40000000))
|
|
#define WB_STDTABBAR WB_BORDER
|
|
|
|
// Page bits
|
|
|
|
enum class TabBarPageBits {
|
|
NONE = 0x00,
|
|
Blue = 0x01,
|
|
Italic = 0x02,
|
|
Underline = 0x04,
|
|
};
|
|
namespace o3tl {
|
|
template<> struct typed_flags<TabBarPageBits> : is_typed_flags<TabBarPageBits, 0x07> {};
|
|
};
|
|
|
|
// interface checks only, do not use in regular control flow
|
|
|
|
#define TPB_DISPLAY_NAME_ALLFLAGS (TabBarPageBits::Blue | TabBarPageBits::Italic | TabBarPageBits::Underline)
|
|
|
|
// - TabBar-Types - used in TabBar::AllowRenaming
|
|
|
|
enum TabBarAllowRenamingReturnCode {
|
|
TABBAR_RENAMING_NO,
|
|
TABBAR_RENAMING_YES,
|
|
TABBAR_RENAMING_CANCEL
|
|
};
|
|
|
|
class MouseEvent;
|
|
class DataChangedEvent;
|
|
|
|
struct ImplTabBarItem;
|
|
struct TabBar_Impl;
|
|
|
|
|
|
class SVT_DLLPUBLIC TabBar : public vcl::Window
|
|
{
|
|
friend class ImplTabSizer;
|
|
|
|
private:
|
|
std::unique_ptr<TabBar_Impl> mpImpl;
|
|
|
|
OUString maEditText;
|
|
Size maWinSize;
|
|
tools::Long mnMaxPageWidth;
|
|
tools::Long mnCurMaxWidth;
|
|
tools::Long mnOffX;
|
|
tools::Long mnOffY;
|
|
tools::Long mnLastOffX;
|
|
tools::Long mnSplitSize;
|
|
sal_uInt64 mnSwitchTime;
|
|
WinBits mnWinStyle;
|
|
sal_uInt16 mnCurPageId;
|
|
sal_uInt16 mnFirstPos;
|
|
sal_uInt16 mnDropPos;
|
|
sal_uInt16 mnSwitchId;
|
|
sal_uInt16 mnEditId;
|
|
|
|
bool mbFormat : 1;
|
|
bool mbFirstFormat : 1;
|
|
bool mbSizeFormat : 1;
|
|
bool mbAutoEditMode : 1;
|
|
bool mbEditCanceled : 1;
|
|
bool mbDropPos : 1;
|
|
bool mbInSelect : 1;
|
|
bool mbMirrored : 1;
|
|
bool mbScrollAlwaysEnabled : 1;
|
|
|
|
Link<TabBar*,void> maSelectHdl;
|
|
Link<TabBar*,void> maSplitHdl;
|
|
Link<const CommandEvent&, void> maScrollAreaContextHdl;
|
|
size_t maCurrentItemList;
|
|
|
|
using Window::ImplInit;
|
|
SVT_DLLPRIVATE void ImplInit( WinBits nWinStyle );
|
|
SVT_DLLPRIVATE void ImplInitSettings( bool bFont, bool bBackground );
|
|
SVT_DLLPRIVATE void ImplGetColors(const StyleSettings& rStyleSettings,
|
|
Color& rFaceColor, Color& rFaceTextColor,
|
|
Color& rSelectColor, Color& rSelectTextColor);
|
|
SVT_DLLPRIVATE void ImplShowPage( sal_uInt16 nPos );
|
|
SVT_DLLPRIVATE bool ImplCalcWidth();
|
|
SVT_DLLPRIVATE void ImplFormat();
|
|
SVT_DLLPRIVATE sal_uInt16 ImplGetLastFirstPos();
|
|
SVT_DLLPRIVATE void ImplInitControls();
|
|
SVT_DLLPRIVATE void ImplEnableControls();
|
|
SVT_DLLPRIVATE void ImplSelect();
|
|
SVT_DLLPRIVATE void ImplActivatePage();
|
|
SVT_DLLPRIVATE bool ImplDeactivatePage();
|
|
SVT_DLLPRIVATE void ImplPrePaint();
|
|
SVT_DLLPRIVATE ImplTabBarItem* ImplGetLastTabBarItem( sal_uInt16 nItemCount );
|
|
|
|
DECL_DLLPRIVATE_LINK(ImplClickHdl, weld::Button&, void);
|
|
DECL_DLLPRIVATE_LINK(ImplAddClickHandler, weld::Button&, void);
|
|
DECL_DLLPRIVATE_LINK(MousePressHdl, const MouseEvent&, bool);
|
|
DECL_DLLPRIVATE_LINK(ContextMenuHdl, const CommandEvent&, void);
|
|
|
|
ImplTabBarItem* seek( size_t i );
|
|
ImplTabBarItem* prev();
|
|
ImplTabBarItem* next();
|
|
|
|
protected:
|
|
virtual void AddTabClick();
|
|
OUString GetAuxiliaryText(sal_uInt16 nPageId) const; // needed in derived class LayerTabBar
|
|
void SetAuxiliaryText(sal_uInt16 nPageId, const OUString& rText );
|
|
|
|
public:
|
|
static const sal_uInt16 APPEND;
|
|
static const sal_uInt16 PAGE_NOT_FOUND;
|
|
|
|
TabBar( vcl::Window* pParent, WinBits nWinStyle );
|
|
virtual ~TabBar() override;
|
|
virtual void dispose() override;
|
|
|
|
virtual void MouseMove( const MouseEvent& rMEvt ) override;
|
|
virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
|
|
virtual void MouseButtonUp( const MouseEvent& rMEvt ) override;
|
|
virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
|
|
virtual void Resize() override;
|
|
virtual void RequestHelp( const HelpEvent& rHEvt ) override;
|
|
virtual void StateChanged( StateChangedType nStateChange ) override;
|
|
virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
|
|
virtual bool PreNotify( NotifyEvent& rNEvt ) override;
|
|
|
|
virtual void Select();
|
|
virtual void DoubleClick();
|
|
void Split();
|
|
virtual void ActivatePage();
|
|
virtual bool DeactivatePage();
|
|
virtual bool StartRenaming();
|
|
virtual TabBarAllowRenamingReturnCode AllowRenaming();
|
|
virtual void EndRenaming();
|
|
virtual void Mirror();
|
|
|
|
virtual void InsertPage( sal_uInt16 nPageId, const OUString& rText,
|
|
TabBarPageBits nBits = TabBarPageBits::NONE,
|
|
sal_uInt16 nPos = TabBar::APPEND );
|
|
void RemovePage( sal_uInt16 nPageId );
|
|
void MovePage( sal_uInt16 nPageId, sal_uInt16 nNewPos );
|
|
|
|
Color GetTabBgColor( sal_uInt16 nPageId ) const;
|
|
void SetTabBgColor( sal_uInt16 nPageId, const Color& aTabBgColor );
|
|
|
|
void Clear();
|
|
|
|
bool IsPageEnabled( sal_uInt16 nPageId ) const;
|
|
|
|
void SetPageBits( sal_uInt16 nPageId, TabBarPageBits nBits );
|
|
TabBarPageBits GetPageBits( sal_uInt16 nPageId ) const;
|
|
|
|
sal_uInt16 GetPageCount() const;
|
|
sal_uInt16 GetPageId( sal_uInt16 nPos ) const;
|
|
sal_uInt16 GetPagePos( sal_uInt16 nPageId ) const;
|
|
sal_uInt16 GetCurPagePos() const { return GetPagePos(GetCurPageId()); }
|
|
sal_uInt16 GetPageId( const Point& rPos ) const;
|
|
tools::Rectangle GetPageRect( sal_uInt16 nPageId ) const;
|
|
// returns the rectangle in which page tabs are drawn
|
|
tools::Rectangle GetPageArea() const;
|
|
|
|
void SetCurPageId( sal_uInt16 nPageId );
|
|
sal_uInt16 GetCurPageId() const { return mnCurPageId; }
|
|
|
|
void SetFirstPageId( sal_uInt16 nPageId );
|
|
void MakeVisible( sal_uInt16 nPageId );
|
|
|
|
void SelectPage( sal_uInt16 nPageId, bool bSelect );
|
|
sal_uInt16 GetSelectPageCount() const;
|
|
bool IsPageSelected( sal_uInt16 nPageId ) const;
|
|
void SetProtectionSymbol( sal_uInt16 nPageId, bool bProtection );
|
|
|
|
void SetMaxPageWidth( tools::Long nMaxWidth );
|
|
|
|
void EnableEditMode() { mbAutoEditMode = true; }
|
|
bool StartEditMode( sal_uInt16 nPageId );
|
|
void EndEditMode( bool bCancel = false );
|
|
void SetEditText( const OUString& rText ) { maEditText = rText; }
|
|
const OUString& GetEditText() const { return maEditText; }
|
|
bool IsInEditMode() const;
|
|
bool IsEditModeCanceled() const { return mbEditCanceled; }
|
|
sal_uInt16 GetEditPageId() const { return mnEditId; }
|
|
|
|
/** Mirrors the entire control including position of buttons and splitter.
|
|
Mirroring is done relative to the current direction of the GUI.
|
|
@param bMirrored sal_True = the control will draw itself RTL in LTR GUI,
|
|
and vice versa; sal_False = the control behaves according to the
|
|
current direction of the GUI. */
|
|
void SetMirrored(bool bMirrored);
|
|
/** Returns true, if the control is set to mirrored mode (see SetMirrored()). */
|
|
bool IsMirrored() const { return mbMirrored; }
|
|
|
|
/** Sets the control to LTR or RTL mode regardless of the GUI direction.
|
|
@param bRTL sal_False = the control will draw from left to right;
|
|
sal_True = the control will draw from right to left. */
|
|
void SetEffectiveRTL( bool bRTL );
|
|
/** Returns true, if the control draws from right to left (see SetEffectiveRTL()). */
|
|
bool IsEffectiveRTL() const;
|
|
|
|
bool StartDrag( const CommandEvent& rCEvt, vcl::Region& rRegion );
|
|
sal_uInt16 ShowDropPos( const Point& rPos );
|
|
void HideDropPos();
|
|
void SwitchPage( const Point& rPos );
|
|
void EndSwitchPage();
|
|
|
|
virtual void SetPageText( sal_uInt16 nPageId, const OUString& rText );
|
|
OUString GetPageText( sal_uInt16 nPageId ) const;
|
|
OUString GetHelpText( sal_uInt16 nPageId ) const;
|
|
|
|
tools::Long GetSplitSize() const { return mnSplitSize; }
|
|
|
|
using Window::SetHelpText;
|
|
using Window::GetHelpText;
|
|
using Window::SetHelpId;
|
|
using Window::GetHelpId;
|
|
|
|
void SetStyle( WinBits nStyle );
|
|
WinBits GetStyle() const { return mnWinStyle; }
|
|
|
|
void SetScrollAlwaysEnabled(bool bScrollAlwaysEnabled);
|
|
|
|
Size CalcWindowSizePixel() const;
|
|
|
|
void SetSelectHdl( const Link<TabBar*,void>& rLink ) { maSelectHdl = rLink; }
|
|
void SetSplitHdl( const Link<TabBar*,void>& rLink ) { maSplitHdl = rLink; }
|
|
void SetScrollAreaContextHdl( const Link<const CommandEvent&,void>& rLink ) { maScrollAreaContextHdl = rLink; }
|
|
|
|
// accessibility
|
|
virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;
|
|
};
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|