]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/foldbar/captionbar.cpp
Warning fix.
[wxWidgets.git] / contrib / src / foldbar / captionbar.cpp
CommitLineData
957f5ab7
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: captionbar.cpp
3// Purpose: wxCaptionBar class belonging to the wxFoldPanel (but can be used independent)
4// Author: Jorgen Bodde
5// Modified by:
6// Created: June 18, 2004
7// RCS-ID:
8// Copyright: (c) Jorgen Bodde
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13#pragma implementation "foldpanelbar.h"
14#endif
15
16// For compilers that support precompilation, includes "wx/wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include "wx/dcmemory.h"
25#include "wx/dcclient.h"
26#endif
27
28#include <wx/app.h>
29
30#include "wx/foldbar/captionbar.h"
31
32/*
33 * wxCaptionBar
34 */
35
36BEGIN_EVENT_TABLE(wxCaptionBar, wxWindow)
37 EVT_PAINT(wxCaptionBar::OnPaint)
38 EVT_CHAR(wxCaptionBar::OnChar)
39 EVT_MOUSE_EVENTS(wxCaptionBar::OnMouseEvent)
40 EVT_SIZE(wxCaptionBar::OnSize)
41END_EVENT_TABLE()
42
43wxCaptionBar::wxCaptionBar(wxWindow* parent, const wxString &caption, wxImageList *images, wxWindowID id,
44 const wxCaptionBarStyle &cbstyle, const wxPoint& pos, const wxSize& size, long style)
45 : wxWindow(parent, id, pos, size, style)
46 , _caption(caption)
47 , _collapsed(false)
48 , _foldIcons(images)
49 , _rightIndent(wxFPB_BMP_RIGHTSPACE)
50 , _iconWidth(16)
51 , _iconHeight(16)
52{
53 // do initialisy thingy stuff
54
55 ApplyCaptionStyle(cbstyle, true);
56
57 // set initial size
58 if(_foldIcons)
59 {
60 wxASSERT(_foldIcons->GetImageCount() > 1);
61 _foldIcons->GetSize(0, _iconWidth, _iconHeight);
62 }
63}
64
65wxCaptionBar::~wxCaptionBar()
66{
67
68}
69
70void wxCaptionBar::ApplyCaptionStyle(const wxCaptionBarStyle &cbstyle, bool applyDefault)
71{
72 wxASSERT(GetParent());
73
74 wxCaptionBarStyle newstyle = cbstyle;
75
76 // set defaults in newly created style copy if needed
77 if(applyDefault)
78 {
79 // get first colour from style or make it default
80 if(!newstyle.FirstColourUsed())
81 newstyle.SetFirstColour(*wxWHITE);
82
83 // get second colour from style or make it default
84 if(!newstyle.SecondColourUsed())
85 {
86 // make the second colour slightly darker then the background
87 wxColour col = GetParent()->GetBackgroundColour();
88 col.Set((col.Red() >> 1) + 20, (col.Green() >> 1) + 20, (col.Blue() >> 1) + 20);
89 newstyle.SetSecondColour(col);
90 }
91
92 // get text colour
93 if(!newstyle.CaptionColourUsed())
94 newstyle.SetCaptionColour(*wxBLACK);
95
96 // get font colour
97 if(!newstyle.CaptionFontUsed())
98 newstyle.SetCaptionFont(GetParent()->GetFont());
99
100 // apply caption style
101 if(!newstyle.CaptionStyleUsed())
102 newstyle.SetCaptionStyle(wxCAPTIONBAR_GRADIENT_V);
103 }
104
105 // apply the style
106 _style = newstyle;
107}
108
109void wxCaptionBar::OnPaint(wxPaintEvent& WXUNUSED(event))
110{
111 wxPaintDC dc(this);
112
113 // TODO: Maybe first a memory DC should draw all, and then paint it on the
114 // caption. This way a flickering arrow during resize is not visible
115
116 // draw basics
117
118 FillCaptionBackground(dc);
119
120 dc.SetFont(_style.GetCaptionFont());
121 dc.DrawText(_caption, 4, (wxFPB_EXTRA_Y / 2));
122
123 // draw small icon, either collapsed or expanded
124 // based on the state of the bar. If we have
125 // any bmp's
126
127 if(_foldIcons)
128 {
129 wxCHECK2(_foldIcons->GetImageCount() > 1, return);
130
131 int index = 0;
132 if(_collapsed)
133 index = 1;
134
135 wxRect wndRect = GetRect();
136 _foldIcons->Draw(index, dc, wndRect.GetRight() - _iconWidth - _rightIndent, (wndRect.GetHeight() - _iconHeight) / 2,
137 wxIMAGELIST_DRAW_TRANSPARENT);
138 }
139}
140
141void wxCaptionBar::FillCaptionBackground(wxPaintDC &dc)
142{
143 // dispatch right style for caption drawing
144
145 switch(_style.GetCaptionStyle())
146 {
147 case wxCAPTIONBAR_GRADIENT_V:
148 DrawVerticalGradient(dc, GetRect());
149 break;
150 case wxCAPTIONBAR_GRADIENT_H:
151 DrawHorizontalGradient(dc, GetRect());
152 break;
153 case wxCAPTIONBAR_SINGLE:
154 DrawSingleColour(dc, GetRect());
155 break;
156 case wxCAPTIONBAR_RECTANGLE:
157 case wxCAPTIONBAR_FILLED_RECTANGLE:
158 DrawSingleRectangle(dc, GetRect());
159 break;
160 default:
161 break;
162 }
163}
164
165void wxCaptionBar::OnMouseEvent(wxMouseEvent& event)
166{
167 // if clicked on the arrow (single) or double on the caption
168 // we change state and an event must be fired to let this
169 // panel collapse or expand
170
171 bool send_event = false;
172
173 if (event.LeftDown() && _foldIcons)
174 {
175 wxPoint pt(event.GetPosition());
176 wxRect rect = GetRect();
177
178 if(pt.x > (rect.GetWidth() - _iconWidth - _rightIndent))
179 send_event = true;
180 }
181 else if(event.LeftDClick())
182 send_event = true;
183
184 // send the collapse, expand event to the parent
185
186 if(send_event)
187 {
188 wxCaptionBarEvent event(wxEVT_CAPTIONBAR);
189 event.SetBar(this);
190
191 ::wxPostEvent(this, event);
192
193 }
194}
195
196void wxCaptionBar::OnChar(wxKeyEvent &event)
197{
198 // TODO: Anything here?
199
200 event.Skip();
201}
202
203wxSize wxCaptionBar::DoGetBestSize() const
204{
205 int x,y;
206
207 GetTextExtent(_caption, &x, &y);
208
209 if(x < _iconWidth)
210 x = _iconWidth;
211
212 if(y < _iconHeight)
213 y = _iconHeight;
214
215 // TODO: The extra wxFPB_EXTRA_X constants should be adjustable as well
216
217 return wxSize(x + wxFPB_EXTRA_X, y + wxFPB_EXTRA_Y);
218}
219
220
221void wxCaptionBar::DrawVerticalGradient(wxDC &dc, const wxRect &rect )
222{
223 // gradient fill from colour 1 to colour 2 with top to bottom
224
225 if(rect.height < 1 || rect.width < 1)
226 return;
227
228 dc.SetPen(*wxTRANSPARENT_PEN);
229
230
231 // calculate gradient coefficients
232 wxColour col2 = _style.GetSecondColour(),
233 col1 = _style.GetFirstColour();
234
235 double rstep = double((col2.Red() - col1.Red())) / double(rect.height), rf = 0,
236 gstep = double((col2.Green() - col1.Green())) / double(rect.height), gf = 0,
237 bstep = double((col2.Blue() - col1.Blue())) / double(rect.height), bf = 0;
238
239 wxColour currCol;
240 for(int y = rect.y; y < rect.y + rect.height; y++)
241 {
242 currCol.Set(col1.Red() + rf, col1.Green() + gf, col1.Blue() + bf);
243 dc.SetBrush( wxBrush( currCol, wxSOLID ) );
244 dc.DrawRectangle( rect.x, rect.y + (y - rect.y), rect.width, rect.height );
245 //currCol.Set(currCol.Red() + rstep, currCol.Green() + gstep, currCol.Blue() + bstep);
246 rf += rstep; gf += gstep; bf += bstep;
247 }
248}
249
250void wxCaptionBar::DrawHorizontalGradient(wxDC &dc, const wxRect &rect )
251{
252 // gradient fill from colour 1 to colour 2 with left to right
253
254 if(rect.height < 1 || rect.width < 1)
255 return;
256
257 dc.SetPen(*wxTRANSPARENT_PEN);
258
259 // calculate gradient coefficients
260 wxColour col2 = _style.GetSecondColour(),
261 col1 = _style.GetFirstColour();
262
263 double rstep = double((col2.Red() - col1.Red())) / double(rect.width), rf = 0,
264 gstep = double((col2.Green() - col1.Green())) / double(rect.width), gf = 0,
265 bstep = double((col2.Blue() - col1.Blue())) / double(rect.width), bf = 0;
266
267 wxColour currCol;
268 for(int x = rect.x; x < rect.x + rect.width; x++)
269 {
270 currCol.Set(col1.Red() + rf, col1.Green() + gf, col1.Blue() + bf);
271 dc.SetBrush( wxBrush( currCol, wxSOLID ) );
272 dc.DrawRectangle( rect.x + (x - rect.x), rect.y, 1, rect.height );
273 rf += rstep; gf += gstep; bf += bstep;
274 }
275}
276
277void wxCaptionBar::DrawSingleColour(wxDC &dc, const wxRect &rect )
278{
279 // single colour fill. This is the most easy one to find
280
281 if(rect.height < 1 || rect.width < 1)
282 return;
283
284 dc.SetPen(*wxTRANSPARENT_PEN);
285
286 // draw simple rectangle
287 dc.SetBrush( wxBrush( _style.GetFirstColour(), wxSOLID ) );
288 dc.DrawRectangle( rect.x, rect.y, rect.width, rect.height );
289}
290
291void wxCaptionBar::DrawSingleRectangle(wxDC &dc, const wxRect &rect )
292{
293 wxASSERT(GetParent());
294
295 // single colour fill. This is the most easy one to find
296
297 if(rect.height < 2 || rect.width < 1)
298 return;
299
300 // single frame, set up internal fill colour
301
302 wxBrush br;
303 br.SetStyle(wxSOLID);
304
305 if(_style.GetCaptionStyle() == wxCAPTIONBAR_RECTANGLE)
306 br.SetColour(GetParent()->GetBackgroundColour());
307 else
308 br.SetColour(_style.GetFirstColour());
309
310 // setup the pen frame
311
312 wxPen pen(_style.GetSecondColour());
313 dc.SetPen(pen);
314
315 dc.SetBrush( br );
316 dc.DrawRectangle( rect.x, rect.y, rect.width, rect.height - 1);
317
318 wxPen bgpen(GetParent()->GetBackgroundColour());
319 dc.SetPen(bgpen);
320 dc.DrawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width, rect.y + rect.height - 1);
321}
322
323
324void wxCaptionBar::OnSize(wxSizeEvent &event)
325{
326 wxSize size = event.GetSize();
327
328 if(_foldIcons)
329 {
330 // What I am doing here is simply invalidating the part of the window exposed. So when I
331 // make a rect with as width the newly exposed part, and the x,y of the old window size origin,
332 // I don't need a bitmap calulation in it, or do I ? The bitmap needs redrawing anyway. Leave it
333 // like this until I figured it out
334
335 // set rect to redraw as old bitmap area which is entitled to redraw
336
337 wxRect rect(size.GetWidth() - _iconWidth - _rightIndent, 0, _iconWidth + _rightIndent,
338 _iconWidth + _rightIndent);
339
340 // adjust rectangle when more is slided so we need to redraw all
341 // the old stuff but not all (ugly flickering)
342
343 int diffX = size.GetWidth() - _oldSize.GetWidth();
344 if(diffX > 1)
345 {
346 // adjust the rect with all the crap to redraw
347
348 rect.SetWidth(rect.GetWidth() + diffX + 10);
349 rect.SetX(rect.GetX() - diffX - 10);
350 }
351
352 RefreshRect(rect);
353 }
354 else
355 {
356 wxRect rect = GetRect();
357 RefreshRect(rect);
358 }
359
360 _oldSize = size;
361}
362
363void wxCaptionBar::RedrawIconBitmap()
364{
365 if(_foldIcons)
366 {
367 // invalidate the bitmap area and force a redraw
368
369 wxRect rect = GetRect();
370
371 rect.SetX(rect.GetWidth() - _iconWidth - _rightIndent);
372 rect.SetWidth(_iconWidth + _rightIndent);
373 RefreshRect(rect);
374 }
375}
376
377/*
378 * wxCaptionBarEvent
379 */
380
381DEFINE_EVENT_TYPE(wxEVT_CAPTIONBAR)
382
383wxCaptionBarEvent::wxCaptionBarEvent(const wxCaptionBarEvent &event)
384 : wxCommandEvent(event)
385{
386 _bar = event._bar;
387}
388
389//DEFINE_EVENT_TYPE(wxEVT_CAPTIONBAR)
390//IMPLEMENT_DYNAMIC_CLASS(wxCaptionBarEvent, wxEvent)
391IMPLEMENT_DYNAMIC_CLASS(wxCaptionBarEvent, wxCommandEvent)