TabBar.h

IƱaki Zabala, 06/19/2020 04:34 PM

Download (17 KB)

 
1
#ifndef _TabBar_TabBar_h_
2
#define _TabBar_TabBar_h_
3

    
4
#include <CtrlLib/CtrlLib.h>
5

    
6
#define IMAGECLASS TabBarImg
7
#define IMAGEFILE <TabBar/TabBar.iml>
8
#include <Draw/iml_header.h>
9

    
10
namespace Upp {
11

    
12
//#define TABBAR_DEBUG
13

    
14
struct AlignedFrame : FrameCtrl<Ctrl>
15
{
16
        int layout;
17
        int framesize;
18
        int border;
19
public:        
20
        enum
21
        {
22
                LEFT = 0,
23
                TOP = 1,
24
                RIGHT = 2,
25
                BOTTOM = 3
26
        };
27
        
28
        AlignedFrame() : layout(TOP), framesize(0), border(0) {}
29
        
30
        virtual void FrameAddSize(Size& sz);
31
        virtual void FramePaint(Draw& w, const Rect& r);
32
        virtual void FrameLayout(Rect& r);
33
        
34
        bool                  IsVert() const        { return (layout & 1) == 0; }
35
        bool                  IsHorz() const        { return layout & 1; }
36
        bool                  IsTL() const                { return layout < 2; }
37
        bool                  IsBR() const                { return layout >= 2; }
38
        
39
        AlignedFrame& SetAlign(int align) { layout = align; FrameSet(); RefreshParentLayout(); return *this; }
40
        AlignedFrame& SetLeft()                { return SetAlign(LEFT); }
41
        AlignedFrame& SetTop()                { return SetAlign(TOP); }
42
        AlignedFrame& SetRight()        { return SetAlign(RIGHT); }
43
        AlignedFrame& SetBottom()        { return SetAlign(BOTTOM); }
44
        AlignedFrame& SetFrameSize(int sz, bool refresh = true);
45
                
46
        int                   GetAlign() const                { return layout; }
47
        int                          GetFrameSize() const         { return framesize; }
48
        int                          GetBorder() const                { return border; }
49
protected:
50
        void Fix(Size& sz);
51
        void Fix(Point& p);
52
        Size Fixed(const Size& sz);
53
        Point Fixed(const Point& p);
54
        
55
        bool                  HasBorder()                                { return border >= 0; }
56
        AlignedFrame& SetBorder(int _border)        { border = _border; return *this; }
57
        
58
        virtual        void  FrameSet()                                { }
59
};
60

    
61
class TabScrollBar : public AlignedFrame
62
{
63
        private:
64
                int total;
65
                double pos, ps;
66
                int new_pos;
67
                int old_pos;
68
                double start_pos;
69
                double size;
70
                double cs, ics;
71
                virtual void UpdatePos(bool update = true);
72
                void RefreshScroll();
73
                bool ready;
74
                Size sz;
75
        public:
76
                TabScrollBar();
77

    
78
                virtual void Paint(Draw& w);
79
                virtual void LeftDown(Point p, dword keyflags);
80
                virtual void LeftUp(Point p, dword keyflags);
81
                virtual void MouseMove(Point p, dword keyflags);
82
                virtual void MouseWheel(Point p, int zdelta, dword keyflags);
83
                virtual void Layout();
84

    
85
                int  GetPos() const;
86
                void SetPos(int p, bool dontscale = false);
87
                void AddPos(int p, bool dontscale = false);
88
                int  GetTotal() const;
89
                void AddTotal(int t);
90
                void SetTotal(int t);
91
                void GoEnd();
92
                void GoBegin();
93
                void Clear();
94
                void Set(const TabScrollBar& t);
95
                bool IsScrollable() const;
96
                Event<>  WhenScroll;
97
};
98

    
99
class TabBar : public AlignedFrame
100
{
101
public:
102
        struct Style : public TabCtrl::Style
103
        {
104
                Image crosses[3];
105
                Value group_separators[2];
106
                
107
                Style &        Write() const               { return *static_cast<Style *>(&TabCtrl::Style::Write()); }
108
                
109
                Style&  DefaultCrosses();
110
                Style&  Variant1Crosses();
111
                Style&  Variant2Crosses();
112
                
113
                Style&  DefaultGroupSeparators();
114
                Style&  GroupSeparators(Value horz, Value vert);
115
                Style&  NoGroupSeparators()                        { return GroupSeparators(Value(), Value()); }
116
        };
117
        
118
        TabBar& SetStyle(const TabBar::Style& s);
119
        
120
protected:
121
        enum {
122
                TB_MARGIN = 5,
123
                TB_SPACE = 10,
124
                TB_SBHEIGHT = 4,
125
                TB_SBSEPARATOR = 1,
126
                TB_ICON = 16,
127
                TB_SPACEICON = 3
128
        };
129
        const Style *style;
130
        
131
public:
132
        struct TabItem : Moveable<TabItem> {
133
                int x;
134
                int y;
135
                Size size;
136
                WString text;
137
                Color ink;
138
                Font font;
139
                Image img;
140
                int side;
141
                bool clickable;
142
                bool cross;
143
                int stacked_tab;
144
                
145
                TabItem& Clickable(bool b = true) { clickable = b; return *this; }
146
                void Clear();
147
                
148
                TabItem() : side(LEFT), clickable(false), cross(false), stacked_tab(-1) {}
149
                String ToString() const {
150
                        return Format("%d, %d - %s", x, y, text);
151
                }
152
        };
153
        
154
        struct Tab : Moveable<Tab> {
155
                int id;
156
                
157
                Image  img;
158
                Color  col;
159
                Value  key;
160
                Value  value;
161
                String group;
162
                
163
                String  stackid;
164
                int     stack;
165

    
166
                bool visible;
167

    
168
                Point pos;
169
                Size  size;
170
                
171
                Point cross_pos;
172
                Size  cross_size;
173
                
174
                Point tab_pos;
175
                Size  tab_size;
176
                
177
                String ToString() const
178
                {
179
                        return Format("Key: %`, Group: %`, StackId: %`, Stack: %d", key, group, stackid, stack);
180
                }
181
                
182
                virtual void Serialize(Stream& s);
183
                
184
                Array<TabItem> items;
185
                int itn;
186
                
187
                Tab();
188
                Tab(const Tab& t) { Set(t); }
189
                
190
                void Set(const Tab& t);
191
                
192
                bool HasMouse(const Point& p) const;
193
                bool HasMouseCross(const Point& p) const;
194
                bool HasIcon() const                                                { return !img.IsEmpty(); }
195
                int  Right() const                          { return pos.x + size.cx; }
196
                
197
                TabItem& AddItem();
198
                void Clear();
199
                TabItem& AddValue(const Value& q, const Font& font = StdFont(), const Color& ink = SColorText);
200
                TabItem& AddText(const WString& s, const Font& font = StdFont(), const Color& ink = SColorText);
201
                TabItem& AddImage(const Image& img, int side = LEFT);
202
                TabItem& AddSpace(int space = 5, int side = LEFT);
203
                
204
                virtual ~Tab() {}
205
        };
206
        
207
        // Tab sorting structures
208
        struct TabSort {
209
                virtual bool operator()(const Tab& a, const Tab& b) const = 0;
210
        };
211
        struct TabGroupSort : public TabSort {
212
                virtual bool operator()(const Tab& a, const Tab& b) const { return a.group < b.group; }
213
        };
214
protected:
215
        struct Group : Moveable<Group> {
216
                Group()        {}
217
                String name;
218
                int active;
219
                int count;
220
                int first;
221
                int last;
222
                virtual void Serialize(Stream& s);
223
                String ToString() const { return Format("%s - %d", name, count); }
224
                
225
                virtual ~Group() {}
226
        };
227

    
228
        struct TabValueSort : public TabSort {
229
                virtual bool operator()(const Tab& a, const Tab& b) const { return (*vo)(a.value, b.value); }
230
                const ValueOrder *vo;
231
        };
232
        struct TabKeySort : public TabSort {
233
                virtual bool operator()(const Tab& a, const Tab& b) const { return (*vo)(a.key, b.key); }
234
                const ValueOrder *vo;
235
        };
236
        
237
protected:
238
        TabScrollBar    sc;
239
        
240
        Array<Group>    groups;
241
        Array<Tab>      tabs;
242
        Array<int>      separators;
243
        int             active;
244
        int             id;
245

    
246
        int highlight;
247
        int drag_highlight;
248
        int target;
249
        int cross;
250
        bool crosses;
251
        int crosses_side;
252
        bool isctrl;
253
        bool isdrag;
254
        bool grouping;
255
        bool autoscrollhide;
256
        bool nosel;
257
        bool nohl;
258
        bool inactivedisabled;
259
        bool stacking;
260
        bool stacksort;
261
        bool groupsort;
262
        bool groupseps;
263
        bool tabsort;
264
        bool allownullcursor;
265
        bool icons;
266
        bool contextmenu;
267
        int mintabcount;
268
        Point mouse, oldp;
269
        int group;
270
        const Display *display;
271
        Image dragtab;
272
        int stackcount;
273
        int scrollbar_sz;
274
        bool allowreorder;
275

    
276
        TabSort *tabsorter;
277
        TabSort *groupsorter;
278
        TabSort *stacksorter;
279
        TabValueSort valuesorter_inst;
280
        TabKeySort          keysorter_inst;
281
        TabValueSort stacksorter_inst;
282

    
283
        void    PaintTab(Draw& w, const Size& sz, int i, bool enable, bool dragsample = false);
284
        
285
        int          TabPos(const String& g, bool& first, int i, int j, bool inactive);        
286
        void    ShowScrollbarFrame(bool b);
287
        void         SyncScrollBar(bool synctotal = true);
288
        void         Scroll();
289

    
290
        int          FindId(int id) const;
291
        int          GetNext(int n, bool drag = false) const;
292
        int          GetPrev(int n, bool drag = false) const;
293

    
294
        int         GetWidth(int n);
295
        int         GetExtraWidth(int n);
296
        int         GetWidth() const;
297
        int         GetHeight(bool scrollbar = true) const;
298

    
299
        bool        SetCursor0(int n, bool action = false);
300

    
301
        void         DoStacking();
302
        void         DoUnstacking();
303
        void         InsertIntoStack(Tab& t, int ix);
304
        int          GetStackCount(int stackix) const;
305
        int          FindStackHead(int stackix) const;
306
        int          FindStackTail(int stackix) const;
307
        bool         IsStackHead(int n) const;
308
        bool         IsStackTail(int n) const;
309
        int         SetStackHead(Tab& t);
310
        void         CycleTabStack(int head, int n);
311
        int         CycleTabStack(int n);
312
                
313
        int           GetNextId();
314
        int           GetScrollPos()                                 { return sc.GetPos(); }                
315
        
316
        int GetStyleHeight() const;
317
        static Image AlignImage(int align, const Image& img);
318
        static Value AlignValue(int align, const Value& v, const Size& isz);
319

    
320
        using Ctrl::GetStdSize;
321
        using Ctrl::Close;
322
public:
323
        enum { JumpDirLeft, JumpDirRight };
324

    
325
        struct JumpStack : Moveable< JumpStack > {
326
                int        All;
327
                int        Rest;
328
                int        jump_direct;
329

    
330
                void Reset()                          { All = 0; Rest = 0; jump_direct = JumpDirLeft; }
331
                bool IsReset() const                  { return ( All == 0 ); }
332
                bool IsFull() const                   { return ( All == Rest ); }
333
                void Activate( int N, int jd )        { All = N; Rest = N; jump_direct = jd; }
334

    
335
                JumpStack() { Reset(); }
336
        };
337

    
338
        JumpStack jump_stack;
339
        int  GetTabLR( int jd );
340
        int  GetTabStackLR( int jd );
341
        int  GetLR( int c, int jd );
342
        
343
protected:
344
        virtual void Paint(Draw& w);
345
        virtual void LeftDown(Point p, dword keysflags);
346
        virtual void LeftUp(Point p, dword keysflags);
347
        virtual void LeftDouble(Point p, dword keysflags);
348
        virtual void RightDown(Point p, dword keyflags);
349
        virtual void MiddleDown(Point p, dword keyflags);
350
        virtual void MiddleUp(Point p, dword keyflags);
351
        virtual void MouseMove(Point p, dword keysflags);
352
        virtual void MouseLeave();
353
        virtual void DragAndDrop(Point p, PasteClip& d);
354
        virtual void LeftDrag(Point p, dword keyflags);
355
        virtual void DragEnter();
356
        virtual void DragLeave();
357
        virtual void DragRepeat(Point p);
358
        virtual void CancelMode();
359
        virtual void MouseWheel(Point p, int zdelta, dword keyflags);
360
        virtual void FrameSet();
361
        virtual void Layout();
362

    
363
        // Mouse handling/tab positioning
364
        Point AdjustMouse(Point const &p) const;
365
        bool ProcessMouse(int i, const Point& p);
366
        bool ProcessStackMouse(int i, const Point& p);
367
        void SetHighlight(int n);
368
        int  GetTargetTab(Point p);        
369
        void Repos();
370
        Size GetBarSize(Size ctrlsz) const;
371
        Rect GetClientArea() const;
372
        
373
        // Grouping
374
        void MakeGroups();
375
        int  FindGroup(const String& g) const;
376
        void CloseAll(int exception, int last_closed = 0);
377
        void GoGrouping(int n);
378
        void DoGrouping(int n);
379
        void DoCloseGroup(int n);
380
        void NewGroup(const String& name);
381
        void DoTabSort(TabSort& sort);
382
        void SortTabs0();
383
        void SortStack(int stackix);
384
        void SortStack(int stackix, int head, int tail);
385

    
386
        void CloseGroup();
387
        
388
        // Insertion without repos/refresh - for batch actions
389
        int InsertKey0(int ix, const Value& key, const Value& value, Image icon = Null, String group = Null);
390
        
391
        // Sub-class Paint override
392
        void PaintTabItems(Tab& t, Draw &w, const Rect& rn, int align);
393
        virtual void ComposeTab(Tab& tab, const Font &font, Color ink, int style);
394
        virtual void ComposeStackedTab(Tab& tab, const Tab& stacked_tab, const Font& font, Color ink, int style);
395
        virtual Size GetStdSize(const Tab& t); 
396
        virtual Size GetStackedSize(const Tab& t);
397
        Size                  GetStdSize(const Value& v); 
398
        
399
        // Paint helpers
400
        int                GetTextAngle();
401
        Point        GetTextPosition(int align, const Rect& r, int cy, int space) const;
402
        Point   GetImagePosition(int align, const Rect& r, int cx, int cy, int space, int side, int offset = 2) const;
403
        bool        PaintIcons()                                                                         { return icons; }
404
                
405
        // Sorting/Stacking overriddes
406
        virtual String                 GetStackId(const Tab& a)                        { return a.group; }
407
        // For sub-classes to recieve cursor changes without using WhenAction
408
        virtual void CursorChanged() { }
409
        // for sub-classes to receive tab closes without using WhenClose
410
        virtual void TabClosed(Value key) { }
411
        
412
        bool IsCancelClose(int id);
413
        bool IsCancelCloseAll(int exception, int last_closed = 0);
414
        
415
public:
416
        typedef TabBar CLASSNAME;
417

    
418
        Event<>                                          WhenHighlight;                // Executed on tab mouse-over
419
        Event<>                                          WhenLeftDouble;                // Executed on left-button double-click (clicked tab will be the active tab)
420
        Gate<Value>                                 CancelClose;                 // Return true to cancel action. Parameter: Key of closed tab
421
        Event<Value>                                WhenClose;                         // Executed before tab closing. Parameter: Key of closed tab
422
        Gate<>                                                 CancelCloseAll;                // Return true to cancel action;
423
        Event<>                                           WhenCloseAll;                // Executed before 'Close All' action
424
        Gate<ValueArray>                     CancelCloseSome;        // Return true to cancel action (executed with list of closing tabs)
425
        Event<ValueArray>                    WhenCloseSome;                // Executed before any 'Close' action (with list of closing tabs)
426
        Gate<int, int>                                CancelDragAndDrop;        // Return true to cancel drag and drop from tab to tab
427

    
428
        TabBar();
429
        TabBar& CopyBaseSettings(const TabBar& src);
430
        void    Set(const TabBar& t);
431
        TabBar& Add(const Value& value, Image icon = Null, String group = Null, bool make_active = false);
432
        TabBar& Insert(int ix, const Value& value, Image icon = Null, String group = Null, bool make_active = false);
433
        
434
        TabBar& AddKey(const Value& key, const Value& value, Image icon = Null, String group = Null, bool make_active = false);
435
        TabBar& InsertKey(int ix, const Value& key, const Value& value, Image icon = Null, String group = Null, bool make_active = false);
436
        
437
        void         CloseForce(int n, bool action = true);
438
        void         Close(int n, bool action = true);
439
        void         CloseKey(const Value& key);
440
        void         Clear();
441

    
442
        TabBar& Crosses(bool b = true, int side = RIGHT);
443
        TabBar& Stacking(bool b = true);
444
        TabBar& Grouping(bool b = true);
445
        TabBar& ContextMenu(bool b = true);
446
        TabBar& GroupSeparators(bool b = true);
447
        TabBar& AutoScrollHide(bool b = true);
448
        TabBar& InactiveDisabled(bool b = true);
449
        TabBar& AllowNullCursor(bool b = true);
450
        TabBar& Icons(bool v = true);
451

    
452
        TabBar& SortTabs(bool b = true);
453
        TabBar& SortTabsOnce();
454
        TabBar& SortTabsOnce(TabSort& sort);
455
        TabBar& SortTabs(TabSort& sort);
456

    
457
        TabBar& SortTabValues(ValueOrder& sort);
458
        TabBar& SortTabValuesOnce(ValueOrder& sort);
459
        TabBar& SortTabKeys(ValueOrder& sort);
460
        TabBar& SortTabKeysOnce(ValueOrder& sort);
461
        
462
        TabBar& SortGroups(bool b = true);
463
        TabBar& SortGroupsOnce();
464
        TabBar& SortGroupsOnce(TabSort& sort);
465
        TabBar& SortGroups(TabSort& sort);
466

    
467
        TabBar& SortStacks(bool b = true);
468
        TabBar& SortStacksOnce();
469
        TabBar& SortStacksOnce(TabSort& sort);
470
        TabBar& SortStacks(TabSort& sort);
471

    
472
        TabBar& SortStacks(ValueOrder& sort);
473

    
474
        bool        IsValueSort() const                                { return tabsort; }
475
        bool        IsGroupSort() const                                { return groupsort; }
476
        bool        IsStackSort() const                                { return stacksort; }
477

    
478
        TabBar&        AllowReorder(bool v = true)                                { allowreorder = v; return *this; }
479
        
480
        bool        IsGrouping() const                                { return grouping; }
481
        bool        HasGroupSeparators() const                { return separators.GetCount(); }
482
        bool        IsStacking() const                                { return stacking; }
483
        bool        IsShowInactive() const                        { return inactivedisabled; }
484
        
485
        TabBar& NeverEmpty()                                        { return MinTabCount(1); }
486
        TabBar& MinTabCount(int cnt)                        { mintabcount = max(cnt, 0); Refresh(); return *this; }
487
        
488
        TabBar& SetDisplay(const Display& d)         { display =& d; Refresh(); return *this; }
489
        TabBar& SetBorder(int border)           { AlignedFrame::SetBorder(border); return *this; }
490
        int         FindKey(const Value& v) const;
491
        int         FindValue(const Value& v) const;
492
        
493
        Value          GetKey(int n) const                                { ASSERT(n >= 0 && n < tabs.GetCount()); return tabs[n].key;}
494
        Value          GetValue(int n) const                        { ASSERT(n >= 0 && n < tabs.GetCount()); return tabs[n].value;}
495
        Value          Get(const Value& key) const                { return GetValue(FindKey(key)); }
496
        void        Set(int n, const Value& newkey, const Value& newvalue);
497
        void        Set(int n, const Value& newkey, const Value& newvalue, Image icon);
498
        void         SetValue(const Value &key, const Value &newvalue);
499
        void         SetValue(int n, const Value &newvalue);
500
        void         SetKey(int n, const Value &newkey);
501
        void        SetIcon(int n, Image icon);
502
        void         SetTabGroup(int n, const String& group);
503

    
504
        void    SetColor(int n, Color c);
505
        
506
        const Tab& operator[] (int n) const     { return tabs[n]; }
507
        
508
        virtual Value         GetData() const;
509
        virtual void         SetData(const Value& key);
510
        
511
        String         GetGroupName() const                      { return (group == 0) ? Null : groups[group].name; }
512
        String         GetGroupName(int i) const                { return groups[i].name;           }
513
        int          SetGroup(const String& s)           { DoGrouping(max(0, FindGroup(s))); return group; }
514
        int          SetGroup(int c)                     { DoGrouping(c); return group;     }
515
        int          GetGroup() const                    { return group;                       }
516
        int         GetGroupCount() const                        { return groups.GetCount();           }
517
        void         SetGroupActive(int id)              { groups[group].active = id;   }
518
        int          GetGroupActive() const              { return groups[group].active; }
519
        int          GetFirst() const                    { return groups[group].first;  }
520
        int          GetLast() const                     { return groups[group].last;   }
521
        bool         IsGroupAll() const                  { return group == 0;           }                        
522
        
523
        int            GetCursor() const                                 { return active; }
524
        bool           HasCursor() const                                { return active >= 0; }
525
        int                   GetHighlight() const                         { return highlight; }
526
        bool           HasHighlight() const                        { return highlight >= 0; }
527
        int            GetCount() const                                 { return tabs.GetCount(); }
528

    
529
        void           SetCursor(int n);
530
        void        KillCursor()                                        { SetCursor(-1); Refresh(); }        
531

    
532
        Image         GetDragSample();
533
        Image         GetDragSample(int n);
534

    
535
        int                                  GetScrollPos() const                        { return sc.GetPos(); }
536
        TabBar&                          SetScrollThickness(int sz);
537

    
538
        void AddFrameToScrollBar(CtrlFrame& fr)  { sc.AddFrame(fr); }
539

    
540
        Vector<Value>         GetKeys() const;
541
        Vector<Image>         GetIcons() const;
542
        TabBar&                          CopySettings(const TabBar& src);
543
        virtual void    Serialize(Stream& s);
544
        
545
        const Style&         GetStyle() const                                        { ASSERT(style); return *style; }        
546

    
547
        virtual void         ContextMenu(Bar& bar);
548
        
549
        static const Style& StyleDefault();
550
};
551

    
552
#include "FileTabs.h"
553
#include "TabBarCtrl.h"
554

    
555
}
556

    
557
#endif