]>
git.saurik.com Git - wxWidgets.git/blob - src/generic/bannerwindow.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/bannerwindow.h
3 // Purpose: wxBannerWindow class implementation
4 // Author: Vadim Zeitlin
6 // Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
10 #include "wx/wxprec.h"
16 #if wxUSE_BANNERWINDOW
18 #include "wx/bannerwindow.h"
21 #include "wx/bitmap.h"
22 #include "wx/colour.h"
25 #include "wx/dcbuffer.h"
30 // Some constants for banner layout, currently they're hard coded but we could
31 // easily make them configurable if needed later.
32 const int MARGIN_X
= 5;
33 const int MARGIN_Y
= 5;
35 } // anonymous namespace
37 const char wxBannerWindowNameStr
[] = "bannerwindow";
39 BEGIN_EVENT_TABLE(wxBannerWindow
, wxWindow
)
40 EVT_SIZE(wxBannerWindow::OnSize
)
41 EVT_PAINT(wxBannerWindow::OnPaint
)
44 void wxBannerWindow::Init()
48 m_colStart
= *wxWHITE
;
53 wxBannerWindow::Create(wxWindow
* parent
,
61 if ( !wxWindow::Create(parent
, winid
, pos
, size
, style
, name
) )
66 dir
== wxLEFT
|| dir
== wxRIGHT
|| dir
== wxTOP
|| dir
== wxBOTTOM
,
67 wxS("Invalid banner direction")
72 SetBackgroundStyle(wxBG_STYLE_PAINT
);
77 void wxBannerWindow::SetBitmap(const wxBitmap
& bmp
)
81 m_colBitmapBg
= wxColour();
88 void wxBannerWindow::SetText(const wxString
& title
, const wxString
& message
)
98 void wxBannerWindow::SetGradient(const wxColour
& start
, const wxColour
& end
)
106 wxFont
wxBannerWindow::GetTitleFont() const
108 wxFont font
= GetFont();
109 font
.MakeBold().MakeLarger();
113 wxSize
wxBannerWindow::DoGetBestClientSize() const
115 if ( m_bitmap
.IsOk() )
117 return m_bitmap
.GetSize();
121 wxClientDC
dc(const_cast<wxBannerWindow
*>(this));
122 const wxSize sizeText
= dc
.GetMultiLineTextExtent(m_message
);
124 dc
.SetFont(GetTitleFont());
126 const wxSize sizeTitle
= dc
.GetTextExtent(m_title
);
128 wxSize
sizeWin(wxMax(sizeTitle
.x
, sizeText
.x
), sizeTitle
.y
+ sizeText
.y
);
130 // If we draw the text vertically width and height are swapped.
131 if ( m_direction
== wxLEFT
|| m_direction
== wxRIGHT
)
132 wxSwap(sizeWin
.x
, sizeWin
.y
);
134 sizeWin
+= 2*wxSize(MARGIN_X
, MARGIN_Y
);
140 void wxBannerWindow::OnSize(wxSizeEvent
& event
)
147 void wxBannerWindow::OnPaint(wxPaintEvent
& WXUNUSED(event
))
149 if ( m_bitmap
.IsOk() && m_title
.empty() && m_message
.empty() )
151 // No need for buffering in this case.
154 DrawBitmapBackground(dc
);
156 else // We need to compose our contents ourselves.
158 wxAutoBufferedPaintDC
dc(this);
160 // Deal with the background first.
161 if ( m_bitmap
.IsOk() )
163 DrawBitmapBackground(dc
);
165 else // Draw gradient background.
167 wxDirection gradientDir
;
168 if ( m_direction
== wxLEFT
)
172 else if ( m_direction
== wxRIGHT
)
174 gradientDir
= wxBOTTOM
;
176 else // For both wxTOP and wxBOTTOM.
178 gradientDir
= wxRIGHT
;
181 dc
.GradientFillLinear(GetClientRect(), m_colStart
, m_colEnd
,
185 // Now draw the text on top of it.
186 dc
.SetFont(GetTitleFont());
188 wxPoint
pos(MARGIN_X
, MARGIN_Y
);
189 DrawBannerTextLine(dc
, m_title
, pos
);
190 pos
.y
+= dc
.GetTextExtent(m_title
).y
;
192 dc
.SetFont(GetFont());
194 wxArrayString lines
= wxSplit(m_message
, '\n', '\0');
195 const unsigned numLines
= lines
.size();
196 for ( unsigned n
= 0; n
< numLines
; n
++ )
198 const wxString
& line
= lines
[n
];
200 DrawBannerTextLine(dc
, line
, pos
);
201 pos
.y
+= dc
.GetTextExtent(line
).y
;
206 wxColour
wxBannerWindow::GetBitmapBg()
208 if ( m_colBitmapBg
.IsOk() )
209 return m_colBitmapBg
;
211 // Determine the colour to use to extend the bitmap. It's the colour of the
212 // bitmap pixels at the edge closest to the area where it can be extended.
213 wxImage
image(m_bitmap
.ConvertToImage());
215 // The point we get the colour from. The choice is arbitrary and in general
216 // the bitmap should have the same colour on the entire edge of this point
217 // for extending it to look good.
220 wxSize size
= image
.GetSize();
224 switch ( m_direction
)
228 // The bitmap will be extended to the right.
234 // The bitmap will be extended from the top.
240 // The bitmap will be extended to the bottom.
245 // This case is there only to prevent g++ warnings about not handling
246 // some enum elements in the switch, it can't really happen.
248 wxFAIL_MSG( wxS("Unreachable") );
251 m_colBitmapBg
.Set(image
.GetRed(p
.x
, p
.y
),
252 image
.GetGreen(p
.x
, p
.y
),
253 image
.GetBlue(p
.x
, p
.y
));
255 return m_colBitmapBg
;
258 void wxBannerWindow::DrawBitmapBackground(wxDC
& dc
)
260 // We may need to fill the part of the background not covered by the bitmap
261 // with the solid colour extending the bitmap, this rectangle will hold the
262 // area to be filled (which could be empty if the bitmap is big enough).
265 const wxSize size
= GetClientSize();
267 switch ( m_direction
)
271 // Draw the bitmap at the origin, its rightmost could be truncated,
272 // as it's meant to be.
273 dc
.DrawBitmap(m_bitmap
, 0, 0);
275 rectSolid
.x
= m_bitmap
.GetWidth();
276 rectSolid
.width
= size
.x
- rectSolid
.x
;
277 rectSolid
.height
= size
.y
;
281 // The top most part of the bitmap may be truncated but its bottom
282 // must be always visible so intentionally draw it possibly partly
283 // outside of the window.
284 rectSolid
.width
= size
.x
;
285 rectSolid
.height
= size
.y
- m_bitmap
.GetHeight();
286 dc
.DrawBitmap(m_bitmap
, 0, rectSolid
.height
);
290 // Draw the bitmap at the origin, possibly truncating its
292 dc
.DrawBitmap(m_bitmap
, 0, 0);
294 rectSolid
.y
= m_bitmap
.GetHeight();
295 rectSolid
.height
= size
.y
- rectSolid
.y
;
296 rectSolid
.width
= size
.x
;
299 // This case is there only to prevent g++ warnings about not handling
300 // some enum elements in the switch, it can't really happen.
302 wxFAIL_MSG( wxS("Unreachable") );
305 if ( rectSolid
.width
> 0 && rectSolid
.height
> 0 )
307 dc
.SetPen(*wxTRANSPARENT_PEN
);
308 dc
.SetBrush(GetBitmapBg());
309 dc
.DrawRectangle(rectSolid
);
314 wxBannerWindow::DrawBannerTextLine(wxDC
& dc
,
318 switch ( m_direction
)
322 // The simple case: we just draw the text normally.
323 dc
.DrawText(str
, pos
);
327 // We draw the text vertically and start from the lower left
328 // corner and not the upper left one as usual.
329 dc
.DrawRotatedText(str
, pos
.y
, GetClientSize().y
- pos
.x
, 90);
333 // We also draw the text vertically but now we start from the upper
334 // right corner and draw it from top to bottom.
335 dc
.DrawRotatedText(str
, GetClientSize().x
- pos
.y
, pos
.x
, -90);
339 wxFAIL_MSG( wxS("Unreachable") );
343 #endif // wxUSE_BANNERWINDOW