File: clAuiMainNotebookTabArt.cpp

package info (click to toggle)
codelite 12.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 95,112 kB
  • sloc: cpp: 424,040; ansic: 18,284; php: 9,569; lex: 4,186; yacc: 2,820; python: 2,294; sh: 312; makefile: 51; xml: 13
file content (311 lines) | stat: -rw-r--r-- 10,337 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// copyright            : (C) 2014 Eran Ifrah
// file name            : cl_aui_notebook_art.cpp
//
// -------------------------------------------------------------------------
// A
//              _____           _      _     _ _
//             /  __ \         | |    | |   (_) |
//             | /  \/ ___   __| | ___| |    _| |_ ___
//             | |    / _ \ / _  |/ _ \ |   | | __/ _ )
//             | \__/\ (_) | (_| |  __/ |___| | ||  __/
//              \____/\___/ \__,_|\___\_____/_|\__\___|
//
//                                                  F i l e
//
//    This program is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

#include "clAuiMainNotebookTabArt.h"

#include "ColoursAndFontsManager.h"
#include "clNotebookTheme.h"
#include "cl_command_event.h"
#include "codelite_events.h"
#include "drawingutils.h"
#include "editor_config.h"
#include "event_notifier.h"
#include "globals.h"
#include "ieditor.h"
#include "lexer_configuration.h"
#include "plugin.h"
#include "plugin_general_wxcp.h"
#include <editor_config.h>
#include <wx/dcgraph.h>
#include <wx/dcmemory.h>
#include <wx/stc/stc.h>
#include <wx/xrc/xmlres.h>

#define Y_PADDING_BASE 3
#ifdef __WXMSW__
#define X_PADDING 12
#else
#define X_PADDING 10
#endif

#ifdef __WXMAC__
#include <wx/osx/private.h>
#endif

static int x_button_size = 12;
static int Y_PADDING = Y_PADDING_BASE;

clAuiMainNotebookTabArt::clAuiMainNotebookTabArt()
    : m_tabRadius(0.0)
{
    RefreshColours(0);
}

clAuiMainNotebookTabArt::~clAuiMainNotebookTabArt() {}

void clAuiMainNotebookTabArt::DrawBackground(wxDC& dc, wxWindow* wnd, const wxRect& rect)
{
    wxUnusedVar(wnd);
    dc.SetPen(m_bgColour);
    dc.SetBrush(m_bgColour);
    dc.DrawRectangle(rect);
    m_windowListButtonRect = wxRect();
}

#define DRAW_LINE(__p1, __p2) \
    dc.DrawLine(__p1, __p2);  \
    dc.DrawLine(__p1, __p2);  \
    dc.DrawLine(__p1, __p2);  \
    dc.DrawLine(__p1, __p2);

void clAuiMainNotebookTabArt::DrawTab(wxDC& wxdc, wxWindow* wnd, const wxAuiNotebookPage& page, const wxRect& in_rect,
                                      int close_button_state, wxRect* out_tab_rect, wxRect* out_button_rect,
                                      int* x_extent)
{
#ifdef __WXMSW__
    wxGCDC dc;
    DrawingUtils::GetGCDC(wxdc, dc);
#else
    wxDC& dc = wxdc;
#endif

    if(in_rect.GetHeight() == 0) { return; } // Tabs are not visible
    int curx = 0;

    wxColour penColour = page.active ? m_activeTabPenColour : m_penColour;
    wxColour bgColour = page.active ? m_activeTabBgColour : m_tabBgColour;

    wxSize sz = GetTabSize(dc, wnd, page.caption, page.bitmap, page.active, close_button_state, x_extent);
    if(sz.GetHeight() < in_rect.GetHeight()) { sz.SetHeight(in_rect.GetHeight()); }

    wxRect rr(in_rect.GetTopLeft(), sz);

    // AUI tab does not really "touching" the bottom rect
    // so we need to change the offsets a bit
    rr.y += 2;

    /// the tab start position (x)
    curx = rr.x + X_PADDING;

    // Set clipping region
    bool tabTruncated = false;
    if(!m_windowListButtonRect.IsEmpty() && (rr.GetTopRight().x >= m_windowListButtonRect.GetX())) {
        rr.SetWidth(rr.GetWidth() - (rr.GetTopRight().x - m_windowListButtonRect.GetX()));
        if(rr.GetWidth() < 0) { rr.SetWidth(0); }
        tabTruncated = true;
    }

    dc.SetClippingRegion(rr);
    dc.SetPen(penColour);
    dc.SetBrush(bgColour);
    dc.DrawRectangle(rr);
    if(tabTruncated) {
        // Erase the right side line
        dc.SetPen(bgColour);
        dc.DrawLine(rr.GetTopRight(), rr.GetBottomRight());
        // Restore the pen
        dc.SetPen(penColour);
    }
    if(!page.active) {
        // Draw 2 lines at the bottom rect
        // one with the background colour of the active tab and the second
        // with the active tab pen colour
        wxPoint p1, p2;
        p1 = rr.GetBottomLeft();
        p2 = rr.GetBottomRight();

        // We reduce 2 pixels that we added earlier (see ~20 line above)
        p1.x += 1;
        p1.y -= 2;
        p2.x -= 1;
        p2.y -= 2;

        dc.SetPen(m_penColour);
        dc.DrawLine(p1, p2);
    } else {
        wxPoint p1, p2;
        p1 = rr.GetBottomLeft();
        p2 = rr.GetBottomRight();

        dc.SetPen(m_activeTabBgColour);
        for(int i = 0; i < 3; ++i) {
            DRAW_LINE(p1, p2);
            p1.y += 1;
            p2.y += 1;
        }

        // Mark the active tab
        p1 = rr.GetTopRight();
        p2 = rr.GetTopLeft();

        // Since the pen width is 3, start the drawing
        // One pixel below
        p1.y += 1;
        p2.y += 1;
        dc.SetPen(wxPen(m_markerColour, 3));
        dc.DrawLine(p1, p2);
    }

    wxString caption = page.caption;
    if(caption.IsEmpty()) { caption = "Tp"; }

    wxFont fnt = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
    dc.SetFont(fnt);
    wxSize ext = dc.GetTextExtent(caption);
    if(caption == "Tp") { caption.Clear(); }

    /// Draw the bitmap
    if(page.bitmap.IsOk()) {
        int bmpy = (rr.y + (rr.height - page.bitmap.GetScaledHeight()) / 2);
        dc.DrawBitmap(page.bitmap, curx, bmpy);
        curx += page.bitmap.GetScaledWidth();
        curx += X_PADDING;
    }

    /// Draw the text
    wxColour textColour = page.active ? m_activeTabTextColour : m_tabTextColour;
    dc.SetTextForeground(textColour);
    wxDouble textYOffCorrd = (rr.y + (rr.height - ext.y) / 2);
    dc.DrawText(page.caption, curx, textYOffCorrd);

    // advance the X offset
    curx += ext.x;
    curx += X_PADDING;

    /// Draw the X button on the tab
    if(close_button_state != wxAUI_BUTTON_STATE_HIDDEN) {
        eButtonState btnState = eButtonState::kNormal;
        switch(close_button_state) {
        case wxAUI_BUTTON_STATE_HOVER:
            btnState = eButtonState::kHover;
            break;
        case wxAUI_BUTTON_STATE_PRESSED:
            btnState = eButtonState::kPressed;
            break;
        }
        int btny = (rr.y + (rr.height - x_button_size) / 2);
        btny += 2; // We add 2 more pixels here cause of the marker line
        
        wxRect xRect = wxRect(curx, btny, x_button_size, x_button_size);
        DrawingUtils::DrawButtonX(dc, wnd, xRect, m_markerColour, btnState);
        *out_button_rect = xRect;
        curx += x_button_size;
        curx += X_PADDING;
    }

    *out_tab_rect = rr;
    dc.DestroyClippingRegion();
}

wxSize clAuiMainNotebookTabArt::GetTabSize(wxDC& dc, wxWindow* WXUNUSED(wnd), const wxString& caption,
                                           const wxBitmap& bitmap, bool active, int close_button_state, int* x_extent)
{
    wxCoord measured_textx;
    wxCoord measured_texty;

    // +------------------+
    // |.[bmp].[text].[x].|
    // +------------------+

    wxFont f = DrawingUtils::GetDefaultGuiFont();
    dc.SetFont(f);
    dc.GetTextExtent(caption, &measured_textx, &measured_texty);

    // add padding around the text
    wxCoord tab_width = X_PADDING;
    wxCoord tab_height = measured_texty;
    tab_height += (2 * Y_PADDING);
    
    // if there's a bitmap, add space for it
    if(bitmap.IsOk()) {
        tab_width += bitmap.GetWidth();
        tab_width += X_PADDING; // right side bitmap padding
    }
    
    tab_width += measured_textx;
    tab_width += X_PADDING;
    
    // if the close button is showing, add space for it
    if(close_button_state != wxAUI_BUTTON_STATE_HIDDEN) { tab_width += x_button_size + X_PADDING; }

    if(m_flags & wxAUI_NB_TAB_FIXED_WIDTH) {
        tab_width = 100;
    }
    *x_extent = tab_width;
    return wxSize(tab_width, tab_height);
}

void clAuiMainNotebookTabArt::RefreshColours(long style)
{
    // Base colours
    wxColour faceColour = DrawingUtils::GetPanelBgColour();
    wxColour textColour = DrawingUtils::GetPanelTextColour();

    // Active tab colours
    m_activeTabTextColour = textColour;
    if(DrawingUtils::IsDark(faceColour)) {
        // Make the active tab darker
        m_activeTabBgColour = faceColour.ChangeLightness(60);
        m_activeTabPenColour = m_activeTabBgColour;

    } else {
        // Make it lighter
        m_activeTabBgColour = faceColour.ChangeLightness(150);
        m_activeTabPenColour = faceColour.ChangeLightness(70);
    }

    // Inactive tab colours
    m_tabTextColour = textColour;
    m_tabBgColour = faceColour.ChangeLightness(95);
    m_penColour = faceColour.ChangeLightness(85);
    m_markerColour = DrawingUtils::GetCaptionColour();
    m_bgColour = faceColour;

    if(style & kNotebook_DynamicColours) {
        LexerConf::Ptr_t lexer = ColoursAndFontsManager::Get().GetLexer("text");
        if(lexer) {
            m_activeTabBgColour = lexer->GetProperty(0).GetBgColour();
            m_activeTabPenColour = m_activeTabBgColour;
        }
    }
    if(DrawingUtils::IsDark(m_activeTabBgColour)) { m_activeTabTextColour = *wxWHITE; }
    // Update the tab height based on the user settings
    Y_PADDING = Y_PADDING_BASE + EditorConfigST::Get()->GetOptions()->GetNotebookTabHeight();
}

static int dropdown_button_size = 20;
void clAuiMainNotebookTabArt::DrawButton(wxDC& dc, wxWindow* wnd, const wxRect& in_rect, int bitmap_id,
                                         int button_state, int orientation, wxRect* out_rect)
{
    if(bitmap_id == wxAUI_BUTTON_WINDOWLIST) {
        m_windowListButtonRect = wxRect((in_rect.x + in_rect.GetWidth() - dropdown_button_size),
                                        in_rect.y + ((in_rect.height - dropdown_button_size) / 2), dropdown_button_size,
                                        dropdown_button_size);
        DrawingUtils::DrawDropDownArrow(wnd, dc, m_windowListButtonRect, m_markerColour);
        *out_rect = m_windowListButtonRect;
    } else {
        wxAuiDefaultTabArt::DrawButton(dc, wnd, in_rect, bitmap_id, button_state, orientation, out_rect);
    }
}