// configurable in the future.
wxFont GetTitleFont() const;
+ // Return the colour to use for extending the bitmap. Non-const as it
+ // updates m_colBitmapBg if needed.
+ wxColour GetBitmapBg();
+
// The window side along which the banner is laid out.
wxDirection m_direction;
// If valid, this bitmap is drawn as is.
wxBitmap m_bitmap;
+ // If bitmap is valid, this is the colour we use to extend it if the bitmap
+ // is smaller than this window. It is computed on demand by GetBitmapBg().
+ wxColour m_colBitmapBg;
+
// The title and main message to draw, used if m_bitmap is invalid.
wxString m_title,
m_message;
/**
Provide the bitmap to use as background.
- Notice that the bitmap should be big enough to always cover the entire
- banner, e.g. for a horizontal banner with wxTOP style its width should
- be bigger than any reasonable window size.
-
- For wxLEFT orientation the bitmap is truncated from the top, for wxTOP
- and wxBOTTOM -- from the right and for wxRIGHT -- from the bottom, so
- put the most important part of the bitmap information in the opposite
- direction.
+ Notice that ideally the bitmap should be big enough to always cover the
+ entire banner, e.g. for a horizontal banner with wxTOP style its width
+ should be bigger than any reasonable window size. Otherwise the bitmap
+ is extended to cover the entire window area with a solid colour taken
+ from the bitmap pixel on the edge in which direction the extension
+ occurs so all bitmap pixels on this edge (top for wxLEFT, right for
+ wxTOP and wxBOTTOM and bottom for wxRIGHT) should have the same colour
+ to avoid jarring discontinuity.
+
+ If, on the other hand, the bitmap is bigger than the window size, then
+ it is truncated. For wxLEFT orientation the bitmap is truncated from
+ the top, for wxTOP and wxBOTTOM -- from the right and for wxRIGHT --
+ from the bottom, so put the most important part of the bitmap
+ information in the opposite direction where it will never be truncated.
If no valid background bitmap is specified, the banner draws gradient
background but if a valid bitmap is given here, the gradient is not
{
m_bitmap = bmp;
+ m_colBitmapBg = wxColour();
+
InvalidateBestSize();
Refresh();
}
}
-void wxBannerWindow::DrawBitmapBackground(wxDC& dc)
+wxColour wxBannerWindow::GetBitmapBg()
{
+ if ( m_colBitmapBg.IsOk() )
+ return m_colBitmapBg;
+
+ // Determine the colour to use to extend the bitmap. It's the colour of the
+ // bitmap pixels at the edge closest to the area where it can be extended.
+ wxImage image(m_bitmap.ConvertToImage());
+
+ // The point we get the colour from. The choice is arbitrary and in general
+ // the bitmap should have the same colour on the entire edge of this point
+ // for extending it to look good.
+ wxPoint p;
+
+ wxSize size = image.GetSize();
+ size.x--;
+ size.y--;
+
switch ( m_direction )
{
case wxTOP:
case wxBOTTOM:
+ // The bitmap will be extended to the right.
+ p.x = size.x;
+ p.y = 0;
+ break;
+
+ case wxLEFT:
+ // The bitmap will be extended from the top.
+ p.x = 0;
+ p.y = 0;
+ break;
+
case wxRIGHT:
- // Draw the bitmap normally, its rightmost or bottom part could be
- // truncated, as it's meant to be.
+ // The bitmap will be extended to the bottom.
+ p.x = 0;
+ p.y = size.y;
+ break;
+
+ // This case is there only to prevent g++ warnings about not handling
+ // some enum elements in the switch, it can't really happen.
+ case wxALL:
+ wxFAIL_MSG( wxS("Unreachable") );
+ }
+
+ m_colBitmapBg.Set(image.GetRed(p.x, p.y),
+ image.GetGreen(p.x, p.y),
+ image.GetBlue(p.x, p.y));
+
+ return m_colBitmapBg;
+}
+
+void wxBannerWindow::DrawBitmapBackground(wxDC& dc)
+{
+ // We may need to fill the part of the background not covered by the bitmap
+ // with the solid colour extending the bitmap, this rectangle will hold the
+ // area to be filled (which could be empty if the bitmap is big enough).
+ wxRect rectSolid;
+
+ const wxSize size = GetClientSize();
+
+ switch ( m_direction )
+ {
+ case wxTOP:
+ case wxBOTTOM:
+ // Draw the bitmap at the origin, its rightmost could be truncated,
+ // as it's meant to be.
dc.DrawBitmap(m_bitmap, 0, 0);
+
+ rectSolid.x = m_bitmap.GetWidth();
+ rectSolid.width = size.x - rectSolid.x;
+ rectSolid.height = size.y;
break;
case wxLEFT:
// The top most part of the bitmap may be truncated but its bottom
// must be always visible so intentionally draw it possibly partly
// outside of the window.
- dc.DrawBitmap(m_bitmap,
- 0, GetClientSize().y - m_bitmap.GetHeight());
+ rectSolid.width = size.x;
+ rectSolid.height = size.y - m_bitmap.GetHeight();
+ dc.DrawBitmap(m_bitmap, 0, rectSolid.height);
+ break;
+
+ case wxRIGHT:
+ // Draw the bitmap at the origin, possibly truncating its
+ // bottommost part.
+ dc.DrawBitmap(m_bitmap, 0, 0);
+
+ rectSolid.y = m_bitmap.GetHeight();
+ rectSolid.height = size.y - rectSolid.y;
+ rectSolid.width = size.x;
break;
// This case is there only to prevent g++ warnings about not handling
case wxALL:
wxFAIL_MSG( wxS("Unreachable") );
}
+
+ if ( rectSolid.width > 0 && rectSolid.height > 0 )
+ {
+ dc.SetPen(*wxTRANSPARENT_PEN);
+ dc.SetBrush(GetBitmapBg());
+ dc.DrawRectangle(rectSolid);
+ }
}
void