mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-17 22:03:07 -06:00
1135 lines
34 KiB
C++
1135 lines
34 KiB
C++
//==============================================================================================
|
|
// DockCtrl: A dockable widget framework for U++
|
|
// Author: Ismail YILMAZ
|
|
// Version: 0.52 (DEV-0803b.2)
|
|
//==============================================================================================
|
|
|
|
#ifndef DOCKCTRL_H
|
|
#define DOCKCTRL_H
|
|
|
|
#include <CtrlLib/CtrlLib.h>
|
|
#include <Draw/Draw.h>
|
|
|
|
using namespace UPP;
|
|
|
|
#define LAYOUTFILE <DockCtrl/DockCtrl.lay>
|
|
#include <CtrlCore/lay.h>
|
|
|
|
#define IMAGECLASS DockCtrlImgs
|
|
#define IMAGEFILE <DockCtrl/DockableCtrl.iml>
|
|
#include <Draw/iml_header.h>
|
|
|
|
#define TFILE <DockCtrl/DockCtrl.t>
|
|
#include <Core/t.h>
|
|
|
|
#include <CtrlLib/Ch.h>
|
|
|
|
class PaneSplitter;
|
|
class TabInterface;
|
|
class AutoHideBar;
|
|
class PaneFrame;
|
|
class DockBase;
|
|
class DockCtrl;
|
|
class DockWindow;
|
|
class TabWindow;
|
|
class DockableCtrl;
|
|
|
|
//----------------------------------------------------------------------------------------------
|
|
// DockCtrl: Chameleon Support.
|
|
//
|
|
struct DockCtrlChStyle : Moveable<DockCtrlChStyle>
|
|
{
|
|
struct Style : ChStyle<Style>
|
|
{
|
|
Font font;
|
|
int bartitlesize;
|
|
int barheight;
|
|
Rect barmargins;
|
|
Value barbackground[1];
|
|
Value barshut[3];
|
|
Value barhide[3];
|
|
Value barmenu[3];
|
|
int tabheight;
|
|
int tabmargin;
|
|
int tabextendleft;
|
|
Rect tabsel;
|
|
Rect tabedge;
|
|
Value tabnormal[4];
|
|
Value tabfirst[4];
|
|
Value tablast[4];
|
|
Value tabboth[4];
|
|
Value hidebutton[4];
|
|
Image stdhighlight;
|
|
Image tabhighlight;
|
|
};
|
|
const Style* style;
|
|
static const Style& StyleDefault();
|
|
static const Style& StyleClassic();
|
|
static const Style& StyleEnhanced();
|
|
};
|
|
|
|
static void DockCtrlImgsLook(Value* look, int i, int n)
|
|
{
|
|
while(n--)
|
|
*look++ = DockCtrlImgs::Get(i++);
|
|
}
|
|
|
|
static Image StandardHighlight(Color inside, Color border)
|
|
{
|
|
Size sz(5, 5);
|
|
ImageBuffer ib(sz);
|
|
RGBA *q = ~ib;
|
|
for (int i = 0; i < 5; i++)
|
|
for (int j = 0; j < 5; j++)
|
|
*(q++) = (i == 4 || j == 4 || !i || !j) ? border : inside;
|
|
ib.SetHotSpot(Point(1, 1));
|
|
ib.Set2ndSpot(Point(3, 3));
|
|
return ib;
|
|
}
|
|
|
|
static Image AlphaHighlight(const Image &img, int alpha)
|
|
{
|
|
ImageDraw draw(img.GetSize());
|
|
draw.Alpha().DrawRect(img.GetSize(), Color(alpha, alpha, alpha));
|
|
draw.DrawImage(0, 0, img);
|
|
// MingW (5.1.3) fix - Damn, I hate that ever-complaining compiler.
|
|
Image dimg = draw;
|
|
// Is there a better way to set hotspots than this?
|
|
ImageBuffer ib(dimg);
|
|
ib.SetHotSpot(Point(1, 1));
|
|
ib.Set2ndSpot(Point(3, 3));
|
|
return ib;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------
|
|
|
|
struct DockCtrlCustomFrame : FrameCtrl<Ctrl>
|
|
{
|
|
public:
|
|
enum { LAYOUT_LEFT, LAYOUT_TOP, LAYOUT_RIGHT, LAYOUT_BOTTOM };
|
|
enum { TAB_MARGIN = 6, TAB_SPACE = 20, TAB_SBHEIGHT = 4, TAB_SBSEPARATOR = 1, TAB_FILEICON = 16, TAB_SPACEICON = 5 };
|
|
enum { BAR_MARGIN = 6, BAR_SPACE = 20, BAR_SBHEIGHT = 4, BAR_SBSEPARATOR = 1, BAR_FILEICON = 16, BAR_SPACEICON = 5 };
|
|
|
|
void SetLayout(int l) { layout = l; RefreshLayout(); }
|
|
void Fix(Size& sz) { if(!horizontal) Swap(sz.cx, sz.cy); }
|
|
void Fix(Point& p) { if(!horizontal) Swap(p.x, p.y); }
|
|
void SetSize(int sz) { size = sz; }
|
|
bool IsHorz() { return layout == LAYOUT_TOP || layout == LAYOUT_BOTTOM; }
|
|
bool IsVert() { return !IsHorz(); }
|
|
|
|
virtual void FrameLayout(Rect& r);
|
|
virtual void FrameAddSize(Size& sz);
|
|
|
|
DockCtrlCustomFrame& SetStyle(const DockCtrlChStyle::Style& s);
|
|
const DockCtrlChStyle::Style* GetStyle();
|
|
|
|
int layout;
|
|
int size;
|
|
bool horizontal;
|
|
const DockCtrlChStyle::Style* style;
|
|
DockCtrlCustomFrame() : layout(LAYOUT_TOP), size(0), horizontal(true) {}
|
|
|
|
};
|
|
|
|
class TabInterface : public DockCtrlCustomFrame
|
|
{
|
|
private:
|
|
|
|
|
|
class TabScrollBar : public DockCtrlCustomFrame
|
|
{
|
|
private:
|
|
int total;
|
|
double pos, ps;
|
|
int new_pos;
|
|
int old_pos;
|
|
double start_pos;
|
|
double size;
|
|
double cs, ics;
|
|
void UpdatePos(bool update = true);
|
|
bool ready;
|
|
Size sz;
|
|
|
|
public:
|
|
TabScrollBar();
|
|
|
|
virtual void Paint(Draw &w);
|
|
virtual void LeftDown(Point p, dword keyflags);
|
|
virtual void LeftUp(Point p, dword keyflags);
|
|
virtual void MouseMove(Point p, dword keyflags);
|
|
virtual void MouseWheel(Point p, int zdelta, dword keyflags);
|
|
virtual void Layout();
|
|
|
|
int GetPos() const;
|
|
void SetPos(int p, bool dontscale = false);
|
|
void AddPos(int p, bool dontscale = false);
|
|
int GetTotal() const;
|
|
void AddTotal(int t);
|
|
void SetTotal(int t);
|
|
void GoEnd();
|
|
void GoBegin();
|
|
void Set(const TabScrollBar& t);
|
|
TabScrollBar& SetLayout(int l);
|
|
Callback WhenScroll;
|
|
};
|
|
|
|
|
|
|
|
protected:
|
|
void OnScrollBar() { Refresh(); };
|
|
int GetPos() { return scrollbar.GetPos(); }
|
|
Point mouse, oldp;
|
|
TabScrollBar scrollbar;
|
|
|
|
public:
|
|
struct Tab : Moveable<Tab>
|
|
{
|
|
DockableCtrl* dock;
|
|
bool active, visible, highlighted;
|
|
int id;
|
|
int x, y, cx, cy;
|
|
Size textsize;
|
|
String name;
|
|
Image icon;
|
|
int Right() { return x + cx; };
|
|
int Bottom() { return y + cy; };
|
|
bool IsActive() { return active; }
|
|
bool IsVisible() { return visible; }
|
|
bool IsHighligted() { return highlighted; }
|
|
bool HasMouse(const Point& p) { return visible && Rect(x, y, x + cx, y + cy).Contains(p);}
|
|
bool HasMouseButton(const Point& p, int w, int h)
|
|
{
|
|
if(!visible) return false;
|
|
Size isz = DockCtrlImgs::DClose().GetSize();
|
|
int iy = (h - isz.cy) / 2;
|
|
int ix = x + cx - isz.cx - w - TAB_MARGIN;
|
|
return p.x >= ix && p.x < ix + isz.cx && p.y >= iy && p.y < iy + isz.cy;
|
|
}
|
|
Tab() : id(-1), active(false), visible(false), highlighted(false) { dock = NULL; }
|
|
~Tab() { if(dock) dock = NULL; }
|
|
};
|
|
|
|
protected:
|
|
Vector<Tab> tabs;
|
|
int id;
|
|
int active, highlight, visible;
|
|
int fileicon, tabbutton;
|
|
bool hastabbutton, hasfileicon, hasscrollbar, isdraggable;
|
|
int target, source;
|
|
bool isctrl;
|
|
bool isdragged;
|
|
String internalname; // not to confuse with different types of ctrls (tabs X autohidebars)
|
|
|
|
public:
|
|
const TabCtrl::Style *style;
|
|
TabInterface& SetStyle(const TabCtrl::Style& s) { style = &s; Refresh(); return *this; }
|
|
static const TabCtrl::Style& StyleDefault();
|
|
|
|
public:
|
|
void Add(DockableCtrl& dock, bool activate = false);
|
|
void Add(String name, bool activate = false);
|
|
void Remove(DockableCtrl& dock);
|
|
void Remove(int n);
|
|
void Close(int n);
|
|
void CloseAll();
|
|
|
|
void SetActiveTab(int n);
|
|
void SetActiveTab(DockableCtrl& dock);
|
|
void SetActiveTabTitle(String name, Image icon);
|
|
int GetActiveTab();
|
|
int Find(int itemid);
|
|
int Find(DockableCtrl& dock);
|
|
int GetNext(int n);
|
|
int GetPrev(int n);
|
|
virtual void ReposTabs();
|
|
virtual void DrawTab(Draw& w, Size &sz, int i);
|
|
void DrawLabel(Draw& w, int x, int y, Tab& t, bool isactive);
|
|
|
|
Vector<Tab>& GetTabs() {return tabs; }
|
|
|
|
int GetWidth(int n);
|
|
int GetWidth();
|
|
int GetHeight();
|
|
|
|
int GetNextId() { return ++id; }
|
|
|
|
TabInterface& HasButtons(bool b) { hastabbutton = b; ReposTabs(); if(IsOpen() && IsChild()) Refresh(); return *this; }
|
|
TabInterface& HasIcons(bool b) { hasfileicon = b; ReposTabs(); if(IsOpen() && IsChild()) Refresh(); return *this; }
|
|
TabInterface& HasScrollBar(bool b);
|
|
TabInterface& Draggable(bool b = true) { isdraggable = b; return *this; }
|
|
|
|
TabInterface& SetLayout(int l);
|
|
|
|
protected:
|
|
virtual void Paint(Draw& d);
|
|
virtual void LeftDown(Point p, dword keyflags);
|
|
virtual void LeftUp(Point p, dword keyflags);
|
|
virtual void LeftDrag(Point p, dword keyflags);
|
|
virtual void MiddleDrag(Point p, dword keyflags);
|
|
virtual void RightDown(Point p, dword keyflags);
|
|
virtual void RightUp(Point p, dword keyflags);
|
|
virtual void MouseMove(Point p, dword keyflags);
|
|
virtual void MouseWheel(Point p, int zdelta, dword keyflags);
|
|
virtual void MouseLeave();
|
|
virtual void DragAndDrop(Point p, PasteClip& d);
|
|
|
|
virtual void DragEnter();
|
|
virtual void DragLeave();
|
|
virtual void DragRepeat(Point p);
|
|
virtual void CancelMode();
|
|
|
|
int GetTargetTab(Point p);
|
|
int GetSourceTab(Point p);
|
|
|
|
public:
|
|
Callback2<int, DockableCtrl&> WhenContext;
|
|
Callback2<int, DockableCtrl&> WhenClose;
|
|
Callback2<int, DockableCtrl&> WhenDrag;
|
|
Callback2<int, DockableCtrl&> WhenActive;
|
|
Callback WhenHighlight;
|
|
Callback WhenSelect;
|
|
|
|
public:
|
|
typedef TabInterface CLASSNAME;
|
|
|
|
TabInterface();
|
|
~TabInterface();
|
|
};
|
|
|
|
//----------------------------------------------------------------------------------------------
|
|
|
|
class PaneSplitter : public Splitter
|
|
{
|
|
public:
|
|
typedef PaneSplitter CLASSNAME;
|
|
|
|
enum {PANEANIMATION, TABANIMATION };
|
|
|
|
void AddChildDock(DockableCtrl& dock, int position);
|
|
void AddChildDock(DockableCtrl& dock);
|
|
void RemoveChildDock(DockableCtrl& dock);
|
|
void RemoveChildDock(int position);
|
|
void RemoveChilds();
|
|
void ReposChilds();
|
|
DockableCtrl* GetChildAt(int position);
|
|
int GetChildCount();
|
|
bool HasChild();
|
|
|
|
void StartAnimation(DockableCtrl& dock, int position);
|
|
void StartAnimation(int position);
|
|
void StopAnimation();
|
|
inline bool IsAnimating() const { return animating; }
|
|
void Animate(int position = 0);
|
|
void SetAnimationType(int type) { animationctrl.Type(animationtype = type); }
|
|
Rect AnimationArea() { return animationctrl.GetScreenRect();}
|
|
Ctrl* GetAnimationCtrl() { return (Ctrl*) &animationctrl; }
|
|
|
|
virtual void Layout();
|
|
|
|
|
|
private:
|
|
Array<int> positions;
|
|
void AnimateCallback();
|
|
|
|
public:
|
|
class AnimationCtrl : public Ctrl
|
|
{
|
|
public:
|
|
typedef AnimationCtrl CLASSNAME;
|
|
void SetAnimImage(Image& img) { image = img; Refresh(); }
|
|
Image& GetAnimImage() { return image; }
|
|
void ClearAnimImage() { image.Clear(); }
|
|
void AnimateVert();
|
|
void AnimateHorz();
|
|
void Paint(Draw& d);
|
|
void Type(int type) { ctrltype = type; }
|
|
public:
|
|
AnimationCtrl() { /*SetFrame(FieldFrame()); */ctrltype = PaneSplitter::PANEANIMATION; }
|
|
|
|
private:
|
|
Image image;
|
|
int ctrltype;
|
|
};
|
|
AnimationCtrl animationctrl;
|
|
private:
|
|
bool animating;
|
|
int animationtype;
|
|
int pos, x, y;
|
|
|
|
public:
|
|
PaneSplitter();
|
|
~PaneSplitter();
|
|
};
|
|
|
|
//----------------------------------------------------------------------------------------------
|
|
|
|
class DockableCtrl : public TopWindow
|
|
{
|
|
public:
|
|
typedef DockableCtrl CLASSNAME;
|
|
|
|
enum { TYPE_DOCKWINDOW, TYPE_TABWINDOW, TYPE_DOCKBAR }; // Available DockableCtrl types.
|
|
enum { DOCK_LEFT, DOCK_TOP, DOCK_RIGHT, DOCK_BOTTOM, DOCK_TABBED, DOCK_NONE }; // Possible alignments.
|
|
enum { STATE_SHUT, STATE_SHOW, STATE_HIDE, STATE_AUTO, STATE_TABBED }; // Possible states.
|
|
|
|
inline bool IsDockWindow() { return docktype == TYPE_DOCKWINDOW; }
|
|
inline bool IsTabWindow() { return docktype == TYPE_TABWINDOW; }
|
|
inline bool IsDockBar() { return docktype == TYPE_DOCKBAR; }
|
|
|
|
DockableCtrl& DockTop() { dockalignment = DOCK_TOP; return *this;}
|
|
DockableCtrl& DockLeft() { dockalignment = DOCK_LEFT; return *this;}
|
|
DockableCtrl& DockRight() { dockalignment = DOCK_RIGHT; return *this;}
|
|
DockableCtrl& DockBottom() { dockalignment = DOCK_BOTTOM; return *this;}
|
|
DockableCtrl& DockFloat() { dockalignment = DOCK_NONE; dockstate= STATE_SHOW; return *this; }
|
|
|
|
DockableCtrl& StateShut() { dockstate = STATE_SHUT; return *this;}
|
|
DockableCtrl& StateShow() { dockstate = STATE_SHOW; return *this;}
|
|
DockableCtrl& StateHide() { dockstate = STATE_HIDE; return *this;}
|
|
DockableCtrl& StateAuto() { dockstate = STATE_AUTO; return *this;}
|
|
DockableCtrl& StateTabbed() { dockstate = STATE_TABBED; return *this;}
|
|
|
|
DockableCtrl& Posit(int position) { dockposition = position; return *this;}
|
|
|
|
DockableCtrl& DockingStyle(int alignment, int state, int position = 0);
|
|
|
|
inline int Alignment() const { return dockalignment; }
|
|
inline int State() const { return dockstate; }
|
|
inline int Position() const { return dockposition; }
|
|
|
|
inline bool IsDocked() { return !IsShut() && !IsTabbed() && !IsFloating(); }
|
|
inline bool IsHidden() { return IsDocked() && dockstate == STATE_HIDE; }
|
|
inline bool IsAutoHidden() { return IsDocked() && dockstate == STATE_AUTO; }
|
|
inline bool IsShut() { return dockalignment == DOCK_NONE && dockstate == STATE_SHUT; }
|
|
inline bool IsFloating() { return dockalignment == DOCK_NONE && dockstate != STATE_SHUT; }
|
|
inline bool IsTabbed() { return dockstate == STATE_TABBED; }
|
|
|
|
int GetType() { return docktype; } // Returns the type of the derived dockablectrl class.
|
|
DockBase& GetBase() { ASSERT(dockbase); return *dockbase; } // Returns the owner (base) framework.
|
|
String GetLabel() const { return dockname; } // Returns the name of the dockablectrl.
|
|
Image GetIcon () const { return dockicon; } // Returns the icon associated with the dockablectrl.
|
|
Size GetSizeHint() { return docksize; } // Returns the absolute (ctrl + frames) size of the dockablectrl.
|
|
|
|
DockableCtrl& SetLabel(String title);
|
|
DockableCtrl& SetIcon(Image icon);
|
|
|
|
Callback1<Bar&> WhenContextMenu;
|
|
|
|
protected:
|
|
DockableCtrl& SetType(int type) { docktype = type; return *this;}
|
|
DockableCtrl& SetBase(DockBase* c) { dockbase = c; return *this;}
|
|
DockableCtrl& SetSizeHint(Size sz) { docksize = sz; return *this;}
|
|
DockableCtrl& SetSize(Size sz);
|
|
void ReSize();
|
|
|
|
private:
|
|
int dockalignment;
|
|
int dockstate;
|
|
int dockposition;
|
|
int docktype;
|
|
Size docksize;
|
|
DockBase* dockbase;
|
|
Image dockicon;
|
|
String dockname;
|
|
MenuBar dockmenu;
|
|
int dockdroptarget;
|
|
int dockdropstate;
|
|
|
|
protected:
|
|
bool haschildbar;
|
|
bool hasdragbar;
|
|
bool isdragged;
|
|
bool isdraggable;
|
|
|
|
friend class DockBase;
|
|
friend class PaneFrame;
|
|
friend class TabWindow;
|
|
friend class AutoHideBar;
|
|
|
|
public:
|
|
const DockCtrlChStyle::Style* style;
|
|
|
|
public:
|
|
virtual void Dock(int alignment, int state, int position, bool check = true) = 0;
|
|
virtual void FloatEx(Rect r) = 0;
|
|
virtual void Float() = 0;
|
|
virtual void Show() = 0;
|
|
virtual void Hide() = 0;
|
|
virtual void AutoHide() = 0;
|
|
virtual void Shut() = 0;
|
|
virtual void Menu() = 0;
|
|
virtual void Settings();
|
|
|
|
virtual void Serialize(Stream& s) = 0;
|
|
|
|
public:
|
|
virtual Rect GetCtrlRect() = 0;
|
|
virtual Size GetCtrlSize() = 0;
|
|
|
|
public:
|
|
void SetDropTarget(int target = DOCK_NONE, int state = STATE_SHUT) { dockdroptarget = target, dockdropstate = state; }
|
|
int GetDropTarget () { return dockdroptarget; }
|
|
int GetDropState () { return dockdropstate; }
|
|
bool HasDropTarget () { return (dockdroptarget != DOCK_NONE);}
|
|
bool IsDropTargetAvailable(Rect r, Point p) { return r.Contains(p); }
|
|
|
|
void ForbidDragAndDrop() { isdraggable = false; };
|
|
void PermitDragAndDrop() { isdraggable = true; };
|
|
|
|
protected:
|
|
void StartWindowDrag();
|
|
|
|
#if defined(PLATFORM_WIN32)
|
|
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
|
#elif defined(PLATFORM_X11)
|
|
virtual void EventProc(XWindow& w, XEvent *event);
|
|
#endif
|
|
|
|
protected:
|
|
virtual void OpenWindow(Rect& r);
|
|
virtual void OpenWindow(int x, int y, int cx, int cy);
|
|
virtual void ShutWindow();
|
|
virtual void ContextMenu();
|
|
virtual void OnShutWindow();
|
|
virtual void Layout();
|
|
virtual void Paint(Draw& d) { d.DrawRect(GetSize(), SColorFace()); }
|
|
public:
|
|
virtual void ShowDragBar() { hasdragbar = true; }
|
|
virtual void HideDragBar() { hasdragbar = false; }
|
|
virtual bool HasDragBar() { return hasdragbar; }
|
|
virtual bool HasChildBar() { return haschildbar; }
|
|
|
|
public:
|
|
DockableCtrl& AddChildBar(CtrlFrame& bar) { AddFrame(bar); haschildbar = true; return *this; }
|
|
DockableCtrl& Add(Ctrl& ctrl) { this << ctrl; return *this; }
|
|
DockableCtrl& operator<<(Ctrl& ctrl) { Add(ctrl); return *this; }
|
|
|
|
DockableCtrl();
|
|
~DockableCtrl();
|
|
};
|
|
|
|
//----------------------------------------------------------------------------------------------
|
|
|
|
class DockWindow : public DockableCtrl
|
|
{
|
|
public:
|
|
typedef DockWindow CLASSNAME;
|
|
|
|
DockWindow& AddMenuBar(MenuBar& bar);
|
|
DockWindow& AddToolBar(ToolBar& bar);
|
|
DockWindow& AddStatusBar(StatusBar& bar);
|
|
|
|
inline bool HasMenuBar () { return hasmenubar; }
|
|
inline bool HasToolBar () { return hastoolbar; }
|
|
inline bool HasStatusBar() { return hasstatusbar; }
|
|
|
|
virtual Rect GetCtrlRect();
|
|
virtual Size GetCtrlSize();
|
|
|
|
TabWindow* GetOwnerTab() { return ownertab; }
|
|
AutoHideBar* GetOwnerBar() { return ownerbar; }
|
|
|
|
DockWindow& SetOwnerTab(TabWindow* tabwindow) { ownertab = tabwindow; return *this; }
|
|
DockWindow& SetOwnerBar(AutoHideBar* hidebar) { ownerbar = hidebar; return *this; }
|
|
|
|
virtual void Serialize(Stream& s);
|
|
|
|
public:
|
|
virtual void Dock(int alignment, int state, int position, bool sizecheck = true);
|
|
virtual void FloatEx(Rect r);
|
|
virtual void Float();
|
|
virtual void Show();
|
|
virtual void Hide();
|
|
virtual void AutoHide();
|
|
virtual void Shut();
|
|
virtual void Menu();
|
|
|
|
public:
|
|
virtual void ShowDragBar();
|
|
virtual void HideDragBar();
|
|
virtual DockWindow& ShowDragBarButtons(bool b = true);
|
|
|
|
protected:
|
|
virtual void OnMenuButton ();
|
|
virtual void OnShutButton ();
|
|
virtual void OnAutoHideButton();
|
|
virtual void ChildMouseEvent(Ctrl *child, int event, Point p, int zdelta, dword keyflags);
|
|
virtual void MouseMove(Point p, dword keyflags);
|
|
virtual void Paint(Draw& d);
|
|
|
|
public:
|
|
virtual void DockWindowMenu(Bar& bar);
|
|
virtual void DockWindowDockMenu(Bar& bar);
|
|
|
|
private:
|
|
class DragBar : public DockCtrlCustomFrame
|
|
{
|
|
public:
|
|
typedef DragBar CLASSNAME;
|
|
void ShowButtons(bool b = true) { show = b; if(IsVisible()) Refresh(); }
|
|
void SetColor (const Color& c) { color = c; }
|
|
void SetOwner (DockWindow* w) { owner = w; }
|
|
DockWindow& GetOwner () { ASSERT(owner); return *owner; }
|
|
int GetWidth ();
|
|
int GetHeight();
|
|
|
|
virtual void Paint(Draw& d);
|
|
virtual void FrameAddSize(Size& sz);
|
|
|
|
private:
|
|
DockWindow* owner;
|
|
Color color;
|
|
bool show;
|
|
|
|
public:
|
|
DragBar();
|
|
};
|
|
|
|
struct DragBarButton : public Button
|
|
{
|
|
public:
|
|
void Paint(Draw& d);
|
|
Ctrl& SetImage(const Image& normal, const Image& highlighted, const Image& pushed);
|
|
private:
|
|
const DockCtrlChStyle::Style* style;
|
|
Image nimage;
|
|
Image himage;
|
|
Image pimage;
|
|
};
|
|
|
|
private:
|
|
bool hasmenubar;
|
|
bool hastoolbar;
|
|
bool hasstatusbar;
|
|
bool hasbarbuttons;
|
|
TabWindow* ownertab;
|
|
AutoHideBar* ownerbar;
|
|
MenuBar* menubar;
|
|
ToolBar* toolbar;
|
|
StatusBar* statusbar;
|
|
DragBar dragbar;
|
|
DragBarButton menubutton;
|
|
DragBarButton autohidebutton;
|
|
DragBarButton shutbutton;
|
|
friend class TabWindow;
|
|
|
|
public:
|
|
DockWindow& SetStyle(const DockCtrlChStyle::Style& s);
|
|
const DockCtrlChStyle::Style* GetStyle();
|
|
|
|
public:
|
|
DockWindow();
|
|
~DockWindow();
|
|
};
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------
|
|
|
|
class TabWindow : public DockWindow
|
|
{
|
|
public:
|
|
typedef TabWindow CLASSNAME;
|
|
|
|
void Attach(DockableCtrl& ctrl, int makeactive = false);
|
|
void Detach(DockableCtrl& ctrl);
|
|
void DetachAll();
|
|
|
|
TabWindow& SetGroup(String name) { groupname = name; groupwindow = true; return *this;}
|
|
void SetActive(int index);
|
|
void SetActive(DockableCtrl& ctrl);
|
|
DockableCtrl* GetActiveCtrl();
|
|
int GetActiveTab();
|
|
int ChildCount();
|
|
void StartTabAnimation();
|
|
void StopTabAnimation();
|
|
|
|
bool HasCtrlInRange();
|
|
bool HasTabbedDock();
|
|
bool IsGroupWindow() { return groupwindow; }
|
|
bool IsTabAnimating() { return animating; }
|
|
bool IsDestroyed() { return destroyed; }
|
|
|
|
TabInterface& GetTabs() { return tabs; }
|
|
DockableCtrl* GetChildAt(int position);
|
|
TabWindow* GetBaseTab();
|
|
int GetNestLevel() { return nestlevel; }
|
|
|
|
void SetNestLevel(int n);
|
|
TabWindow& SetLayout(int n) { if(tabs.IsChild()) RemoveFrame(tabs); AddFrame(tabs.SetLayout(n)); return *this; }
|
|
|
|
virtual void Serialize(Stream& s);
|
|
|
|
virtual void FloatEx(Rect r) { DockWindow::FloatEx(r); RefreshTabWindowLabel(*this); }
|
|
virtual void Float() { DockWindow::Float(); RefreshTabWindowLabel(*this); }
|
|
|
|
protected:
|
|
void OnMenuButton();
|
|
void OnShutButton();
|
|
void OnAutoHideButton();
|
|
virtual void OnShutWindow();
|
|
|
|
virtual void OnActiveTab();
|
|
virtual void OnTabClose(int id, DockableCtrl& ctrl);
|
|
virtual void OnTabDrag(int id, DockableCtrl& ctrl);
|
|
virtual void OnTabActive(int id, DockableCtrl& ctrl);
|
|
virtual void OnTabContextMenu(int id, DockableCtrl& ctrl);
|
|
|
|
virtual void Paint(Draw& d);
|
|
|
|
private:
|
|
void AttachNormal(DockableCtrl& ctrl, int makeactive = false);
|
|
void AttachNested(DockableCtrl& ctrl, int makeactive = false);
|
|
void Attach0(DockableCtrl& ctrl, int makeactive = false);
|
|
|
|
void RefreshTabWindowLabel(DockableCtrl& ctrl);
|
|
bool RemoveTabWindow();
|
|
void ReposChilds();
|
|
|
|
private:
|
|
int position;
|
|
int previous;
|
|
int nestlevel;
|
|
int childcount;
|
|
bool destroyed;
|
|
bool animating;
|
|
bool groupwindow;
|
|
String groupname;
|
|
Image animimage;
|
|
TabInterface tabs;
|
|
DockableCtrl* activectrl;
|
|
|
|
public:
|
|
TabWindow();
|
|
~TabWindow();
|
|
};
|
|
|
|
//----------------------------------------------------------------------------------------------
|
|
|
|
class AutoHideBar : public TabInterface
|
|
{
|
|
public:
|
|
typedef AutoHideBar CLASSNAME;
|
|
|
|
AutoHideBar& Attach(DockableCtrl& ctrl);
|
|
void Detach(DockableCtrl& ctrl);
|
|
|
|
void ShowBar();
|
|
void HideBar();
|
|
|
|
int GetSize() { return DockCtrlCustomFrame::size; }
|
|
void SetSize(int sz) { DockCtrlCustomFrame::size = sz; RefreshParentLayout(); }
|
|
|
|
DockableCtrl* GetChild(int position);
|
|
int GetCount();
|
|
|
|
protected:
|
|
|
|
virtual void FrameRemove();
|
|
virtual void FrameAdd(Ctrl& parent);
|
|
virtual void MouseMove(Point p, dword keysflags);
|
|
virtual void MouseLeave();
|
|
virtual void MouseEnter(Point p, dword keyflags);
|
|
|
|
void ShowWindow();
|
|
void HideWindow();
|
|
|
|
void OnHighlight();
|
|
void OnClose(int id, DockableCtrl& ctrl);
|
|
|
|
void AdjustSize(Rect &r, const Size &sz);
|
|
|
|
private:
|
|
struct PopupWindow : public Ctrl
|
|
{
|
|
Callback WhenEnter;
|
|
Callback WhenLeave;
|
|
virtual void ChildMouseEvent(Ctrl *child, int event, Point p, int zdelta, dword keyflags);
|
|
virtual void Paint(Draw& d) { Ctrl::Paint(d); }
|
|
PopupWindow() { BackPaint(); }
|
|
};
|
|
|
|
PopupWindow popup;
|
|
DockableCtrl* ctrl;
|
|
int childcount;
|
|
|
|
public:
|
|
const DockCtrlChStyle::Style* style;
|
|
AutoHideBar& SetStyle(const DockCtrlChStyle::Style& s) { style = &s; Refresh(); return *this; }
|
|
const DockCtrlChStyle::Style* GetStyle() { return style ? style : &DockCtrlChStyle::StyleDefault(); }
|
|
|
|
public:
|
|
AutoHideBar();
|
|
~AutoHideBar();
|
|
};
|
|
|
|
//----------------------------------------------------------------------------------------------
|
|
class PaneFrame : public CtrlFrame, private Ctrl
|
|
{
|
|
|
|
public:
|
|
typedef PaneFrame CLASSNAME;
|
|
|
|
PaneFrame& Attach(DockableCtrl& ctrl);
|
|
PaneFrame& Detach(DockableCtrl& ctrl);
|
|
|
|
void ShowFrame();
|
|
void ShowFrame(Size sz);
|
|
void HideFrame();
|
|
void LockFrame();
|
|
void UnlockFrame();
|
|
|
|
bool HasChild(DockableCtrl& ctrl);
|
|
DockableCtrl* GetChild(int position);
|
|
int GetCount();
|
|
Vector<TabWindow*>& GetTabWindows();
|
|
|
|
TabWindow* AddTabWindow();
|
|
void AddtoTabWindow(DockableCtrl& ctrl);
|
|
void RemovefromTabWindow(DockableCtrl& ctrl);
|
|
void RemoveTabWindows();
|
|
|
|
void RefreshTabWindowList();
|
|
|
|
private:
|
|
PaneFrame& AttachAsDock(DockableCtrl& ctrl);
|
|
PaneFrame& AttachAsTab(DockableCtrl& ctrl);
|
|
PaneFrame& AttachAsAuto(DockableCtrl& ctrl);
|
|
|
|
TabWindow* AddTabWindow(DockableCtrl& ctrl);
|
|
void RemoveTabWindow(TabWindow* tabwindow);
|
|
void RemoveTabWindow(int position);
|
|
void RemovefromTabWindow(int position);
|
|
TabWindow* FindTabWindow(int position);
|
|
TabWindow* FindTabWindow(DockableCtrl& ctrl);
|
|
|
|
inline TabWindow* GetActiveTabWindow();
|
|
void SetActiveTabWindow(TabWindow* tabwindow);
|
|
bool HasTabWindow(TabWindow* tabwindow);
|
|
|
|
|
|
private:
|
|
PaneSplitter dockcontainer;
|
|
AutoHideBar hidebar;
|
|
TabWindow* activetabwindow;
|
|
Vector<TabWindow*> tabwindows;
|
|
|
|
public:
|
|
virtual void FrameAdd(Ctrl& parent);
|
|
virtual void FrameRemove();
|
|
virtual void FrameAddSize(Size& sz);
|
|
virtual void FrameLayout(Rect& r);
|
|
|
|
virtual void Paint(Draw& draw);
|
|
virtual void LeftDown(Point p, dword keyflags);
|
|
virtual void MouseMove(Point p, dword keyflags);
|
|
virtual void LeftUp(Point p, dword keyflags);
|
|
virtual Image CursorImage(Point p, dword keyflags);
|
|
|
|
private:
|
|
Point ref;
|
|
Size parentsize;
|
|
int type, minsize, sizemin, maxsize, stdsize;
|
|
int size, size0;
|
|
int dndpos;
|
|
bool created;
|
|
bool locked;
|
|
int BoundSize();
|
|
DockBase* base;
|
|
int ncount;
|
|
|
|
public:
|
|
enum { LEFT, TOP, RIGHT, BOTTOM };
|
|
|
|
PaneFrame& SetLayout(DockBase* basectrl, int alignment, int _maxsize);
|
|
|
|
PaneFrame& Set(Ctrl& c, int size, int type);
|
|
PaneFrame& Left(Ctrl& c, int size) { return Set(c, size, LEFT); }
|
|
PaneFrame& Top(Ctrl& c, int size) { return Set(c, size, TOP); }
|
|
PaneFrame& Right(Ctrl& c, int size) { return Set(c, size, RIGHT); }
|
|
PaneFrame& Bottom(Ctrl& c, int size) { return Set(c, size, BOTTOM); }
|
|
|
|
PaneFrame& MinSize(int sz) { minsize = sz; return *this; }
|
|
PaneFrame& MaxSize(int sz) { maxsize = sz; return *this; }
|
|
PaneFrame& SizeMin(int sz) { sizemin = sz; return *this; }
|
|
|
|
PaneFrame& Vert() { dockcontainer.Vert(); return *this; }
|
|
PaneFrame& Horz() { dockcontainer.Horz(); return *this; }
|
|
PaneFrame& RefreshPaneFrame() { RefreshParentLayout(); dockcontainer.Layout(); return *this; }
|
|
|
|
PaneFrame& SetBase(DockBase* ctrlbase) { base = ctrlbase; return *this; }
|
|
DockBase& GetBase() { ASSERT(base); return *base; }
|
|
|
|
int GetType() const { return type; }
|
|
int GetSize() const { return size; }
|
|
int GetPaneMaxSize() const { return maxsize; }
|
|
void SetSize(int sz) { size = sz; RefreshParentLayout(); }
|
|
|
|
Rect GetScreenView() { return Ctrl::GetScreenView(); }
|
|
Rect GetScreenRect() { return Ctrl::GetScreenRect(); }
|
|
|
|
void Enable() { Ctrl::Enable(); }
|
|
void Disable() { Ctrl::Disable(); }
|
|
void Show(bool show = true) { Ctrl::Show(show); }
|
|
void Hide() { Ctrl::Hide(); }
|
|
|
|
bool IsShown() { return Ctrl::IsShown(); }
|
|
bool IsEnabled() { return Ctrl::IsEnabled(); }
|
|
bool IsCreated() { return created; }
|
|
bool IsLocked() { return locked; }
|
|
|
|
public:
|
|
PaneFrame();
|
|
~PaneFrame();
|
|
|
|
//===============================================
|
|
// DockPane: Drag-n-Drop related methods.
|
|
//===============================================
|
|
|
|
public:
|
|
bool HasCtrlInRange(DockableCtrl& ctrl, Point p);
|
|
|
|
void StartPaneFrameAnimation(DockableCtrl& ctrl, int position);
|
|
void StartTabWindowAnimation(DockableCtrl& ctrl, int position);
|
|
void StopPaneFrameAnimation();
|
|
void StopTabWindowAnimation();
|
|
|
|
private:
|
|
bool CalculateCtrlRange(DockableCtrl& t, Ctrl& c, Point p);
|
|
bool CalculateEmptyRange(Ctrl& c, Point p);
|
|
|
|
public:
|
|
void DnDSourceinRange() { _dndsource = true; }
|
|
void DnDSourceoutofRange() { _dndsource = false; }
|
|
bool DnDHasSource() const { return _dndsource; }
|
|
|
|
void DnDAnimate(int position = dnd_none);
|
|
|
|
void DoDropAnimation(int command = ANIMATE_ALL, int position = dnd_none, DockableCtrl* dock = NULL);
|
|
bool DnDIsAnimating() const { return _dndanim; }
|
|
|
|
void DnDAnimStart() { _dndanim = true; }
|
|
void DnDAnimStop() { _dndanim = false; }
|
|
|
|
public:
|
|
enum { dnd_first = 1, dnd_last = 2, dnd_tab = 128, dnd_none = -1 };
|
|
enum { TAB_ANIMATION_START, TAB_ANIMATION_STOP, PANE_ANIMATION_START, PANE_ANIMATION_STOP, ANIMATE_ALL};
|
|
|
|
private:
|
|
bool _dndsource;
|
|
bool _dndanim;
|
|
int _dndposition;
|
|
int _dndtype;
|
|
};
|
|
|
|
//----------------------------------------------------------------------------------------------
|
|
|
|
class DockBase : public TopWindow
|
|
{
|
|
public:
|
|
typedef DockBase CLASSNAME;
|
|
|
|
Ctrl& Dock(DockableCtrl& ctrl);
|
|
DockableCtrl& Tabify(DockableCtrl& ctrl1, DockableCtrl& ctrl2);
|
|
DockableCtrl& Tabify(String groupname, DockableCtrl& ctrl1, DockableCtrl& ctrl2);
|
|
DockableCtrl& Tabify(DockableCtrl& ctrl1, DockableCtrl& ctrl2, DockableCtrl& ctrl3, DockableCtrl& ctrl4);
|
|
DockableCtrl& Tabify(String groupname, DockableCtrl& ctrl1, DockableCtrl& ctrl2, DockableCtrl& ctrl3, DockableCtrl& ctrl4);
|
|
|
|
void TabifyGroupAndDock(String groupname, int alignment);
|
|
void TabifyGroupAndAutoHide(String groupname, int alignment);
|
|
void TabifyGroupAndFloat(String groupname);
|
|
|
|
void AllowAll();
|
|
void AllowLeft();
|
|
void AllowTop();
|
|
void AllowRight();
|
|
void AllowBottom();
|
|
void AllowLeftRight();
|
|
void AllowTopBottom();
|
|
void AllowLeftTop();
|
|
void AllowRightBottom();
|
|
void AllowLeftBottom();
|
|
void AllowTopRight();
|
|
|
|
void AllowNestedTabbing(bool b = true);
|
|
|
|
void ShowLeftPane(bool b = true);
|
|
void ShowTopPane(bool b = true);
|
|
void ShowRightPane(bool b = true);
|
|
void ShowBottomPane(bool b = true);
|
|
|
|
Ctrl& GetBase() { return (Ctrl&) *this; }
|
|
PaneFrame& GetPaneFrame(int alignment) { return pane[alignment]; }
|
|
AutoHideBar& GetHideBar(int alignment) { return hide[alignment]; }
|
|
|
|
void ControlPanel();
|
|
void RefreshWidgetLayout();
|
|
void ResetWidgetLayout();
|
|
|
|
void SetKey(dword key) { hotkey = key; }
|
|
dword GetKey() { return hotkey;}
|
|
|
|
void AddWidgetLayout(String name, DockableCtrl& ctrl, int alignment, int state, int position = 0);
|
|
void SetWidgetLayout(String name);
|
|
void SetWidgetLayout(int index);
|
|
|
|
virtual bool Key(dword key, int count);
|
|
virtual void Serialize(Stream& s);
|
|
|
|
protected:
|
|
void InitFrameWork();
|
|
void InitDefaultLayout();
|
|
void InitFrameWorkSettings();
|
|
|
|
void FrameWorkReady(bool b = true) { isready = b; }
|
|
bool IsFrameWorkReady() { return isready; }
|
|
|
|
private:
|
|
void Attach(DockableCtrl& ctrl);
|
|
void Attach(DockableCtrl* ctrl);
|
|
void Detach(DockableCtrl& ctrl);
|
|
void Detach(DockableCtrl* ctrl);
|
|
void DoDragAndDrop(DockableCtrl& ctrl, Point p, Size sz);
|
|
|
|
private:
|
|
struct CtrlRecord : Moveable<CtrlRecord>
|
|
{
|
|
DockableCtrl* ctrl;
|
|
int id;
|
|
CtrlRecord() { ctrl = NULL; id = 0; }
|
|
};
|
|
|
|
void AddCtrlRecord(DockableCtrl& ctrl);
|
|
void RemoveCtrlRecord(DockableCtrl& ctrl);
|
|
void DeleteCtrlRecords();
|
|
CtrlRecord* GetCtrlRecord(DockableCtrl& ctrl);
|
|
CtrlRecord* GetCtrlRecordFromIndex(int index);
|
|
CtrlRecord* GetCtrlRecordFromGroup(String group);
|
|
CtrlRecord* GetCtrlRecordFromId(int id);
|
|
Vector<CtrlRecord*>& GetCtrlRecords() { return ctrls; };
|
|
|
|
DockableCtrl* GetDockedWindowFromIndex(int index);
|
|
TabWindow* GetTabWindowFromIndex(int index);
|
|
int GetTabWindowCount();
|
|
int GetDockedWindowCount();
|
|
|
|
// TabWindow* AddTabWindow();
|
|
// TabWindow* AddTabWindow(DockableCtrl ctrl);
|
|
void RemoveTabWindows();
|
|
void RefreshTabWindowList();
|
|
Vector<TabWindow*>& GetTabWindows();
|
|
|
|
void SerializeLayout(Stream& s, bool deflay = false);
|
|
|
|
protected:
|
|
void NewWidgetLayout(String name);
|
|
void DelWidgetLayout(String name);
|
|
int AddWidgetLayout(String name);
|
|
|
|
void NewWidgetGroup(String name, bool predefined = false);
|
|
bool AddWidgettoGroup(String name, DockableCtrl& ctrl);
|
|
bool AddWidgettoGroup(String name, int id);
|
|
bool DeleteWidgetfromGroup(String name, DockableCtrl& ctrl);
|
|
bool DeleteWidgetfromGroup(String name, int id);
|
|
int AddWidgetGroup(String name);
|
|
void DeleteWidgetGroup(String name);
|
|
Vector<int>& FindWidgetGroup(String name);
|
|
bool FindWidgetinGroup(String name, int id);
|
|
|
|
private:
|
|
void GroupDrop(int parent, int ii, PasteClip& d);
|
|
void GroupDrag();
|
|
void GroupSelect();
|
|
void GroupMenu(Bar& bar);
|
|
void GroupDockMenu(Bar& bar, int command);
|
|
void GroupTabifyMenu(Bar& bar, int command);
|
|
void GroupMenuAction(String name, int command, int alignment);
|
|
|
|
void RefreshGroups();
|
|
|
|
DockableCtrl& TabifyGroup(String name);
|
|
|
|
void SetSkin(int index);
|
|
|
|
private:
|
|
int skinindex;
|
|
int layoutindex;
|
|
bool tabsicons;
|
|
bool tabsclose;
|
|
bool tabsnested;
|
|
bool tabsautoalign;
|
|
bool autohideicons;
|
|
bool autohideclose;
|
|
bool isready;
|
|
bool IsSideAllowed(int i) { return AllowedSides[i]; }
|
|
bool AllowedSides[4];
|
|
|
|
private:
|
|
void OnPanelAction();
|
|
void OnSelectSkin ();
|
|
void OnSelectLayout();
|
|
void OnAddNewLayout();
|
|
void OnDeleteLayout();
|
|
void OnAddNewGroup();
|
|
void OnDeleteGroup();
|
|
void RefreshPanel();
|
|
void CleanUp();
|
|
|
|
private:
|
|
Size panesize;
|
|
PaneFrame pane[4];
|
|
AutoHideBar hide[4];
|
|
dword hotkey;
|
|
String predefinedlayout;
|
|
String predefinedgroup;
|
|
String activegroup;
|
|
|
|
WithControlPanelLayout<TopWindow> controlpanel;
|
|
WithWidgetListLayout<ParentCtrl> listtab;
|
|
WithWidgetGroupsLayout<ParentCtrl> grouptab;
|
|
|
|
TreeCtrl grouptree;
|
|
TabCtrl paneltab;
|
|
|
|
Vector<TabWindow*> tabwindows;
|
|
Array<ImageCtrl*> panelicons;
|
|
ArrayMap<String, String> layouts;
|
|
ArrayMap<String, Vector<int> > groups;
|
|
Vector<CtrlRecord*> ctrls;
|
|
|
|
friend class DockableCtrl;
|
|
friend class DockWindow;
|
|
friend class TabWindow;
|
|
friend class PaneFrame;
|
|
|
|
public:
|
|
const DockCtrlChStyle::Style* style;
|
|
DockBase& SetStyle(const DockCtrlChStyle::Style& s);
|
|
const DockCtrlChStyle::Style* GetStyle() { return style ? style : &DockCtrlChStyle::StyleDefault(); }
|
|
|
|
public:
|
|
DockBase& WidgetGroup(String name);
|
|
DockBase& operator%(DockableCtrl& ctrl);
|
|
DockBase& WidgetLayout(String name);
|
|
DockBase& operator/(DockableCtrl& ctrl);
|
|
|
|
public:
|
|
DockBase();
|
|
~DockBase();
|
|
};
|
|
|
|
class DockCtrl : public DockBase
|
|
{
|
|
public:
|
|
typedef DockCtrl CLASSNAME;
|
|
virtual void InitDockCtrl() {}
|
|
virtual void InitCustomLayouts() {}
|
|
void State(int reason);
|
|
void Serialize(Stream& s) { DockBase::Serialize(s); }
|
|
private:
|
|
bool ctrlinit;
|
|
|
|
public:
|
|
DockCtrl();
|
|
~DockCtrl();
|
|
};
|
|
|
|
#endif
|