implemented menu drawing in the GTK theme
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14553 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -30,6 +30,8 @@
|
|||||||
#include "wx/dcmemory.h"
|
#include "wx/dcmemory.h"
|
||||||
#include "wx/window.h"
|
#include "wx/window.h"
|
||||||
|
|
||||||
|
#include "wx/menu.h"
|
||||||
|
|
||||||
#include "wx/bmpbuttn.h"
|
#include "wx/bmpbuttn.h"
|
||||||
#include "wx/button.h"
|
#include "wx/button.h"
|
||||||
#include "wx/checkbox.h"
|
#include "wx/checkbox.h"
|
||||||
@@ -40,6 +42,8 @@
|
|||||||
#include "wx/slider.h"
|
#include "wx/slider.h"
|
||||||
#include "wx/textctrl.h"
|
#include "wx/textctrl.h"
|
||||||
#include "wx/toolbar.h"
|
#include "wx/toolbar.h"
|
||||||
|
|
||||||
|
#include "wx/settings.h"
|
||||||
#endif // WX_PRECOMP
|
#endif // WX_PRECOMP
|
||||||
|
|
||||||
#include "wx/notebook.h"
|
#include "wx/notebook.h"
|
||||||
@@ -51,6 +55,8 @@
|
|||||||
#include "wx/univ/theme.h"
|
#include "wx/univ/theme.h"
|
||||||
#include "wx/toplevel.h"
|
#include "wx/toplevel.h"
|
||||||
|
|
||||||
|
class WXDLLEXPORT wxGTKMenuGeometryInfo;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// constants (to be removed, for testing only)
|
// constants (to be removed, for testing only)
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -425,6 +431,16 @@ protected:
|
|||||||
wxAlignment align,
|
wxAlignment align,
|
||||||
int indexAccel);
|
int indexAccel);
|
||||||
|
|
||||||
|
// common part of DrawMenuItem() and DrawMenuBarItem()
|
||||||
|
void DoDrawMenuItem(wxDC& dc,
|
||||||
|
const wxRect& rect,
|
||||||
|
const wxString& label,
|
||||||
|
int flags,
|
||||||
|
int indexAccel,
|
||||||
|
const wxString& accel = _T(""),
|
||||||
|
const wxBitmap& bitmap = wxNullBitmap,
|
||||||
|
const wxGTKMenuGeometryInfo *geometryInfo = NULL);
|
||||||
|
|
||||||
// initialize the combo bitmaps
|
// initialize the combo bitmaps
|
||||||
void InitComboBitmaps();
|
void InitComboBitmaps();
|
||||||
|
|
||||||
@@ -1215,6 +1231,10 @@ void wxGTKRenderer::DrawButtonLabel(wxDC& dc,
|
|||||||
dc.DrawLabel(label, rectShadow, alignment, indexAccel);
|
dc.DrawLabel(label, rectShadow, alignment, indexAccel);
|
||||||
dc.SetTextForeground(wxSCHEME_COLOUR(m_scheme, CONTROL_TEXT_DISABLED));
|
dc.SetTextForeground(wxSCHEME_COLOUR(m_scheme, CONTROL_TEXT_DISABLED));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dc.SetTextForeground(wxSCHEME_COLOUR(m_scheme, CONTROL_TEXT));
|
||||||
|
}
|
||||||
|
|
||||||
dc.DrawLabel(label, image, rect, alignment, indexAccel, rectBounds);
|
dc.DrawLabel(label, image, rect, alignment, indexAccel, rectBounds);
|
||||||
}
|
}
|
||||||
@@ -1273,6 +1293,7 @@ void wxGTKRenderer::DrawCheckItem(wxDC& dc,
|
|||||||
wxRect rectBitmap = rect;
|
wxRect rectBitmap = rect;
|
||||||
rectBitmap.x -= 1;
|
rectBitmap.x -= 1;
|
||||||
rectBitmap.width = GetCheckBitmapSize().x;
|
rectBitmap.width = GetCheckBitmapSize().x;
|
||||||
|
|
||||||
// never draw the focus rect around the check indicators here
|
// never draw the focus rect around the check indicators here
|
||||||
DrawCheckButton(dc, _T(""), bitmap, rectBitmap, flags & ~wxCONTROL_FOCUSED);
|
DrawCheckButton(dc, _T(""), bitmap, rectBitmap, flags & ~wxCONTROL_FOCUSED);
|
||||||
|
|
||||||
@@ -1894,45 +1915,265 @@ void wxGTKRenderer::DrawSliderThumb(wxDC& dc,
|
|||||||
// menu and menubar
|
// menu and menubar
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// wxGTKMenuGeometryInfo: the wxMenuGeometryInfo used by wxGTKRenderer
|
||||||
|
class WXDLLEXPORT wxGTKMenuGeometryInfo : public wxMenuGeometryInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual wxSize GetSize() const { return m_size; }
|
||||||
|
|
||||||
|
wxCoord GetLabelOffset() const { return m_ofsLabel; }
|
||||||
|
wxCoord GetAccelOffset() const { return m_ofsAccel; }
|
||||||
|
|
||||||
|
wxCoord GetItemHeight() const { return m_heightItem; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// the total size of the menu
|
||||||
|
wxSize m_size;
|
||||||
|
|
||||||
|
// the offset of the start of the menu item label
|
||||||
|
wxCoord m_ofsLabel;
|
||||||
|
|
||||||
|
// the offset of the start of the accel label
|
||||||
|
wxCoord m_ofsAccel;
|
||||||
|
|
||||||
|
// the height of a normal (not separator) item
|
||||||
|
wxCoord m_heightItem;
|
||||||
|
|
||||||
|
friend wxMenuGeometryInfo *
|
||||||
|
wxGTKRenderer::GetMenuGeometry(wxWindow *, const wxMenu&) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME: all constants are hardcoded but shouldn't be
|
||||||
|
static const wxCoord MENU_LEFT_MARGIN = 9;
|
||||||
|
static const wxCoord MENU_RIGHT_MARGIN = 6;
|
||||||
|
|
||||||
|
static const wxCoord MENU_HORZ_MARGIN = 6;
|
||||||
|
static const wxCoord MENU_VERT_MARGIN = 3;
|
||||||
|
|
||||||
|
// the margin around bitmap/check marks (on each side)
|
||||||
|
static const wxCoord MENU_BMP_MARGIN = 2;
|
||||||
|
|
||||||
|
// the margin between the labels and accel strings
|
||||||
|
static const wxCoord MENU_ACCEL_MARGIN = 8;
|
||||||
|
|
||||||
|
// the separator height in pixels: in fact, strangely enough, the real height
|
||||||
|
// is 2 but Windows adds one extra pixel in the bottom margin, so take it into
|
||||||
|
// account here
|
||||||
|
static const wxCoord MENU_SEPARATOR_HEIGHT = 3;
|
||||||
|
|
||||||
|
// the size of the standard checkmark bitmap
|
||||||
|
static const wxCoord MENU_CHECK_SIZE = 9;
|
||||||
|
|
||||||
void wxGTKRenderer::DrawMenuBarItem(wxDC& dc,
|
void wxGTKRenderer::DrawMenuBarItem(wxDC& dc,
|
||||||
const wxRect& rect,
|
const wxRect& rect,
|
||||||
const wxString& label,
|
const wxString& label,
|
||||||
int flags,
|
int flags,
|
||||||
int indexAccel)
|
int indexAccel)
|
||||||
{
|
{
|
||||||
DrawLabel(dc, label, rect, flags, wxALIGN_CENTRE, indexAccel);
|
DoDrawMenuItem(dc, rect, label, flags, indexAccel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxGTKRenderer::DrawMenuItem(wxDC& dc,
|
void wxGTKRenderer::DrawMenuItem(wxDC& dc,
|
||||||
wxCoord y,
|
wxCoord y,
|
||||||
const wxMenuGeometryInfo& geometryInfo,
|
const wxMenuGeometryInfo& gi,
|
||||||
const wxString& label,
|
const wxString& label,
|
||||||
const wxString& accel,
|
const wxString& accel,
|
||||||
const wxBitmap& bitmap,
|
const wxBitmap& bitmap,
|
||||||
int flags,
|
int flags,
|
||||||
int indexAccel)
|
int indexAccel)
|
||||||
{
|
{
|
||||||
wxFAIL_MSG(_T("TODO"));
|
const wxGTKMenuGeometryInfo& geomInfo = (const wxGTKMenuGeometryInfo&)gi;
|
||||||
|
|
||||||
|
wxRect rect;
|
||||||
|
rect.x = 0;
|
||||||
|
rect.y = y;
|
||||||
|
rect.width = geomInfo.GetSize().x;
|
||||||
|
rect.height = geomInfo.GetItemHeight();
|
||||||
|
|
||||||
|
DoDrawMenuItem(dc, rect, label, flags, indexAccel, accel, bitmap, &geomInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxGTKRenderer::DoDrawMenuItem(wxDC& dc,
|
||||||
|
const wxRect& rectOrig,
|
||||||
|
const wxString& label,
|
||||||
|
int flags,
|
||||||
|
int indexAccel,
|
||||||
|
const wxString& accel,
|
||||||
|
const wxBitmap& bitmap,
|
||||||
|
const wxGTKMenuGeometryInfo *geometryInfo)
|
||||||
|
{
|
||||||
|
wxRect rect = rectOrig;
|
||||||
|
|
||||||
|
// draw the selected item specially
|
||||||
|
if ( flags & wxCONTROL_SELECTED )
|
||||||
|
{
|
||||||
|
wxRect rectIn;
|
||||||
|
DrawBorder(dc, wxBORDER_RAISED, rect, flags, &rectIn);
|
||||||
|
|
||||||
|
DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL_CURRENT), rectIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.Deflate(MENU_HORZ_MARGIN, MENU_VERT_MARGIN);
|
||||||
|
|
||||||
|
// draw the bitmap: use the bitmap provided or the standard checkmark for
|
||||||
|
// the checkable items
|
||||||
|
if ( geometryInfo )
|
||||||
|
{
|
||||||
|
wxBitmap bmp = bitmap;
|
||||||
|
if ( !bmp.Ok() && (flags & wxCONTROL_CHECKABLE) )
|
||||||
|
{
|
||||||
|
bmp = GetCheckBitmap(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bmp.Ok() )
|
||||||
|
{
|
||||||
|
rect.SetRight(geometryInfo->GetLabelOffset());
|
||||||
|
wxControlRenderer::DrawBitmap(dc, bmp, rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//else: menubar items don't have bitmaps
|
||||||
|
|
||||||
|
// draw the label
|
||||||
|
if ( geometryInfo )
|
||||||
|
{
|
||||||
|
rect.x = geometryInfo->GetLabelOffset();
|
||||||
|
rect.SetRight(geometryInfo->GetAccelOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawLabel(dc, label, rect, flags, wxALIGN_CENTRE_VERTICAL, indexAccel);
|
||||||
|
|
||||||
|
// draw the accel string
|
||||||
|
if ( !accel.empty() )
|
||||||
|
{
|
||||||
|
// menubar items shouldn't have them
|
||||||
|
wxCHECK_RET( geometryInfo, _T("accel strings only valid for menus") );
|
||||||
|
|
||||||
|
rect.x = geometryInfo->GetAccelOffset();
|
||||||
|
rect.SetRight(geometryInfo->GetSize().x);
|
||||||
|
|
||||||
|
// NB: no accel index here
|
||||||
|
DrawLabel(dc, accel, rect, flags, wxALIGN_CENTRE_VERTICAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the submenu indicator
|
||||||
|
if ( flags & wxCONTROL_ISSUBMENU )
|
||||||
|
{
|
||||||
|
wxCHECK_RET( geometryInfo, _T("wxCONTROL_ISSUBMENU only valid for menus") );
|
||||||
|
|
||||||
|
rect.x = geometryInfo->GetSize().x - MENU_RIGHT_MARGIN;
|
||||||
|
rect.width = MENU_RIGHT_MARGIN;
|
||||||
|
|
||||||
|
DrawArrow(dc, wxRIGHT, rect, flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxGTKRenderer::DrawMenuSeparator(wxDC& dc,
|
void wxGTKRenderer::DrawMenuSeparator(wxDC& dc,
|
||||||
wxCoord y,
|
wxCoord y,
|
||||||
const wxMenuGeometryInfo& geomInfo)
|
const wxMenuGeometryInfo& geomInfo)
|
||||||
{
|
{
|
||||||
wxFAIL_MSG(_T("TODO"));
|
DrawHorizontalLine(dc, y + MENU_VERT_MARGIN, 0, geomInfo.GetSize().x);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxSize wxGTKRenderer::GetMenuBarItemSize(const wxSize& sizeText) const
|
wxSize wxGTKRenderer::GetMenuBarItemSize(const wxSize& sizeText) const
|
||||||
{
|
{
|
||||||
return sizeText;
|
wxSize size = sizeText;
|
||||||
|
|
||||||
|
// TODO: make this configurable
|
||||||
|
size.x += 2*MENU_HORZ_MARGIN;
|
||||||
|
size.y += 2*MENU_VERT_MARGIN;
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxMenuGeometryInfo *wxGTKRenderer::GetMenuGeometry(wxWindow *win,
|
wxMenuGeometryInfo *wxGTKRenderer::GetMenuGeometry(wxWindow *win,
|
||||||
const wxMenu& menu) const
|
const wxMenu& menu) const
|
||||||
{
|
{
|
||||||
wxFAIL_MSG(_T("TODO"));
|
// prepare the dc: for now we draw all the items with the system font
|
||||||
|
wxClientDC dc(win);
|
||||||
|
dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
|
||||||
|
|
||||||
return NULL;
|
// the height of a normal item
|
||||||
|
wxCoord heightText = dc.GetCharHeight();
|
||||||
|
|
||||||
|
// the total height
|
||||||
|
wxCoord height = 0;
|
||||||
|
|
||||||
|
// the max length of label and accel strings: the menu width is the sum of
|
||||||
|
// them, even if they're for different items (as the accels should be
|
||||||
|
// aligned)
|
||||||
|
//
|
||||||
|
// the max length of the bitmap is never 0 as Windows always leaves enough
|
||||||
|
// space for a check mark indicator
|
||||||
|
wxCoord widthLabelMax = 0,
|
||||||
|
widthAccelMax = 0,
|
||||||
|
widthBmpMax = MENU_LEFT_MARGIN;
|
||||||
|
|
||||||
|
for ( wxMenuItemList::Node *node = menu.GetMenuItems().GetFirst();
|
||||||
|
node;
|
||||||
|
node = node->GetNext() )
|
||||||
|
{
|
||||||
|
// height of this item
|
||||||
|
wxCoord h;
|
||||||
|
|
||||||
|
wxMenuItem *item = node->GetData();
|
||||||
|
if ( item->IsSeparator() )
|
||||||
|
{
|
||||||
|
h = MENU_SEPARATOR_HEIGHT;
|
||||||
|
}
|
||||||
|
else // not separator
|
||||||
|
{
|
||||||
|
h = heightText;
|
||||||
|
|
||||||
|
wxCoord widthLabel;
|
||||||
|
dc.GetTextExtent(item->GetLabel(), &widthLabel, NULL);
|
||||||
|
if ( widthLabel > widthLabelMax )
|
||||||
|
{
|
||||||
|
widthLabelMax = widthLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxCoord widthAccel;
|
||||||
|
dc.GetTextExtent(item->GetAccelString(), &widthAccel, NULL);
|
||||||
|
if ( widthAccel > widthAccelMax )
|
||||||
|
{
|
||||||
|
widthAccelMax = widthAccel;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wxBitmap& bmp = item->GetBitmap();
|
||||||
|
if ( bmp.Ok() )
|
||||||
|
{
|
||||||
|
wxCoord widthBmp = bmp.GetWidth();
|
||||||
|
if ( widthBmp > widthBmpMax )
|
||||||
|
widthBmpMax = widthBmp;
|
||||||
|
}
|
||||||
|
//else if ( item->IsCheckable() ): no need to check for this as
|
||||||
|
// MENU_LEFT_MARGIN is big enough to show the check mark
|
||||||
|
}
|
||||||
|
|
||||||
|
h += 2*MENU_VERT_MARGIN;
|
||||||
|
|
||||||
|
// remember the item position and height
|
||||||
|
item->SetGeometry(height, h);
|
||||||
|
|
||||||
|
height += h;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bundle the metrics into a struct and return it
|
||||||
|
wxGTKMenuGeometryInfo *gi = new wxGTKMenuGeometryInfo;
|
||||||
|
|
||||||
|
gi->m_ofsLabel = widthBmpMax + 2*MENU_BMP_MARGIN;
|
||||||
|
gi->m_ofsAccel = gi->m_ofsLabel + widthLabelMax;
|
||||||
|
if ( widthAccelMax > 0 )
|
||||||
|
{
|
||||||
|
// if we actually have any accesl, add a margin
|
||||||
|
gi->m_ofsAccel += MENU_ACCEL_MARGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
gi->m_heightItem = heightText + 2*MENU_VERT_MARGIN;
|
||||||
|
|
||||||
|
gi->m_size.x = gi->m_ofsAccel + widthAccelMax + MENU_RIGHT_MARGIN;
|
||||||
|
gi->m_size.y = height;
|
||||||
|
|
||||||
|
return gi;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user