~ubuntu-dev/wxwidgets2.6/upstream-debian

« back to all changes in this revision

Viewing changes to contrib/src/foldbar/foldpanelbar.cpp

  • Committer: Daniel T Chen
  • Date: 2006-06-26 10:15:11 UTC
  • Revision ID: crimsun@ubuntu.com-20060626101511-a4436cec4c6d9b35
ImportĀ DebianĀ 2.6.3.2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/////////////////////////////////////////////////////////////////////////////
 
2
// Name:        foldpanelbar.cpp
 
3
// Purpose:
 
4
// Author:      Jorgen Bodde
 
5
// Modified by: ABX - 19/12/2004 : possibility of horizontal orientation
 
6
//                               : wxWidgets coding standards
 
7
// Created:     22/06/2004
 
8
// RCS-ID:      $Id: foldpanelbar.cpp,v 1.7 2005/07/28 23:23:27 VZ Exp $
 
9
// Copyright:   (c) Jorgen Bodde
 
10
// Licence:     wxWindows licence
 
11
/////////////////////////////////////////////////////////////////////////////
 
12
 
 
13
// For compilers that support precompilation, includes "wx/wx.h".
 
14
#include "wx/wxprec.h"
 
15
 
 
16
#ifdef __BORLANDC__
 
17
    #pragma hdrstop
 
18
#endif
 
19
 
 
20
#ifndef WX_PRECOMP
 
21
    #include "wx/wx.h"
 
22
#endif
 
23
 
 
24
#include "wx/foldbar/foldpanelbar.h"
 
25
#include "icon_collapsed.xpm"
 
26
#include "icon_expanded.xpm"
 
27
#include "icon_theresmore.xpm"
 
28
 
 
29
//----------------------------------------------------------------------------
 
30
// wxFoldPanelBar
 
31
//----------------------------------------------------------------------------
 
32
 
 
33
IMPLEMENT_DYNAMIC_CLASS( wxFoldPanelBar, wxPanel )
 
34
 
 
35
BEGIN_EVENT_TABLE(wxFoldPanelBar,wxPanel)
 
36
    EVT_SIZE(wxFoldPanelBar::OnSizePanel)
 
37
    //EVT_PAINT(wxFoldPanelBar::OnPaint)
 
38
    EVT_CAPTIONBAR(wxID_ANY, wxFoldPanelBar::OnPressCaption)
 
39
END_EVENT_TABLE()
 
40
 
 
41
wxFoldPanelBar::wxFoldPanelBar()
 
42
    : wxPanel()
 
43
    , m_foldPanel(NULL)
 
44
    , m_bottomPanel(NULL)
 
45
    , m_controlCreated(false)
 
46
{
 
47
 
 
48
}
 
49
 
 
50
wxFoldPanelBar::wxFoldPanelBar( wxWindow *parent, wxWindowID id, const wxPoint &position,
 
51
                                const wxSize& size, long style, long extraStyle)
 
52
    : wxPanel()
 
53
    , m_foldPanel(NULL)
 
54
    , m_bottomPanel(NULL)
 
55
    , m_controlCreated(false)
 
56
{
 
57
    Create( parent, id, position, size, style, extraStyle);
 
58
}
 
59
 
 
60
void wxFoldPanelBar::Create( wxWindow *parent, wxWindowID id, const wxPoint &position,
 
61
                             const wxSize& size, long style, long extraStyle )
 
62
{
 
63
 
 
64
    m_extraStyle = extraStyle;
 
65
 
 
66
    // make sure there is any orientation
 
67
    if ( ( style & wxFPB_HORIZONTAL ) != wxFPB_HORIZONTAL )
 
68
        style |= wxFPB_VERTICAL;
 
69
 
 
70
    // create the panel (duh!). This causes a size event, which we are going
 
71
    // to skip when we are not initialised
 
72
 
 
73
    wxPanel::Create(parent, id, position, size, style);
 
74
 
 
75
    // the fold panel area
 
76
 
 
77
    m_foldPanel = new wxPanel(this, wxID_ANY, position, size, wxNO_BORDER|wxTAB_TRAVERSAL);
 
78
 
 
79
    // the extra area for some icons / context menu etc
 
80
 
 
81
#if 0
 
82
    m_bottomPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(wxDefaultCoord,22), wxNO_BORDER|wxTAB_TRAVERSAL);
 
83
    m_bottomPanel->SetBackgroundColour(*wxWHITE);
 
84
#endif
 
85
 
 
86
    // create the fold icons to be used in the captions
 
87
 
 
88
    m_images = new wxImageList(16, 16);
 
89
 
 
90
    wxBitmap *bmp = new wxBitmap(icon_expanded);
 
91
    m_images->Add(*bmp);
 
92
    delete bmp;
 
93
 
 
94
    bmp = new wxBitmap(icon_collapsed);
 
95
    m_images->Add(*bmp);
 
96
    delete bmp;
 
97
 
 
98
    m_moreBmp = new wxBitmap(icon_theresmore);
 
99
 
 
100
    // do this as last, to check if create is already called
 
101
 
 
102
    m_controlCreated = true;
 
103
}
 
104
 
 
105
wxFoldPanelBar::~wxFoldPanelBar()
 
106
{
 
107
    delete m_images;
 
108
    delete m_moreBmp;
 
109
}
 
110
 
 
111
wxFoldPanel wxFoldPanelBar::AddFoldPanel(const wxString &caption, bool collapsedInitially, const wxCaptionBarStyle &style)
 
112
{
 
113
    wxASSERT(m_controlCreated);
 
114
 
 
115
    // create a fold panel item, which is first only the caption.
 
116
    // the user can now add a panel area which will be folded in
 
117
    // when pressed.
 
118
 
 
119
    wxFoldPanelItem *item = new wxFoldPanelItem(m_foldPanel, caption, m_images, collapsedInitially, style);
 
120
 
 
121
    // look at the last added one and reposition this one
 
122
    int pos = 0;
 
123
    if(m_panels.GetCount() > 0)
 
124
        pos = m_panels.Last()->GetItemPos() + m_panels.Last()->GetPanelLength();
 
125
 
 
126
    item->Reposition(pos);
 
127
    m_panels.Add(item);
 
128
 
 
129
    //return wxFoldPanel(item);
 
130
    return wxFoldPanel(item);
 
131
}
 
132
 
 
133
int wxFoldPanelBar::AddFoldPanelWindow(const wxFoldPanel &panel, wxWindow *window, int flags, int ySpacing, int leftSpacing,
 
134
                                       int rightSpacing)
 
135
{
 
136
    wxCHECK(panel.IsOk(), -1);
 
137
    panel.GetItem()->AddWindow(window, flags, ySpacing, leftSpacing, rightSpacing);
 
138
 
 
139
    // TODO: Take old and new height, and if difference, reposition all the lower panels
 
140
    // this is because the user can add new wxWindow controls somewhere in between
 
141
    // when other panels are already present.
 
142
 
 
143
    return 0;
 
144
}
 
145
 
 
146
int wxFoldPanelBar::AddFoldPanelSeperator(const wxFoldPanel &panel, const wxColour &color, int ySpacing, int leftSpacing,
 
147
                                          int rightSpacing)
 
148
{
 
149
    wxCHECK(panel.IsOk(), -1);
 
150
    panel.GetItem()->AddSeparator(color, ySpacing, leftSpacing, rightSpacing);
 
151
 
 
152
    return 0;
 
153
}
 
154
 
 
155
void wxFoldPanelBar::OnSizePanel(wxSizeEvent &event)
 
156
{
 
157
    // skip all stuff when we are not initialised yet
 
158
 
 
159
    if(!m_controlCreated)
 
160
    {
 
161
        event.Skip();
 
162
        return;
 
163
    }
 
164
 
 
165
    // now size the fold panel area and the
 
166
    // lower bar in such a way that the bar is always
 
167
    // visible
 
168
 
 
169
    wxRect foldrect = GetRect();
 
170
 
 
171
    // fold panel itself. If too little space,
 
172
    // don't show it
 
173
 
 
174
#if 0
 
175
    if(foldrect.GetHeight() < 23)
 
176
        foldrect.SetHeight(0);
 
177
    else
 
178
        foldrect.SetHeight(foldrect.GetHeight() - 22);
 
179
#endif
 
180
 
 
181
    foldrect.SetX(0);
 
182
    foldrect.SetY(0);
 
183
    m_foldPanel->SetSize(foldrect);
 
184
 
 
185
    if(m_extraStyle & wxFPB_COLLAPSE_TO_BOTTOM)
 
186
    {
 
187
        wxRect rect = RepositionCollapsedToBottom();
 
188
        bool vertical = IsVertical();
 
189
        if((vertical && rect.GetHeight() > 0) || (!vertical && rect.GetWidth() > 0))
 
190
            RefreshRect(rect);
 
191
    }
 
192
 
 
193
    // TODO: A smart way to check wether the old - new width of the
 
194
    // panel changed, if so no need to resize the fold panel items
 
195
 
 
196
    RedisplayFoldPanelItems();
 
197
 
 
198
    // tool panel for icons and other stuff
 
199
 
 
200
#if 0
 
201
    wxRect bottomrect = GetRect();
 
202
    if(bottomrect.GetHeight() < 22)
 
203
        bottomrect.SetY(0);
 
204
    else
 
205
        bottomrect.SetY(bottomrect.GetHeight() - 22);
 
206
 
 
207
    bottomrect.SetHeight(22);
 
208
    bottomrect.SetX(0);
 
209
    m_bottomPanel->SetSize(bottomrect);
 
210
 
 
211
    // TODO: redraw the bitmap properly
 
212
    // use the captionbar algorithm for that
 
213
 
 
214
    m_bottomPanel->Refresh();
 
215
#endif
 
216
}
 
217
 
 
218
void wxFoldPanelBar::OnPaint(wxPaintEvent &event)
 
219
{
 
220
    if(!m_controlCreated)
 
221
        return;
 
222
#if 0
 
223
    // paint the bottom panel only, where the
 
224
    // arrow is shown when there is more to show the user
 
225
    // just as informative icon
 
226
 
 
227
    wxPaintDC dc(m_bottomPanel);
 
228
 
 
229
    wxSize size = m_bottomPanel->GetSize();
 
230
    int offset = (size.GetHeight() - m_moreBmp->GetHeight()) / 2;
 
231
 
 
232
    dc.DrawBitmap(*m_moreBmp, size.GetWidth() - m_moreBmp->GetWidth() - 2, offset, true);
 
233
#endif
 
234
 
 
235
    event.Skip();
 
236
}
 
237
 
 
238
void wxFoldPanelBar::OnPressCaption(wxCaptionBarEvent &event)
 
239
{
 
240
    // act upon the folding or expanding status of the bar
 
241
    // to expand or collapse the panel(s)
 
242
 
 
243
    if(event.GetFoldStatus())
 
244
        Collapse(wxFoldPanel((wxFoldPanelItem *)event.GetTag()));
 
245
    else
 
246
        Expand(wxFoldPanel((wxFoldPanelItem *)event.GetTag()));
 
247
}
 
248
 
 
249
void wxFoldPanelBar::RefreshPanelsFrom(wxFoldPanelItem *item)
 
250
{
 
251
    wxASSERT(item);
 
252
 
 
253
    int i = m_panels.Index(item);
 
254
    if(i != wxNOT_FOUND)
 
255
        RefreshPanelsFrom(i);
 
256
}
 
257
 
 
258
void wxFoldPanelBar::RefreshPanelsFrom(size_t i)
 
259
{
 
260
    Freeze();
 
261
 
 
262
    // if collapse to bottom is on, the panels that are not expanded
 
263
    // should be drawn at the bottom. All panels that are expanded
 
264
    // are drawn on top. The last expanded panel gets all the extra space
 
265
 
 
266
    if(m_extraStyle & wxFPB_COLLAPSE_TO_BOTTOM)
 
267
    {
 
268
        int offset = 0;
 
269
 
 
270
        for(size_t j = 0; j < m_panels.GetCount(); j++)
 
271
        {
 
272
            if(m_panels.Item(j)->IsExpanded())
 
273
                offset += m_panels.Item(j)->Reposition(offset);
 
274
        }
 
275
 
 
276
        // put all non collapsed panels at the bottom where there is space, else
 
277
        // put them right behind the expanded ones
 
278
 
 
279
        RepositionCollapsedToBottom();
 
280
    }
 
281
    else
 
282
    {
 
283
        int pos = m_panels.Item(i)->GetItemPos() + m_panels.Item(i)->GetPanelLength();
 
284
        for(i++; i < m_panels.GetCount(); i++)
 
285
            pos += m_panels.Item(i)->Reposition(pos);
 
286
    }
 
287
    Thaw();
 
288
}
 
289
 
 
290
void wxFoldPanelBar::RedisplayFoldPanelItems()
 
291
{
 
292
    // resize them all. No need to reposition
 
293
 
 
294
    wxFoldPanelItem *item;
 
295
    for(size_t i = 0; i < m_panels.GetCount(); i++)
 
296
    {
 
297
        item = m_panels.Item(i);
 
298
        wxASSERT(item);
 
299
 
 
300
        item->ResizePanel();
 
301
    }
 
302
}
 
303
 
 
304
wxRect wxFoldPanelBar::RepositionCollapsedToBottom()
 
305
{
 
306
    wxRect value(0,0,0,0);
 
307
    bool vertical = IsVertical();
 
308
 
 
309
    // determine wether the number of panels left
 
310
    // times the size of their captions is enough
 
311
    // to be placed in the left over space
 
312
 
 
313
    int expanded = 0, collapsed = 0, offset;
 
314
    GetPanelsLength(collapsed, expanded);
 
315
 
 
316
    // if no room stick them behind the normal ones, else
 
317
    // at the bottom
 
318
 
 
319
    if(((vertical ? GetSize().GetHeight() : GetSize().GetWidth()) - expanded - collapsed) < 0)
 
320
        offset = expanded;
 
321
    else
 
322
    {
 
323
        // value is the region which is left unpainted
 
324
        // I will send it back as 'slack' so it does not need to
 
325
        // be recalulated.
 
326
 
 
327
        value.SetHeight(GetSize().GetHeight());
 
328
        value.SetWidth(GetSize().GetWidth());
 
329
 
 
330
        if(vertical)
 
331
        {
 
332
            value.SetY(expanded);
 
333
            value.SetHeight(value.GetHeight() - expanded);
 
334
        }
 
335
        else
 
336
        {
 
337
            value.SetX(expanded);
 
338
            value.SetWidth(value.GetWidth() - expanded);
 
339
        }
 
340
 
 
341
        offset = (vertical ? GetSize().GetHeight() : GetSize().GetWidth()) - collapsed;
 
342
    }
 
343
 
 
344
    // go reposition
 
345
 
 
346
    for(size_t i = 0; i < m_panels.GetCount(); i++)
 
347
    {
 
348
        if(!m_panels.Item(i)->IsExpanded())
 
349
            offset += m_panels.Item(i)->Reposition(offset);
 
350
    }
 
351
 
 
352
    return value;
 
353
}
 
354
 
 
355
int wxFoldPanelBar::GetPanelsLength(int &collapsed, int &expanded)
 
356
{
 
357
    int value = 0;
 
358
 
 
359
    // assumed here that all the panels that are expanded
 
360
    // are positioned after each other from 0,0 to end.
 
361
 
 
362
    for(size_t j = 0; j < m_panels.GetCount(); j++)
 
363
    {
 
364
        int offset = m_panels.Item(j)->GetPanelLength();
 
365
        value += offset;
 
366
        if(m_panels.Item(j)->IsExpanded())
 
367
            expanded += offset;
 
368
        else
 
369
            collapsed += offset;
 
370
    }
 
371
 
 
372
    return value;
 
373
}