deargui-vpl/ref/virtools/Includes/VITabCtrl.h

254 lines
8.2 KiB
C++

#pragma once
#include "XClassArray.h"
// Creation :
//-----------
// 1) create an instance of VITabCtrl
// 2) call Create() method
// 3) add tabs with one of the InsertTab() methods
// 4) set the flags according to the style you want (up, down, fixed width ..), using SetFlags() or ModifyFlags() methods from VIControl.h
// 5) Activate the tab you want , default activated is 0, with SetActiveTabIndex() method
//
// Functioning :
//--------------
// when the user click on a tab,
// parent windows receives a WM_COMMAND message,
// with in wParam : LOWORD = id of VITabCtrl control in wParam, HIWORD = (activated tab index & 0x0ff) + (old activated index & 0x0ff <<8)
// when the user right click on a tab
// parent windows recieves a WM_NOTIFY message,
// with in wParam : id
// in lParam : a NMTABACTIVATE* with code = NM_RCLICK
//
// when a tab switch is done, the control sends a notifcation with a NMTABSWITCH* in lParam
//
// Important note : 255 max tabs allowed, no more, since in activate tab WM_COMMAND, we have just a short to put old and new activated tab index
//
/////////////////////////////////////////////////////////////////////////////
// VITabCtrl window
class AFX_EXT_CLASS VITabCtrl : public CWnd, public VIControl
{
public:
struct NMTABACTIVATE
{
NMHDR hdr;
int activatedTab;
};
struct NMTABSWITCH
{
NMHDR hdr;
int index1;
int index2;
};
struct VITab
{
XString m_Name;
CWnd* m_Wnd;
int m_Width;
DWORD m_Flags;
DWORD m_Data;
enum VITAB_FLAGS
{
};
VITab() {memset(this,0,sizeof(VITab));}
};
enum VITABCTRL_NOTIFICATION{
VITAB_NM_BEGIN_DRAG = 0x00001000,
VITAB_NM_DRAG = 0x00001001,
VITAB_NM_END_DRAG = 0x00001002,
VITAB_NM_SWITCH = 0x00001003,
};
//Flags
enum VITABCTRL_FLAGS{
VITAB_UP = 0x00000001, //tabs are rounded upside
VITAB_DOWN = 0x00000002, //tabs are rounded downside
VITAB_FIXEDWIDTH = 0x00000004, //tabs have a fixed width
VITAB_BORDER = 0x00000008, //tabs have a border on the opposite side of the rounded rect
VITAB_NEEDARROWBUTTONS = 0x00000010, //Used Internally.too much tabs for wnd width=>, so need arrow buttons to scroll
VITAB_LEFTBUTTON_ROLLOVER = 0x00000020, //Used Internally. rollover on left arrow button info for redraw
VITAB_RIGHTBUTTON_ROLLOVER = 0x00000040, //Used Internally. rollover on right arrow button info for redraw
VITAB_LEFTBUTTON_DOWN = 0x00000080, //Used Internally. left arrow button is pushed info for redraw
VITAB_RIGHTBUTTON_DOWN = 0x00000100, //Used Internally. right arrow button is pushed info for redraw
VITAB_LEFTBUTTON_AVAILABLE = 0x00000200, //Used Internally. left button is available for clicking
VITAB_RIGHTBUTTON_AVAILABLE = 0x00000400, //Used Internally. right button is available for clicking
VITAB_MANAGEWNDS = 0x00000800, //if m_Wnd members of VITAb structs exists, then these windows are shown/hidden when tabs are activated/deactivated
VITAB_MANAGEDRAGNDROPINTERNAL = 0x00001000, //tabs can be dragged & dropped to switch their position
VITAB_MANAGEDRAGNDROPEXTERNAL = 0x00002000, //tabs can be dragged & dropped and notify any wnd about current state of drag & drop
VITAB_MANAGEDRAGNDROP = 0x00003000, //global drag & drop management
VITAB_AUTORESIZETOMINWIDTH = 0x00004000, //Not effective yet. according to added / removed tab, the tab control autoresizes to min width maximized by parent client rect width
};
public:
// Construction
VITabCtrl();
~VITabCtrl();
HRESULT Create(const char* name,DWORD style,RECT &r,CWnd* parent,int id);
//return value : index or -1 if failed
int InsertTab(int index,VITab* tab,BOOL redraw=FALSE); //-1 => append
int InsertTab(int index,const char* name,CWnd* wnd=NULL,BOOL redraw=FALSE); //-1 => append
// Get index of tab under mouse, -1 if any
int GetTabUnderMouse();
// Get index of tab under given client coordinaates
int GetTabAt(POINT &clientP);
//get tab struct ptr, to change on the fly
int GetTabCount() const;
VITab* GetTab(int index);
//update tab after having modified a VITab struct
int UpdateTab(int index,BOOL recomputeWidth=TRUE);
//remove a tab
int RemoveTab(int index,BOOL redraw=TRUE);
//remove all tabs
int RemoveAllTabs(BOOL redraw=TRUE);
//set active tab. -1 means no activate tab
int SetActiveTab(int index=-1,BOOL redraw=TRUE,BOOL sendMessageToParent=FALSE);
//switch tabs
int SwitchTabs(int index1,int index2);
// Data access
int GetTabMargin() {return m_TabMargin;}
int SetTabMargin(int m); //free space around text in tabs
int GetTabSeparationSpace() {return m_TabSeparationSpace;}
int SetTabSeparationSpace(int s); //space in pixel between end of textof 1st tab and drawing of next tab
int GetActiveTabIndex() {return m_ActiveTabIndex;}
int GetTabFixedWidth() {return m_TabFixedWidth;}
int SetTabFixedWidth(int width);
COLORREF GetActiveTabColor() {return m_ActiveTabColor;}
int SetActiveTabColor(COLORREF c);
CImageList* CreateDragImage(int index);
//compute total max width
int ComputeTotalTabWidth();
//get maximum width (to use width flag VITAB_AUTORESIZETOMINWIDTH)
int GetMaximumWidth();
//set maximum width (to use width flag VITAB_AUTORESIZETOMINWIDTH)
void SetMaximumWidth(int newmaxwidth);
protected:
//DATAS
//array of string / tabs
XClassArray<VITab> m_Tabs;
//free space around text in tabs (so x2, margin added to text width left and right)
int m_TabMargin;
//separation between two tabs, after the end of text of the 1st tab
int m_TabSeparationSpace;
//fixed width
int m_TabFixedWidth;
//active tab backcolor
COLORREF m_ActiveTabColor;
//index of first visible tab
int m_FirstVisibleTab;
//image list for internal drag & drop
CImageList* m_DragNDropImageList;
//drag & drop hot spot
POINT m_DragNDropHotspot;
//maximum width, to use with flag VITAB_AUTORESIZETOMINWIDTH.
int m_MaximumWidth;
//FUNCS
//callbacks
int DoOnPaint();
int DoOnLButtonDown(int x,int y,int dblclk=0);
int DoOnLButtonUp(int x,int y);
int DoOnRButtonUp(int x,int y);
int DoOnMouseMove(int x,int y);
int DoOnSize(int width,int height);
int OnClickLeftArrowButton();
int OnClickRightArrowButton();
int OnClickOnTab(int index);
//draw a tab button
int DrawTab(VITab* tab,CDC* dc,int xoffset=-1,int active = 0);
//draw arrow buttons. Return Value : new available width left. If rollover==1 draws only left button filled, if ==2, draws only right button filled, ==3, left is down, ==4 right is down
int DrawArrowButtons(CDC* dc,int rollover=0);
//test available arrow buttons. Modify m_CtrlFlags in consequence
int TestAvailableArrowButtons();
//add/remove VITAB_NEEDARROWBUTTONS flag according to total tab width (ComputeTotalTabWidth()) and client rect .Returns total width
int CheckForArrowButtons();
//get arrow buttons rect.Return Value : new available width left
int GetArrowButtonsRect(RECT* oR1=NULL,RECT* oR2=NULL);
//compute tab width (after insertion, or if need update)
int ComputeTabWidth(VITab* tab);
//return 1 if is 1st visible tab and tabindex!=0, otherwise 0
int IsFirstVisibleTab(int tabIndex);
//return 1 if is last visible tab, otherwise 0
int IsLastVisibleTab(int tabIndex);
//Manage wnds
int ActivatedTabChange(int oldActivatedIndex,int newActivatedIndex);
//return x position of tab, fill oRect
int GetTabRect(int index,RECT* oRect=NULL);
//drag & drop
int BeginDrag(POINT &hotspot);
int DragStop();
int DragCont();
int IsDragActive();
int DragMove();
int EndDrag();
private:
//active tab. Must be set only via SetActiveTab func
int m_ActiveTabIndex;
//---------------------------------------------------------------------------
//----------WINDOWS----------------------------------------------------------
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(VITabCtrl)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Generated message map functions
protected:
//{{AFX_MSG(VITabCtrl)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
//----------WINDOWS----------------------------------------------------------
//---------------------------------------------------------------------------
};