📄 gtk.cpp
字号:
// 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, wxCoord y, const wxMenuGeometryInfo& geomInfo){ DrawHorizontalLine(dc, y + MENU_VERT_MARGIN, 0, geomInfo.GetSize().x);}wxSize wxGTKRenderer::GetMenuBarItemSize(const wxSize& sizeText) const{ 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, const wxMenu& menu) const{ // 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)); // 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::compatibility_iterator 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;}#endif // wxUSE_MENUS// ----------------------------------------------------------------------------// combobox// ----------------------------------------------------------------------------void wxGTKRenderer::InitComboBitmaps(){ wxSize sizeArrow = m_sizeScrollbarArrow; sizeArrow.x -= 2; sizeArrow.y -= 2; size_t n; for ( n = ComboState_Normal; n < ComboState_Max; n++ ) { m_bitmapsCombo[n].Create(sizeArrow.x, sizeArrow.y); } static const int comboButtonFlags[ComboState_Max] = { 0, wxCONTROL_CURRENT, wxCONTROL_PRESSED, wxCONTROL_DISABLED, }; wxRect rect(sizeArrow); wxMemoryDC dc; for ( n = ComboState_Normal; n < ComboState_Max; n++ ) { int flags = comboButtonFlags[n]; dc.SelectObject(m_bitmapsCombo[n]); DrawSolidRect(dc, GetBackgroundColour(flags), rect); DrawArrow(dc, wxDOWN, rect, flags); }}void wxGTKRenderer::GetComboBitmaps(wxBitmap *bmpNormal, wxBitmap *bmpFocus, wxBitmap *bmpPressed, wxBitmap *bmpDisabled){ if ( !m_bitmapsCombo[ComboState_Normal].Ok() ) { InitComboBitmaps(); } if ( bmpNormal ) *bmpNormal = m_bitmapsCombo[ComboState_Normal]; if ( bmpFocus ) *bmpFocus = m_bitmapsCombo[ComboState_Focus]; if ( bmpPressed ) *bmpPressed = m_bitmapsCombo[ComboState_Pressed]; if ( bmpDisabled ) *bmpDisabled = m_bitmapsCombo[ComboState_Disabled];}// ----------------------------------------------------------------------------// scrollbar// ----------------------------------------------------------------------------void wxGTKRenderer::DrawArrowBorder(wxDC& dc, wxRect *rect, wxDirection dir){ static const wxDirection sides[] = { wxUP, wxLEFT, wxRIGHT, wxDOWN }; wxRect rect1, rect2, rectInner; rect1 = rect2 = rectInner = *rect; rect2.Inflate(-1); rectInner.Inflate(-2); DrawSolidRect(dc, wxSCHEME_COLOUR(m_scheme, SCROLLBAR), *rect); // find the side not to draw and also adjust the rectangles to compensate // for it wxDirection sideToOmit; switch ( dir ) { case wxUP: sideToOmit = wxDOWN; rect2.height += 1; rectInner.height += 1; break; case wxDOWN: sideToOmit = wxUP; rect2.y -= 1; rect2.height += 1; rectInner.y -= 2; rectInner.height += 1; break; case wxLEFT: sideToOmit = wxRIGHT; rect2.width += 1; rectInner.width += 1; break; case wxRIGHT: sideToOmit = wxLEFT; rect2.x -= 1; rect2.width += 1; rectInner.x -= 2; rectInner.width += 1; break; default: wxFAIL_MSG(_T("unknown arrow direction")); return; } // the outer rect first size_t n; for ( n = 0; n < WXSIZEOF(sides); n++ ) { wxDirection side = sides[n]; if ( side == sideToOmit ) continue; DrawAntiShadedRectSide(dc, rect1, m_penDarkGrey, m_penHighlight, side); } // and then the inner one for ( n = 0; n < WXSIZEOF(sides); n++ ) { wxDirection side = sides[n]; if ( side == sideToOmit ) continue; DrawAntiShadedRectSide(dc, rect2, m_penBlack, m_penGrey, side); } *rect = rectInner;}void wxGTKRenderer::DrawScrollbarArrow(wxDC& dc, wxDirection dir, const wxRect& rectArrow, int flags){ // first of all, draw the border around it - but we don't want the border // on the side opposite to the arrow point wxRect rect = rectArrow; DrawArrowBorder(dc, &rect, dir); // then the arrow itself DrawArrow(dc, dir, rect, flags);}// gtk_default_draw_arrow() takes ~350 lines and we can't do much better here// these people are just crazy :-(void wxGTKRenderer::DrawArrow(wxDC& dc, wxDirection dir, const wxRect& rect, int flags){ enum { Point_First, Point_Second, Point_Third, Point_Max }; wxPoint ptArrow[Point_Max]; wxColour colInside = GetBackgroundColour(flags); wxPen penShadow[4]; if ( flags & wxCONTROL_DISABLED ) { penShadow[0] = m_penDarkGrey; penShadow[1] = m_penDarkGrey; penShadow[2] = wxNullPen; penShadow[3] = wxNullPen; } else if ( flags & wxCONTROL_PRESSED ) { penShadow[0] = m_penDarkGrey; penShadow[1] = m_penHighlight; penShadow[2] = wxNullPen; penShadow[3] = m_penBlack; } else // normal arrow { penShadow[0] = m_penHighlight; penShadow[1] = m_penBlack; penShadow[2] = m_penDarkGrey; penShadow[3] = wxNullPen; } wxCoord middle; if ( dir == wxUP || dir == wxDOWN ) { // horz middle middle = (rect.GetRight() + rect.GetLeft() + 1) / 2; } else // horz arrow { middle = (rect.GetTop() + rect.GetBottom() + 1) / 2; } // draw the arrow interior dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush(colInside); switch ( dir ) { case wxUP: ptArrow[Point_First].x = rect.GetLeft(); ptArrow[Point_First].y = rect.GetBottom(); ptArrow[Point_Second].x = middle; ptArrow[Point_Second].y = rect.GetTop(); ptArrow[Point_Third].x = rect.GetRight(); ptArrow[Point_Third].y = rect.GetBottom(); break; case wxDOWN: ptArrow[Point_First] = rect.GetPosition(); ptArrow[Point_Second].x = middle; ptArrow[Point_Second].y = rect.GetBottom(); ptArrow[Point_Third].x = rect.GetRight(); ptArrow[Point_Third].y = rect.GetTop(); break; case wxLEFT: ptArrow[Point_First].x = rect.GetRight(); ptArrow[Point_First].y = rect.GetTop(); ptArrow[Point_Second].x = rect.GetLeft(); ptArrow[Point_Second].y
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -