]>
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
7 // Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 #include "wx/wxprec.h"
17 #if wxUSE_BANNERWINDOW
19 #include "wx/bannerwindow.h"
22 #include "wx/bitmap.h"
23 #include "wx/colour.h"
26 #include "wx/dcbuffer.h"
31 // Some constants for banner layout, currently they're hard coded but we could
32 // easily make them configurable if needed later.
33 const int MARGIN_X
= 5;
34 const int MARGIN_Y
= 5;
36 } // anonymous namespace
38 const char wxBannerWindowNameStr
[] = "bannerwindow";
40 BEGIN_EVENT_TABLE(wxBannerWindow
, wxWindow
)
41 EVT_SIZE(wxBannerWindow::OnSize
)
42 EVT_PAINT(wxBannerWindow::OnPaint
)
45 void wxBannerWindow::Init()
49 m_colStart
= *wxWHITE
;
54 wxBannerWindow::Create(wxWindow
* parent
,
62 if ( !wxWindow::Create(parent
, winid
, pos
, size
, style
, name
) )
67 dir
== wxLEFT
|| dir
== wxRIGHT
|| dir
== wxTOP
|| dir
== wxBOTTOM
,
68 wxS("Invalid banner direction")
73 SetBackgroundStyle(wxBG_STYLE_PAINT
);
78 void wxBannerWindow::SetBitmap(const wxBitmap
& bmp
)
82 m_colBitmapBg
= wxColour();
89 void wxBannerWindow::SetText(const wxString
& title
, const wxString
& message
)
99 void wxBannerWindow::SetGradient(const wxColour
& start
, const wxColour
& end
)
107 wxFont
wxBannerWindow::GetTitleFont() const
109 wxFont font
= GetFont();
110 font
.MakeBold().MakeLarger();
114 wxSize
wxBannerWindow::DoGetBestClientSize() const
116 if ( m_bitmap
.IsOk() )
118 return m_bitmap
.GetSize();
122 wxClientDC
dc(const_cast<wxBannerWindow
*>(this));
123 const wxSize sizeText
= dc
.GetMultiLineTextExtent(m_message
);
125 dc
.SetFont(GetTitleFont());
127 const wxSize sizeTitle
= dc
.GetTextExtent(m_title
);
129 wxSize
sizeWin(wxMax(sizeTitle
.x
, sizeText
.x
), sizeTitle
.y
+ sizeText
.y
);
131 // If we draw the text vertically width and height are swapped.
132 if ( m_direction
== wxLEFT
|| m_direction
== wxRIGHT
)
133 wxSwap(sizeWin
.x
, sizeWin
.y
);
135 sizeWin
+= 2*wxSize(MARGIN_X
, MARGIN_Y
);
141 void wxBannerWindow::OnSize(wxSizeEvent
& event
)
148 void wxBannerWindow::OnPaint(wxPaintEvent
& WXUNUSED(event
))
150 if ( m_bitmap
.IsOk() && m_title
.empty() && m_message
.empty() )
152 // No need for buffering in this case.
155 DrawBitmapBackground(dc
);
157 else // We need to compose our contents ourselves.
159 wxAutoBufferedPaintDC
dc(this);
161 // Deal with the background first.
162 if ( m_bitmap
.IsOk() )
164 DrawBitmapBackground(dc
);
166 else // Draw gradient background.
168 wxDirection gradientDir
;
169 if ( m_direction
== wxLEFT
)
173 else if ( m_direction
== wxRIGHT
)
175 gradientDir
= wxBOTTOM
;
177 else // For both wxTOP and wxBOTTOM.
179 gradientDir
= wxRIGHT
;
182 dc
.GradientFillLinear(GetClientRect(), m_colStart
, m_colEnd
,
186 // Now draw the text on top of it.
187 dc
.SetFont(GetTitleFont());
189 wxPoint
pos(MARGIN_X
, MARGIN_Y
);
190 DrawBannerTextLine(dc
, m_title
, pos
);
191 pos
.y
+= dc
.GetTextExtent(m_title
).y
;
193 dc
.SetFont(GetFont());
195 wxArrayString lines
= wxSplit(m_message
, '\n', '\0');
196 const unsigned numLines
= lines
.size();
197 for ( unsigned n
= 0; n
< numLines
; n
++ )
199 const wxString
& line
= lines
[n
];
201 DrawBannerTextLine(dc
, line
, pos
);
202 pos
.y
+= dc
.GetTextExtent(line
).y
;
207 wxColour
wxBannerWindow::GetBitmapBg()
209 if ( m_colBitmapBg
.IsOk() )
210 return m_colBitmapBg
;
212 // Determine the colour to use to extend the bitmap. It's the colour of the
213 // bitmap pixels at the edge closest to the area where it can be extended.
214 wxImage
image(m_bitmap
.ConvertToImage());
216 // The point we get the colour from. The choice is arbitrary and in general
217 // the bitmap should have the same colour on the entire edge of this point
218 // for extending it to look good.
221 wxSize size
= image
.GetSize();
225 switch ( m_direction
)
229 // The bitmap will be extended to the right.
235 // The bitmap will be extended from the top.
241 // The bitmap will be extended to the bottom.
246 // This case is there only to prevent g++ warnings about not handling
247 // some enum elements in the switch, it can't really happen.
249 wxFAIL_MSG( wxS("Unreachable") );
252 m_colBitmapBg
.Set(image
.GetRed(p
.x
, p
.y
),
253 image
.GetGreen(p
.x
, p
.y
),
254 image
.GetBlue(p
.x
, p
.y
));
256 return m_colBitmapBg
;
259 void wxBannerWindow::DrawBitmapBackground(wxDC
& dc
)
261 // We may need to fill the part of the background not covered by the bitmap
262 // with the solid colour extending the bitmap, this rectangle will hold the
263 // area to be filled (which could be empty if the bitmap is big enough).
266 const wxSize size
= GetClientSize();
268 switch ( m_direction
)
272 // Draw the bitmap at the origin, its rightmost could be truncated,
273 // as it's meant to be.
274 dc
.DrawBitmap(m_bitmap
, 0, 0);
276 rectSolid
.x
= m_bitmap
.GetWidth();
277 rectSolid
.width
= size
.x
- rectSolid
.x
;
278 rectSolid
.height
= size
.y
;
282 // The top most part of the bitmap may be truncated but its bottom
283 // must be always visible so intentionally draw it possibly partly
284 // outside of the window.
285 rectSolid
.width
= size
.x
;
286 rectSolid
.height
= size
.y
- m_bitmap
.GetHeight();
287 dc
.DrawBitmap(m_bitmap
, 0, rectSolid
.height
);
291 // Draw the bitmap at the origin, possibly truncating its
293 dc
.DrawBitmap(m_bitmap
, 0, 0);
295 rectSolid
.y
= m_bitmap
.GetHeight();
296 rectSolid
.height
= size
.y
- rectSolid
.y
;
297 rectSolid
.width
= size
.x
;
300 // This case is there only to prevent g++ warnings about not handling
301 // some enum elements in the switch, it can't really happen.
303 wxFAIL_MSG( wxS("Unreachable") );
306 if ( rectSolid
.width
> 0 && rectSolid
.height
> 0 )
308 dc
.SetPen(*wxTRANSPARENT_PEN
);
309 dc
.SetBrush(GetBitmapBg());
310 dc
.DrawRectangle(rectSolid
);
315 wxBannerWindow::DrawBannerTextLine(wxDC
& dc
,
319 switch ( m_direction
)
323 // The simple case: we just draw the text normally.
324 dc
.DrawText(str
, pos
);
328 // We draw the text vertically and start from the lower left
329 // corner and not the upper left one as usual.
330 dc
.DrawRotatedText(str
, pos
.y
, GetClientSize().y
- pos
.x
, 90);
334 // We also draw the text vertically but now we start from the upper
335 // right corner and draw it from top to bottom.
336 dc
.DrawRotatedText(str
, GetClientSize().x
- pos
.y
, pos
.x
, -90);
340 wxFAIL_MSG( wxS("Unreachable") );
344 #endif // wxUSE_BANNERWINDOW