1 /////////////////////////////////////////////////////////////////////////////
2 // Name: captionbar.cpp
3 // Purpose: wxCaptionBar class belonging to the wxFoldPanel (but can be used independent)
4 // Author: Jorgen Bodde
8 // Copyright: (c) Jorgen Bodde
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "foldpanelbar.h"
16 // For compilers that support precompilation, includes "wx/wx.h".
17 #include "wx/wxprec.h"
24 #include "wx/dcmemory.h"
25 #include "wx/dcclient.h"
30 #include "wx/foldbar/captionbar.h"
36 BEGIN_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
)
43 wxCaptionBar::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
)
48 , _rightIndent(wxFPB_BMP_RIGHTSPACE
)
53 // do initialisy thingy stuff
55 ApplyCaptionStyle(cbstyle
, true);
60 wxASSERT(_foldIcons
->GetImageCount() > 1);
61 _foldIcons
->GetSize(0, _iconWidth
, _iconHeight
);
65 wxCaptionBar::~wxCaptionBar()
70 void wxCaptionBar::ApplyCaptionStyle(const wxCaptionBarStyle
&cbstyle
, bool applyDefault
)
72 wxASSERT(GetParent());
74 wxCaptionBarStyle newstyle
= cbstyle
;
76 // set defaults in newly created style copy if needed
79 // get first colour from style or make it default
80 if(!newstyle
.FirstColourUsed())
81 newstyle
.SetFirstColour(*wxWHITE
);
83 // get second colour from style or make it default
84 if(!newstyle
.SecondColourUsed())
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
);
93 if(!newstyle
.CaptionColourUsed())
94 newstyle
.SetCaptionColour(*wxBLACK
);
97 if(!newstyle
.CaptionFontUsed())
98 newstyle
.SetCaptionFont(GetParent()->GetFont());
100 // apply caption style
101 if(!newstyle
.CaptionStyleUsed())
102 newstyle
.SetCaptionStyle(wxCAPTIONBAR_GRADIENT_V
);
109 void wxCaptionBar::OnPaint(wxPaintEvent
& WXUNUSED(event
))
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
118 FillCaptionBackground(dc
);
120 dc
.SetFont(_style
.GetCaptionFont());
121 dc
.DrawText(_caption
, 4, (wxFPB_EXTRA_Y
/ 2));
123 // draw small icon, either collapsed or expanded
124 // based on the state of the bar. If we have
129 wxCHECK2(_foldIcons
->GetImageCount() > 1, return);
135 wxRect wndRect
= GetRect();
136 _foldIcons
->Draw(index
, dc
, wndRect
.GetRight() - _iconWidth
- _rightIndent
, (wndRect
.GetHeight() - _iconHeight
) / 2,
137 wxIMAGELIST_DRAW_TRANSPARENT
);
141 void wxCaptionBar::FillCaptionBackground(wxPaintDC
&dc
)
143 // dispatch right style for caption drawing
145 switch(_style
.GetCaptionStyle())
147 case wxCAPTIONBAR_GRADIENT_V
:
148 DrawVerticalGradient(dc
, GetRect());
150 case wxCAPTIONBAR_GRADIENT_H
:
151 DrawHorizontalGradient(dc
, GetRect());
153 case wxCAPTIONBAR_SINGLE
:
154 DrawSingleColour(dc
, GetRect());
156 case wxCAPTIONBAR_RECTANGLE
:
157 case wxCAPTIONBAR_FILLED_RECTANGLE
:
158 DrawSingleRectangle(dc
, GetRect());
165 void wxCaptionBar::OnMouseEvent(wxMouseEvent
& event
)
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
171 bool send_event
= false;
173 if (event
.LeftDown() && _foldIcons
)
175 wxPoint
pt(event
.GetPosition());
176 wxRect rect
= GetRect();
178 if(pt
.x
> (rect
.GetWidth() - _iconWidth
- _rightIndent
))
181 else if(event
.LeftDClick())
184 // send the collapse, expand event to the parent
188 wxCaptionBarEvent
event(wxEVT_CAPTIONBAR
);
191 ::wxPostEvent(this, event
);
196 void wxCaptionBar::OnChar(wxKeyEvent
&event
)
198 // TODO: Anything here?
203 wxSize
wxCaptionBar::DoGetBestSize() const
207 GetTextExtent(_caption
, &x
, &y
);
215 // TODO: The extra wxFPB_EXTRA_X constants should be adjustable as well
217 return wxSize(x
+ wxFPB_EXTRA_X
, y
+ wxFPB_EXTRA_Y
);
221 void wxCaptionBar::DrawVerticalGradient(wxDC
&dc
, const wxRect
&rect
)
223 // gradient fill from colour 1 to colour 2 with top to bottom
225 if(rect
.height
< 1 || rect
.width
< 1)
228 dc
.SetPen(*wxTRANSPARENT_PEN
);
231 // calculate gradient coefficients
232 wxColour col2
= _style
.GetSecondColour(),
233 col1
= _style
.GetFirstColour();
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;
240 for(int y
= rect
.y
; y
< rect
.y
+ rect
.height
; y
++)
243 (unsigned char)(col1
.Red() + rf
),
244 (unsigned char)(col1
.Green() + gf
),
245 (unsigned char)(col1
.Blue() + bf
)
247 dc
.SetBrush( wxBrush( currCol
, wxSOLID
) );
248 dc
.DrawRectangle( rect
.x
, rect
.y
+ (y
- rect
.y
), rect
.width
, rect
.height
);
249 //currCol.Set(currCol.Red() + rstep, currCol.Green() + gstep, currCol.Blue() + bstep);
250 rf
+= rstep
; gf
+= gstep
; bf
+= bstep
;
254 void wxCaptionBar::DrawHorizontalGradient(wxDC
&dc
, const wxRect
&rect
)
256 // gradient fill from colour 1 to colour 2 with left to right
258 if(rect
.height
< 1 || rect
.width
< 1)
261 dc
.SetPen(*wxTRANSPARENT_PEN
);
263 // calculate gradient coefficients
264 wxColour col2
= _style
.GetSecondColour(),
265 col1
= _style
.GetFirstColour();
267 double rstep
= double((col2
.Red() - col1
.Red())) / double(rect
.width
), rf
= 0,
268 gstep
= double((col2
.Green() - col1
.Green())) / double(rect
.width
), gf
= 0,
269 bstep
= double((col2
.Blue() - col1
.Blue())) / double(rect
.width
), bf
= 0;
272 for(int x
= rect
.x
; x
< rect
.x
+ rect
.width
; x
++)
275 (unsigned char)(col1
.Red() + rf
),
276 (unsigned char)(col1
.Green() + gf
),
277 (unsigned char)(col1
.Blue() + bf
)
279 dc
.SetBrush( wxBrush( currCol
, wxSOLID
) );
280 dc
.DrawRectangle( rect
.x
+ (x
- rect
.x
), rect
.y
, 1, rect
.height
);
281 rf
+= rstep
; gf
+= gstep
; bf
+= bstep
;
285 void wxCaptionBar::DrawSingleColour(wxDC
&dc
, const wxRect
&rect
)
287 // single colour fill. This is the most easy one to find
289 if(rect
.height
< 1 || rect
.width
< 1)
292 dc
.SetPen(*wxTRANSPARENT_PEN
);
294 // draw simple rectangle
295 dc
.SetBrush( wxBrush( _style
.GetFirstColour(), wxSOLID
) );
296 dc
.DrawRectangle( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
299 void wxCaptionBar::DrawSingleRectangle(wxDC
&dc
, const wxRect
&rect
)
301 wxASSERT(GetParent());
303 // single colour fill. This is the most easy one to find
305 if(rect
.height
< 2 || rect
.width
< 1)
308 // single frame, set up internal fill colour
311 br
.SetStyle(wxSOLID
);
313 if(_style
.GetCaptionStyle() == wxCAPTIONBAR_RECTANGLE
)
314 br
.SetColour(GetParent()->GetBackgroundColour());
316 br
.SetColour(_style
.GetFirstColour());
318 // setup the pen frame
320 wxPen
pen(_style
.GetSecondColour());
324 dc
.DrawRectangle( rect
.x
, rect
.y
, rect
.width
, rect
.height
- 1);
326 wxPen
bgpen(GetParent()->GetBackgroundColour());
328 dc
.DrawLine(rect
.x
, rect
.y
+ rect
.height
- 1, rect
.x
+ rect
.width
, rect
.y
+ rect
.height
- 1);
332 void wxCaptionBar::OnSize(wxSizeEvent
&event
)
334 wxSize size
= event
.GetSize();
338 // What I am doing here is simply invalidating the part of the window exposed. So when I
339 // make a rect with as width the newly exposed part, and the x,y of the old window size origin,
340 // I don't need a bitmap calulation in it, or do I ? The bitmap needs redrawing anyway. Leave it
341 // like this until I figured it out
343 // set rect to redraw as old bitmap area which is entitled to redraw
345 wxRect
rect(size
.GetWidth() - _iconWidth
- _rightIndent
, 0, _iconWidth
+ _rightIndent
,
346 _iconWidth
+ _rightIndent
);
348 // adjust rectangle when more is slided so we need to redraw all
349 // the old stuff but not all (ugly flickering)
351 int diffX
= size
.GetWidth() - _oldSize
.GetWidth();
354 // adjust the rect with all the crap to redraw
356 rect
.SetWidth(rect
.GetWidth() + diffX
+ 10);
357 rect
.SetX(rect
.GetX() - diffX
- 10);
364 wxRect rect
= GetRect();
371 void wxCaptionBar::RedrawIconBitmap()
375 // invalidate the bitmap area and force a redraw
377 wxRect rect
= GetRect();
379 rect
.SetX(rect
.GetWidth() - _iconWidth
- _rightIndent
);
380 rect
.SetWidth(_iconWidth
+ _rightIndent
);
389 DEFINE_EVENT_TYPE(wxEVT_CAPTIONBAR
)
391 wxCaptionBarEvent::wxCaptionBarEvent(const wxCaptionBarEvent
&event
)
392 : wxCommandEvent(event
)
397 //DEFINE_EVENT_TYPE(wxEVT_CAPTIONBAR)
398 //IMPLEMENT_DYNAMIC_CLASS(wxCaptionBarEvent, wxEvent)
399 IMPLEMENT_DYNAMIC_CLASS(wxCaptionBarEvent
, wxCommandEvent
)