1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/themes/gtk.cpp
3 // Purpose: wxUniversal theme implementing GTK-like LNF
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
30 #include "wx/dcmemory.h"
31 #include "wx/window.h"
35 #include "wx/bmpbuttn.h"
36 #include "wx/button.h"
37 #include "wx/checkbox.h"
38 #include "wx/listbox.h"
39 #include "wx/checklst.h"
40 #include "wx/combobox.h"
41 #include "wx/scrolbar.h"
42 #include "wx/slider.h"
43 #include "wx/textctrl.h"
44 #include "wx/toolbar.h"
45 #include "wx/statusbr.h"
47 #include "wx/settings.h"
48 #include "wx/toplevel.h"
52 #include "wx/notebook.h"
53 #include "wx/spinbutt.h"
54 #include "wx/artprov.h"
55 #ifdef wxUSE_TOGGLEBTN
56 #include "wx/tglbtn.h"
57 #endif // wxUSE_TOGGLEBTN
59 #include "wx/univ/stdrend.h"
60 #include "wx/univ/inpcons.h"
61 #include "wx/univ/inphand.h"
62 #include "wx/univ/colschem.h"
63 #include "wx/univ/theme.h"
65 class WXDLLEXPORT wxGTKMenuGeometryInfo
;
67 // ----------------------------------------------------------------------------
69 // ----------------------------------------------------------------------------
71 // standard border size
72 static const int BORDER_THICKNESS
= 2;
74 // ----------------------------------------------------------------------------
75 // wxGTKRenderer: draw the GUI elements in GTK style
76 // ----------------------------------------------------------------------------
78 class wxGTKRenderer
: public wxStdRenderer
81 wxGTKRenderer(const wxColourScheme
*scheme
);
84 virtual void DrawFocusRect(wxDC
& dc
, const wxRect
& rect
);
85 virtual void DrawTextBorder(wxDC
& dc
,
89 wxRect
*rectIn
= NULL
);
90 virtual void DrawButtonLabel(wxDC
& dc
,
91 const wxString
& label
,
92 const wxBitmap
& image
,
98 virtual void DrawButtonBorder(wxDC
& dc
,
101 wxRect
*rectIn
= NULL
);
102 virtual void DrawArrow(wxDC
& dc
,
106 virtual void DrawScrollbarArrow(wxDC
& dc
,
110 virtual void DrawScrollbarThumb(wxDC
& dc
,
111 wxOrientation orient
,
114 virtual void DrawScrollbarShaft(wxDC
& dc
,
115 wxOrientation orient
,
118 virtual void DrawScrollCorner(wxDC
& dc
,
120 virtual void DrawCheckItem(wxDC
& dc
,
121 const wxString
& label
,
122 const wxBitmap
& bitmap
,
127 virtual void DrawToolBarButton(wxDC
& dc
,
128 const wxString
& label
,
129 const wxBitmap
& bitmap
,
134 #endif // wxUSE_TOOLBAR
137 virtual void DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
);
138 #endif // wxUSE_TEXTCTRL
141 virtual void DrawTab(wxDC
& dc
,
144 const wxString
& label
,
145 const wxBitmap
& bitmap
= wxNullBitmap
,
147 int indexAccel
= -1);
148 #endif // wxUSE_NOTEBOOK
151 virtual void DrawSliderShaft(wxDC
& dc
,
154 wxOrientation orient
,
157 wxRect
*rectShaft
= NULL
);
158 virtual void DrawSliderThumb(wxDC
& dc
,
160 wxOrientation orient
,
163 virtual void DrawSliderTicks(wxDC
& WXUNUSED(dc
),
164 const wxRect
& WXUNUSED(rect
),
165 int WXUNUSED(lenThumb
),
166 wxOrientation
WXUNUSED(orient
),
169 int WXUNUSED(step
) = 1,
170 int WXUNUSED(flags
) = 0,
171 long WXUNUSED(style
) = 0)
173 // we don't have the ticks in GTK version
175 #endif // wxUSE_SLIDER
178 virtual void DrawMenuBarItem(wxDC
& dc
,
180 const wxString
& label
,
182 int indexAccel
= -1);
183 virtual void DrawMenuItem(wxDC
& dc
,
185 const wxMenuGeometryInfo
& geometryInfo
,
186 const wxString
& label
,
187 const wxString
& accel
,
188 const wxBitmap
& bitmap
= wxNullBitmap
,
190 int indexAccel
= -1);
191 virtual void DrawMenuSeparator(wxDC
& dc
,
193 const wxMenuGeometryInfo
& geomInfo
);
194 #endif // wxUSE_MENUS
197 virtual void DrawStatusField(wxDC
& dc
,
199 const wxString
& label
,
200 int flags
= 0, int style
= 0);
201 #endif // wxUSE_STATUSBAR
203 virtual void DrawFrameTitleBar(wxDC
& dc
,
205 const wxString
& title
,
208 int specialButton
= 0,
209 int specialButtonFlag
= 0);
210 virtual void DrawFrameBorder(wxDC
& dc
,
213 virtual void DrawFrameBackground(wxDC
& dc
,
216 virtual void DrawFrameTitle(wxDC
& dc
,
218 const wxString
& title
,
220 virtual void DrawFrameIcon(wxDC
& dc
,
224 virtual void DrawFrameButton(wxDC
& dc
,
225 wxCoord x
, wxCoord y
,
230 virtual wxRect
GetFrameClientArea(const wxRect
& rect
, int flags
) const;
231 virtual wxSize
GetFrameTotalSize(const wxSize
& clientSize
, int flags
) const;
232 virtual wxSize
GetFrameMinSize(int flags
) const;
233 virtual wxSize
GetFrameIconSize() const;
234 virtual int HitTestFrame(const wxRect
& rect
, const wxPoint
& pt
, int flags
) const;
236 virtual void GetComboBitmaps(wxBitmap
*bmpNormal
,
238 wxBitmap
*bmpPressed
,
239 wxBitmap
*bmpDisabled
);
241 virtual void AdjustSize(wxSize
*size
, const wxWindow
*window
);
243 // geometry and hit testing
244 virtual wxSize
GetScrollbarArrowSize() const
245 { return m_sizeScrollbarArrow
; }
247 virtual wxRect
GetScrollbarRect(const wxScrollBar
*scrollbar
,
248 wxScrollBar::Element elem
,
249 int thumbPos
= -1) const;
250 #endif // wxUSE_SCROLLBAR
252 virtual wxCoord
GetListboxItemHeight(wxCoord fontHeight
)
253 { return fontHeight
+ 2; }
254 virtual wxSize
GetCheckBitmapSize() const
255 { return wxSize(10, 10); }
256 virtual wxSize
GetRadioBitmapSize() const
257 { return wxSize(11, 11); }
258 virtual wxCoord
GetCheckItemMargin() const
261 virtual wxSize
GetToolBarButtonSize(wxCoord
*separator
) const
262 { if ( separator
) *separator
= 5; return wxSize(16, 15); }
263 virtual wxSize
GetToolBarMargin() const
264 { return wxSize(6, 6); }
267 virtual wxRect
GetTextTotalArea(const wxTextCtrl
*text
,
268 const wxRect
& rect
) const;
269 virtual wxRect
GetTextClientArea(const wxTextCtrl
*text
,
271 wxCoord
*extraSpaceBeyond
) const;
272 #endif // wxUSE_TEXTCTRL
275 virtual wxSize
GetTabIndent() const { return wxSize(2, 2); }
276 virtual wxSize
GetTabPadding() const { return wxSize(6, 6); }
277 #endif // wxUSE_NOTEBOOK
280 virtual wxCoord
GetSliderDim() const { return 15; }
281 virtual wxCoord
GetSliderTickLen() const { return 0; }
282 virtual wxRect
GetSliderShaftRect(const wxRect
& rect
,
284 wxOrientation orient
,
285 long style
= 0) const;
286 virtual wxSize
GetSliderThumbSize(const wxRect
& rect
,
288 wxOrientation orient
) const;
289 #endif // wxUSE_SLIDER
291 virtual wxSize
GetProgressBarStep() const { return wxSize(16, 32); }
294 virtual wxSize
GetMenuBarItemSize(const wxSize
& sizeText
) const;
295 virtual wxMenuGeometryInfo
*GetMenuGeometry(wxWindow
*win
,
296 const wxMenu
& menu
) const;
297 #endif // wxUSE_MENUS
300 virtual wxSize
GetStatusBarBorders(wxCoord
*borderBetweenFields
) const;
301 #endif // wxUSE_STATUSBAR
303 // helpers for "wxBitmap wxColourScheme::Get()"
304 void DrawCheckBitmap(wxDC
& dc
, const wxRect
& rect
);
305 void DrawUncheckBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
306 void DrawUndeterminedBitmap(wxDC
& dc
, const wxRect
& rect
, bool isPressed
);
309 virtual void DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
);
311 virtual void DrawFrameWithLabel(wxDC
& dc
,
312 const wxString
& label
,
313 const wxRect
& rectFrame
,
314 const wxRect
& rectText
,
319 // get the colour to use for background
320 wxColour
GetBackgroundColour(int flags
) const
322 if ( flags
& wxCONTROL_PRESSED
)
323 return wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
324 else if ( flags
& wxCONTROL_CURRENT
)
325 return wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
);
327 return wxSCHEME_COLOUR(m_scheme
, CONTROL
);
330 // as DrawShadedRect() but the pixels in the bottom left and upper right
331 // border are drawn with the pen1, not pen2
332 void DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
333 const wxPen
& pen1
, const wxPen
& pen2
);
335 // used for drawing opened rectangles - draws only one side of it at once
336 // (and doesn't adjust the rect)
337 void DrawAntiShadedRectSide(wxDC
& dc
,
343 // draw an opened rect for the arrow in given direction
344 void DrawArrowBorder(wxDC
& dc
,
348 // draw two sides of the rectangle
349 void DrawThumbBorder(wxDC
& dc
,
351 wxOrientation orient
);
353 // just as DrawRaisedBorder() except that the bottom left and up right
354 // pixels of the interior rect are drawn in another colour (i.e. the inner
355 // rect is drawn with DrawAntiShadedRect() and not DrawShadedRect())
356 void DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
);
358 // draw inner GTK shadow
359 void DrawInnerShadedRect(wxDC
& dc
, wxRect
*rect
);
362 // returns the size of the arrow for the scrollbar (depends on
364 wxSize
GetScrollbarArrowSize(const wxScrollBar
*scrollbar
) const
367 if ( scrollbar
->IsVertical() )
369 size
= m_sizeScrollbarArrow
;
373 size
.x
= m_sizeScrollbarArrow
.y
;
374 size
.y
= m_sizeScrollbarArrow
.x
;
379 #endif // wxUSE_SCROLLBAR
381 // get the line wrap indicator bitmap
382 wxBitmap
GetLineWrapBitmap() const;
384 virtual wxBitmap
GetCheckBitmap(int flags
);
385 virtual wxBitmap
GetRadioBitmap(int flags
);
387 // draw a /\ or \/ line from (x1, y1) to (x2, y1) passing by the point
389 void DrawUpZag(wxDC
& dc
,
390 wxCoord x1
, wxCoord x2
,
391 wxCoord y1
, wxCoord y2
);
392 void DrawDownZag(wxDC
& dc
,
393 wxCoord x1
, wxCoord x2
,
394 wxCoord y1
, wxCoord y2
);
396 // draw the radio button bitmap for the given state
397 void DrawRadioBitmap(wxDC
& dc
, const wxRect
& rect
, int flags
);
399 // draw check/radio - the bitmap must be a valid one by now
400 void DoDrawCheckOrRadioBitmap(wxDC
& dc
,
401 const wxString
& label
,
402 const wxBitmap
& bitmap
,
403 const wxRect
& rectTotal
,
408 // common part of DrawMenuItem() and DrawMenuBarItem()
409 void DoDrawMenuItem(wxDC
& dc
,
411 const wxString
& label
,
414 const wxString
& accel
= wxEmptyString
,
415 const wxBitmap
& bitmap
= wxNullBitmap
,
416 const wxGTKMenuGeometryInfo
*geometryInfo
= NULL
);
418 // initialize the combo bitmaps
419 void InitComboBitmaps();
422 const wxColourScheme
*m_scheme
;
425 wxSize m_sizeScrollbarArrow
;
430 // the checkbox and radio button bitmaps: first row is for the normal,
431 // second for the pressed state and the columns are for checked, unchecked
432 // and undeterminated respectively
433 wxBitmap m_bitmapsCheckbox
[IndicatorState_MaxCtrl
][IndicatorStatus_Max
],
434 m_bitmapsRadiobtn
[IndicatorState_MaxCtrl
][IndicatorStatus_Max
];
436 // the line wrap bitmap (drawn at the end of wrapped lines)
437 wxBitmap m_bmpLineWrap
;
439 // the combobox bitmaps
449 wxBitmap m_bitmapsCombo
[ComboState_Max
];
452 // ----------------------------------------------------------------------------
453 // wxGTKInputHandler and derived classes: process the keyboard and mouse
454 // messages according to GTK standards
455 // ----------------------------------------------------------------------------
457 class wxGTKInputHandler
: public wxInputHandler
460 wxGTKInputHandler() { }
462 virtual bool HandleKey(wxInputConsumer
*control
,
463 const wxKeyEvent
& event
,
465 virtual bool HandleMouse(wxInputConsumer
*control
,
466 const wxMouseEvent
& event
);
467 virtual bool HandleMouseMove(wxInputConsumer
*control
,
468 const wxMouseEvent
& event
);
473 class wxGTKScrollBarInputHandler
: public wxStdScrollBarInputHandler
476 wxGTKScrollBarInputHandler(wxRenderer
*renderer
, wxInputHandler
*handler
)
477 : wxStdScrollBarInputHandler(renderer
, handler
) { }
480 virtual void Highlight(wxScrollBar
*scrollbar
, bool doIt
)
482 // only arrows and the thumb can be highlighted
483 if ( !IsArrow() && m_htLast
!= wxHT_SCROLLBAR_THUMB
)
486 wxStdScrollBarInputHandler::Highlight(scrollbar
, doIt
);
489 virtual void Press(wxScrollBar
*scrollbar
, bool doIt
)
491 // only arrows can be pressed
495 wxStdScrollBarInputHandler::Press(scrollbar
, doIt
);
498 // any button can be used to drag the scrollbar under GTK+
499 virtual bool IsAllowedButton(int WXUNUSED(button
)) const { return true; }
503 return m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_1
||
504 m_htLast
== wxHT_SCROLLBAR_ARROW_LINE_2
;
508 #endif // wxUSE_SCROLLBAR
512 class wxGTKCheckboxInputHandler
: public wxStdInputHandler
515 wxGTKCheckboxInputHandler(wxInputHandler
*handler
)
516 : wxStdInputHandler(handler
) { }
518 virtual bool HandleKey(wxInputConsumer
*control
,
519 const wxKeyEvent
& event
,
523 #endif // wxUSE_CHECKBOX
527 class wxGTKTextCtrlInputHandler
: public wxStdInputHandler
530 wxGTKTextCtrlInputHandler(wxInputHandler
*handler
)
531 : wxStdInputHandler(handler
) { }
533 virtual bool HandleKey(wxInputConsumer
*control
,
534 const wxKeyEvent
& event
,
538 #endif // wxUSE_TEXTCTRL
540 // ----------------------------------------------------------------------------
541 // wxGTKColourScheme: uses the standard GTK colours
542 // ----------------------------------------------------------------------------
544 class wxGTKColourScheme
: public wxColourScheme
547 virtual wxColour
Get(StdColour col
) const;
548 virtual wxColour
GetBackground(wxWindow
*win
) const;
551 // ----------------------------------------------------------------------------
553 // ----------------------------------------------------------------------------
555 class wxGTKArtProvider
: public wxArtProvider
558 virtual wxBitmap
CreateBitmap(const wxArtID
& id
,
559 const wxArtClient
& client
,
563 // ----------------------------------------------------------------------------
565 // ----------------------------------------------------------------------------
567 WX_DEFINE_ARRAY_PTR(wxInputHandler
*, wxArrayHandlers
);
569 class wxGTKTheme
: public wxTheme
573 virtual ~wxGTKTheme();
575 virtual wxRenderer
*GetRenderer();
576 virtual wxArtProvider
*GetArtProvider();
577 virtual wxInputHandler
*GetInputHandler(const wxString
& control
,
578 wxInputConsumer
*consumer
);
579 virtual wxColourScheme
*GetColourScheme();
582 wxGTKRenderer
*m_renderer
;
584 wxGTKArtProvider
*m_artProvider
;
586 // the names of the already created handlers and the handlers themselves
587 // (these arrays are synchronized)
588 wxSortedArrayString m_handlerNames
;
589 wxArrayHandlers m_handlers
;
591 wxGTKInputHandler
*m_handlerDefault
;
593 wxGTKColourScheme
*m_scheme
;
595 WX_DECLARE_THEME(gtk
)
598 // ============================================================================
600 // ============================================================================
602 WX_IMPLEMENT_THEME(wxGTKTheme
, gtk
, wxTRANSLATE("GTK+ theme"));
604 // ----------------------------------------------------------------------------
606 // ----------------------------------------------------------------------------
608 wxGTKTheme::wxGTKTheme()
612 m_handlerDefault
= NULL
;
613 m_artProvider
= NULL
;
616 wxGTKTheme::~wxGTKTheme()
618 size_t count
= m_handlers
.GetCount();
619 for ( size_t n
= 0; n
< count
; n
++ )
621 if ( m_handlers
[n
] != m_handlerDefault
)
622 delete m_handlers
[n
];
625 delete m_handlerDefault
;
628 wxArtProvider::RemoveProvider(m_artProvider
);
631 wxRenderer
*wxGTKTheme::GetRenderer()
635 m_renderer
= new wxGTKRenderer(GetColourScheme());
641 wxArtProvider
*wxGTKTheme::GetArtProvider()
643 if ( !m_artProvider
)
645 m_artProvider
= new wxGTKArtProvider
;
648 return m_artProvider
;
651 wxColourScheme
*wxGTKTheme::GetColourScheme()
655 m_scheme
= new wxGTKColourScheme
;
660 wxInputHandler
*wxGTKTheme::GetInputHandler(const wxString
& control
,
661 wxInputConsumer
*consumer
)
663 wxInputHandler
*handler
= NULL
;
664 int n
= m_handlerNames
.Index(control
);
665 if ( n
== wxNOT_FOUND
)
667 static wxGTKInputHandler s_handlerDef
;
669 wxInputHandler
* const
670 handlerStd
= consumer
->DoGetStdInputHandler(&s_handlerDef
);
672 // create a new handler
674 if ( control
== wxINP_HANDLER_CHECKBOX
)
676 static wxGTKCheckboxInputHandler
s_handler(handlerStd
);
678 handler
= &s_handler
;
681 #endif // wxUSE_CHECKBOX
683 if ( control
== wxINP_HANDLER_SCROLLBAR
)
685 static wxGTKScrollBarInputHandler
s_handler(m_renderer
, handlerStd
);
687 handler
= &s_handler
;
690 #endif // wxUSE_SCROLLBAR
692 if ( control
== wxINP_HANDLER_TEXTCTRL
)
694 static wxGTKTextCtrlInputHandler
s_handler(handlerStd
);
696 handler
= &s_handler
;
699 #endif // wxUSE_TEXTCTRL
701 // no special handler for this control
702 handler
= handlerStd
;
705 n
= m_handlerNames
.Add(control
);
706 m_handlers
.Insert(handler
, n
);
708 else // we already have it
710 handler
= m_handlers
[n
];
716 // ============================================================================
718 // ============================================================================
720 wxColour
wxGTKColourScheme::GetBackground(wxWindow
*win
) const
723 if ( win
->UseBgCol() )
725 // use the user specified colour
726 col
= win
->GetBackgroundColour();
729 if ( !win
->ShouldInheritColours() )
731 // doesn't depend on the state
739 int flags
= win
->GetStateFlags();
741 // the colour set by the user should be used for the normal state
742 // and for the states for which we don't have any specific colours
743 if ( !col
.Ok() || (flags
!= 0) )
746 if ( wxDynamicCast(win
, wxScrollBar
) )
747 col
= Get(SCROLLBAR
);
749 #endif //wxUSE_SCROLLBAR
750 if ( (flags
& wxCONTROL_CURRENT
) && win
->CanBeHighlighted() )
751 col
= Get(CONTROL_CURRENT
);
752 else if ( flags
& wxCONTROL_PRESSED
)
753 col
= Get(CONTROL_PRESSED
);
762 wxColour
wxGTKColourScheme::Get(wxGTKColourScheme::StdColour col
) const
766 case WINDOW
: return *wxWHITE
;
768 case SHADOW_DARK
: return *wxBLACK
;
769 case SHADOW_HIGHLIGHT
: return *wxWHITE
;
770 case SHADOW_IN
: return wxColour(0xd6d6d6);
771 case SHADOW_OUT
: return wxColour(0x969696);
773 case CONTROL
: return wxColour(0xd6d6d6);
774 case CONTROL_PRESSED
: return wxColour(0xc3c3c3);
775 case CONTROL_CURRENT
: return wxColour(0xeaeaea);
777 case CONTROL_TEXT
: return *wxBLACK
;
778 case CONTROL_TEXT_DISABLED
:
779 return wxColour(0x757575);
780 case CONTROL_TEXT_DISABLED_SHADOW
:
784 case SCROLLBAR_PRESSED
: return wxColour(0xc3c3c3);
786 case HIGHLIGHT
: return wxColour(0x9c0000);
787 case HIGHLIGHT_TEXT
: return wxColour(0xffffff);
789 case GAUGE
: return Get(CONTROL_CURRENT
);
791 case TITLEBAR
: return wxColour(0xaeaaae);
792 case TITLEBAR_ACTIVE
: return wxColour(0x820300);
793 case TITLEBAR_TEXT
: return wxColour(0xc0c0c0);
794 case TITLEBAR_ACTIVE_TEXT
:
797 case DESKTOP
: return *wxBLACK
;
801 wxFAIL_MSG(_T("invalid standard colour"));
806 // ============================================================================
808 // ============================================================================
810 // ----------------------------------------------------------------------------
812 // ----------------------------------------------------------------------------
814 wxGTKRenderer::wxGTKRenderer(const wxColourScheme
*scheme
)
815 : wxStdRenderer(scheme
)
817 m_sizeScrollbarArrow
= wxSize(15, 14);
819 m_penGrey
= wxPen(wxSCHEME_COLOUR(scheme
, SCROLLBAR
));
822 // ----------------------------------------------------------------------------
824 // ----------------------------------------------------------------------------
826 void wxGTKRenderer::DrawAntiShadedRectSide(wxDC
& dc
,
832 dc
.SetPen(dir
== wxLEFT
|| dir
== wxUP
? pen1
: pen2
);
837 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
838 rect
.GetLeft(), rect
.GetBottom() + 1);
842 dc
.DrawLine(rect
.GetLeft(), rect
.GetTop(),
843 rect
.GetRight() + 1, rect
.GetTop());
847 dc
.DrawLine(rect
.GetRight(), rect
.GetTop(),
848 rect
.GetRight(), rect
.GetBottom() + 1);
852 dc
.DrawLine(rect
.GetLeft(), rect
.GetBottom(),
853 rect
.GetRight() + 1, rect
.GetBottom());
857 wxFAIL_MSG(_T("unknown rectangle side"));
861 void wxGTKRenderer::DrawAntiShadedRect(wxDC
& dc
, wxRect
*rect
,
862 const wxPen
& pen1
, const wxPen
& pen2
)
864 // draw the rectangle
866 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
867 rect
->GetLeft(), rect
->GetBottom() + 1);
868 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
869 rect
->GetRight() + 1, rect
->GetTop());
871 dc
.DrawLine(rect
->GetRight(), rect
->GetTop() + 1,
872 rect
->GetRight(), rect
->GetBottom());
873 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetBottom(),
874 rect
->GetRight() + 1, rect
->GetBottom());
880 void wxGTKRenderer::DrawInnerShadedRect(wxDC
& dc
, wxRect
*rect
)
882 DrawAntiShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
883 DrawAntiShadedRect(dc
, rect
, m_penBlack
, m_penHighlight
);
886 void wxGTKRenderer::DrawAntiRaisedBorder(wxDC
& dc
, wxRect
*rect
)
888 DrawShadedRect(dc
, rect
, m_penHighlight
, m_penBlack
);
889 DrawAntiShadedRect(dc
, rect
, m_penLightGrey
, m_penDarkGrey
);
892 void wxGTKRenderer::DrawSunkenBorder(wxDC
& dc
, wxRect
*rect
)
894 DrawAntiShadedRect(dc
, rect
, m_penDarkGrey
, m_penHighlight
);
895 DrawShadedRect(dc
, rect
, m_penBlack
, m_penLightGrey
);
898 void wxGTKRenderer::DrawFocusRect(wxDC
& dc
, const wxRect
& rect
)
900 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
901 wxRect rectFocus
= rect
;
902 DrawRect(dc
, &rectFocus
, m_penBlack
);
905 void wxGTKRenderer::DrawTextBorder(wxDC
& dc
,
907 const wxRect
& rectOrig
,
911 wxRect rect
= rectOrig
;
913 if ( border
!= wxBORDER_NONE
)
915 if ( flags
& wxCONTROL_FOCUSED
)
917 DrawRect(dc
, &rect
, m_penBlack
);
918 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
922 DrawInnerShadedRect(dc
, &rect
);
930 void wxGTKRenderer::DrawButtonLabel(wxDC
& dc
,
931 const wxString
& label
,
932 const wxBitmap
& image
,
939 // no focus rect around buttons label in GTK+
940 wxStdRenderer::DrawButtonLabel(dc
, label
, image
, rect
, flags
,
941 alignment
, indexAccel
, rectBounds
);
944 void wxGTKRenderer::DrawButtonBorder(wxDC
& dc
,
945 const wxRect
& rectTotal
,
949 wxRect rect
= rectTotal
;
951 if ( flags
& wxCONTROL_PRESSED
)
953 // button pressed: draw a black border around it and an inward shade
954 DrawRect(dc
, &rect
, m_penBlack
);
956 DrawInnerShadedRect(dc
, &rect
);
958 else // button not pressed
960 if ( flags
& wxCONTROL_ISDEFAULT
)
965 if ( flags
& wxCONTROL_FOCUSED
)
967 // button is currently default: add an extra border around it
968 DrawRect(dc
, &rect
, m_penBlack
);
971 // now draw a normal button
972 DrawShadedRect(dc
, &rect
, m_penHighlight
, m_penBlack
);
973 DrawAntiShadedRect(dc
, &rect
, GetBackgroundColour(flags
), m_penDarkGrey
);
980 // ----------------------------------------------------------------------------
982 // ----------------------------------------------------------------------------
984 void wxGTKRenderer::DrawFrameWithLabel(wxDC
& dc
,
985 const wxString
& label
,
986 const wxRect
& rectFrame
,
987 const wxRect
& rectTextOrig
,
992 wxRect
rectText(rectTextOrig
);
993 rectText
.Inflate(1, 0);
996 DrawLabel(dc
, label
, rectText
, flags
, alignment
, indexAccel
, &rectLabel
);
998 rectLabel
.width
+= 2;
1000 DrawFrameWithoutLabel(dc
, rectFrame
, rectLabel
);
1002 // GTK+ does it like this
1003 dc
.SetPen(m_penHighlight
);
1004 dc
.DrawPoint(rectText
.x
, rectFrame
.y
);
1005 dc
.DrawPoint(rectText
.x
+ rectLabel
.width
- 3, rectFrame
.y
);
1008 // ----------------------------------------------------------------------------
1010 // ----------------------------------------------------------------------------
1012 void wxGTKRenderer::DrawCheckItem(wxDC
& dc
,
1013 const wxString
& label
,
1014 const wxBitmap
& bitmap
,
1018 wxRect rectBitmap
= rect
;
1020 rectBitmap
.width
= GetCheckBitmapSize().x
;
1022 // never draw the focus rect around the check indicators here
1023 DrawCheckButton(dc
, wxEmptyString
, bitmap
, rectBitmap
, flags
& ~wxCONTROL_FOCUSED
);
1025 wxRect rectLabel
= rect
;
1026 wxCoord shift
= rectBitmap
.width
+ 2*GetCheckItemMargin();
1027 rectLabel
.x
+= shift
;
1028 rectLabel
.width
-= shift
;
1029 DrawItem(dc
, label
, rectLabel
, flags
);
1032 // ----------------------------------------------------------------------------
1033 // check/radion buttons
1034 // ----------------------------------------------------------------------------
1036 void wxGTKRenderer::DrawUndeterminedBitmap(wxDC
& dc
,
1037 const wxRect
& rectTotal
,
1040 // FIXME: For sure it is not GTK look but it is better than nothing.
1041 // Show me correct look and I will immediatelly make it better (ABX)
1042 wxRect rect
= rectTotal
;
1044 wxColour col1
, col2
;
1048 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
1049 col2
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1053 col1
= wxSCHEME_COLOUR(m_scheme
, SHADOW_DARK
);
1054 col2
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1057 dc
.SetPen(*wxTRANSPARENT_PEN
);
1059 dc
.DrawRectangle(rect
);
1062 dc
.DrawRectangle(rect
);
1065 void wxGTKRenderer::DrawUncheckBitmap(wxDC
& dc
,
1066 const wxRect
& rectTotal
,
1069 wxRect rect
= rectTotal
;
1070 DrawAntiRaisedBorder(dc
, &rect
);
1072 wxColour col
= wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
);
1073 dc
.SetPen(wxPen(col
));
1074 dc
.DrawPoint(rect
.GetRight() - 1, rect
.GetBottom() - 1);
1077 col
= wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
);
1078 //else: it is SHADOW_IN, leave as is
1080 dc
.SetPen(*wxTRANSPARENT_PEN
);
1082 dc
.DrawRectangle(rect
);
1085 void wxGTKRenderer::DrawCheckBitmap(wxDC
& dc
, const wxRect
& rectTotal
)
1087 wxRect rect
= rectTotal
;
1088 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1089 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1091 dc
.SetPen(*wxTRANSPARENT_PEN
);
1092 dc
.SetBrush(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
));
1093 dc
.DrawRectangle(rect
);
1096 void wxGTKRenderer::DrawRadioBitmap(wxDC
& dc
,
1102 xRight
= rect
.GetRight(),
1103 yBottom
= rect
.GetBottom();
1105 wxCoord yMid
= (y
+ yBottom
) / 2;
1107 // then draw the upper half
1108 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penDarkGrey
: m_penHighlight
);
1109 DrawUpZag(dc
, x
, xRight
, yMid
, y
);
1110 DrawUpZag(dc
, x
+ 1, xRight
- 1, yMid
, y
+ 1);
1113 if ( flags
& wxCONTROL_CHECKED
)
1114 dc
.SetPen(m_penBlack
);
1115 else if ( flags
& wxCONTROL_PRESSED
)
1116 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
)));
1117 else // unchecked and unpressed
1121 DrawUpZag(dc
, x
+ 2, xRight
- 2, yMid
, y
+ 2);
1123 // and then the lower one
1124 dc
.SetPen(flags
& wxCONTROL_CHECKED
? m_penHighlight
: m_penBlack
);
1125 DrawDownZag(dc
, x
, xRight
, yMid
, yBottom
);
1126 if ( !(flags
& wxCONTROL_CHECKED
) )
1127 dc
.SetPen(m_penDarkGrey
);
1128 DrawDownZag(dc
, x
+ 1, xRight
- 1, yMid
, yBottom
- 1);
1130 if ( !(flags
& wxCONTROL_CHECKED
) )
1131 drawIt
= true; // with the same pen
1132 else if ( flags
& wxCONTROL_PRESSED
)
1134 dc
.SetPen(wxPen(wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
)));
1137 else // checked and unpressed
1141 DrawDownZag(dc
, x
+ 2, xRight
- 2, yMid
, yBottom
- 2);
1144 void wxGTKRenderer::DrawUpZag(wxDC
& dc
,
1150 wxCoord xMid
= (x1
+ x2
) / 2;
1151 dc
.DrawLine(x1
, y1
, xMid
, y2
);
1152 dc
.DrawLine(xMid
, y2
, x2
+ 1, y1
+ 1);
1155 void wxGTKRenderer::DrawDownZag(wxDC
& dc
,
1161 wxCoord xMid
= (x1
+ x2
) / 2;
1162 dc
.DrawLine(x1
+ 1, y1
+ 1, xMid
, y2
);
1163 dc
.DrawLine(xMid
, y2
, x2
, y1
);
1166 wxBitmap
wxGTKRenderer::GetCheckBitmap(int flags
)
1168 if ( !m_bitmapsCheckbox
[0][0].Ok() )
1170 // init the bitmaps once only
1172 wxSize size
= GetCheckBitmapSize();
1173 rect
.width
= size
.x
;
1174 rect
.height
= size
.y
;
1175 for ( int i
= 0; i
< 2; i
++ )
1177 for ( int j
= 0; j
< 3; j
++ )
1178 m_bitmapsCheckbox
[i
][j
].Create(rect
.width
, rect
.height
);
1184 dc
.SelectObject(m_bitmapsCheckbox
[0][0]);
1185 DrawCheckBitmap(dc
, rect
);
1188 dc
.SelectObject(m_bitmapsCheckbox
[0][1]);
1189 DrawUncheckBitmap(dc
, rect
, false);
1191 // normal undeterminated
1192 dc
.SelectObject(m_bitmapsCheckbox
[0][2]);
1193 DrawUndeterminedBitmap(dc
, rect
, false);
1196 m_bitmapsCheckbox
[1][0] = m_bitmapsCheckbox
[0][0];
1198 // pressed unchecked
1199 dc
.SelectObject(m_bitmapsCheckbox
[1][1]);
1200 DrawUncheckBitmap(dc
, rect
, true);
1202 // pressed undeterminated
1203 dc
.SelectObject(m_bitmapsCheckbox
[1][2]);
1204 DrawUndeterminedBitmap(dc
, rect
, true);
1207 IndicatorState state
;
1208 IndicatorStatus status
;
1209 GetIndicatorsFromFlags(flags
, state
, status
);
1211 // disabled looks the same as normal
1212 if ( state
== IndicatorState_Disabled
)
1213 state
= IndicatorState_Normal
;
1215 return m_bitmapsCheckbox
[state
][status
];
1218 wxBitmap
wxGTKRenderer::GetRadioBitmap(int flags
)
1220 IndicatorState state
;
1221 IndicatorStatus status
;
1222 GetIndicatorsFromFlags(flags
, state
, status
);
1224 wxBitmap
& bmp
= m_bitmapsRadiobtn
[state
][status
];
1227 const wxSize size
= GetRadioBitmapSize();
1230 bmp
.Create(size
.x
, size
.y
);
1231 dc
.SelectObject(bmp
);
1233 DrawRadioBitmap(dc
, size
, flags
);
1239 wxBitmap
wxGTKRenderer::GetLineWrapBitmap() const
1241 if ( !m_bmpLineWrap
.Ok() )
1243 // the line wrap bitmap as used by GTK+
1244 #define line_wrap_width 6
1245 #define line_wrap_height 9
1246 static const char line_wrap_bits
[] =
1248 0x1e, 0x3e, 0x30, 0x30, 0x39, 0x1f, 0x0f, 0x0f, 0x1f,
1251 wxBitmap
bmpLineWrap(line_wrap_bits
, line_wrap_width
, line_wrap_height
);
1252 if ( !bmpLineWrap
.Ok() )
1254 wxFAIL_MSG( _T("Failed to create line wrap XBM") );
1258 wxConstCast(this, wxGTKRenderer
)->m_bmpLineWrap
= bmpLineWrap
;
1262 return m_bmpLineWrap
;
1266 void wxGTKRenderer::DrawToolBarButton(wxDC
& dc
,
1267 const wxString
& label
,
1268 const wxBitmap
& bitmap
,
1269 const wxRect
& rectOrig
,
1271 long WXUNUSED(style
),
1274 // we don't draw the separators at all
1275 if ( !label
.empty() || bitmap
.Ok() )
1277 wxRect rect
= rectOrig
;
1278 rect
.Deflate(BORDER_THICKNESS
);
1280 if ( flags
& wxCONTROL_PRESSED
)
1282 DrawBorder(dc
, wxBORDER_SUNKEN
, rect
, flags
, &rect
);
1284 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_PRESSED
), rect
);
1286 else if ( flags
& wxCONTROL_CURRENT
)
1288 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rect
);
1290 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rect
);
1293 if(tbarStyle
& wxTB_TEXT
)
1295 if(tbarStyle
& wxTB_HORIZONTAL
)
1297 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_CENTRE
);
1301 dc
.DrawLabel(label
, bitmap
, rect
, wxALIGN_LEFT
|wxALIGN_CENTER_VERTICAL
);
1306 int xpoint
= (rect
.GetLeft() + rect
.GetRight() + 1 - bitmap
.GetWidth()) / 2;
1307 int ypoint
= (rect
.GetTop() + rect
.GetBottom() + 1 - bitmap
.GetHeight()) / 2;
1308 dc
.DrawBitmap(bitmap
, xpoint
, ypoint
);
1312 #endif // wxUSE_TOOLBAR
1314 // ----------------------------------------------------------------------------
1316 // ----------------------------------------------------------------------------
1320 wxRect
wxGTKRenderer::GetTextTotalArea(const wxTextCtrl
* WXUNUSED(text
),
1321 const wxRect
& rect
) const
1323 wxRect rectTotal
= rect
;
1324 rectTotal
.Inflate(2*BORDER_THICKNESS
);
1328 wxRect
wxGTKRenderer::GetTextClientArea(const wxTextCtrl
*text
,
1330 wxCoord
*extraSpaceBeyond
) const
1332 wxRect rectText
= rect
;
1333 rectText
.Deflate(2*BORDER_THICKNESS
);
1335 if ( text
->WrapLines() )
1337 // leave enough for the line wrap bitmap indicator
1338 wxCoord widthMark
= GetLineWrapBitmap().GetWidth() + 2;
1340 rectText
.width
-= widthMark
;
1342 if ( extraSpaceBeyond
)
1343 *extraSpaceBeyond
= widthMark
;
1349 #endif // wxUSE_TEXTCTRL
1351 void wxGTKRenderer::DrawLineWrapMark(wxDC
& dc
, const wxRect
& rect
)
1353 wxBitmap bmpLineWrap
= GetLineWrapBitmap();
1355 // for a mono bitmap he colours it appears in depends on the current text
1356 // colours, so set them correctly
1358 if ( bmpLineWrap
.GetDepth() == 1 )
1360 colFgOld
= dc
.GetTextForeground();
1362 // FIXME: I wonder what should we do if the background is black too?
1363 dc
.SetTextForeground(*wxBLACK
);
1366 dc
.DrawBitmap(bmpLineWrap
,
1367 rect
.x
, rect
.y
+ (rect
.height
- bmpLineWrap
.GetHeight())/2);
1369 if ( colFgOld
.Ok() )
1371 // restore old colour
1372 dc
.SetTextForeground(colFgOld
);
1376 // ----------------------------------------------------------------------------
1378 // ----------------------------------------------------------------------------
1382 void wxGTKRenderer::DrawTab(wxDC
& dc
,
1383 const wxRect
& rectOrig
,
1385 const wxString
& label
,
1386 const wxBitmap
& bitmap
,
1390 #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X )
1391 #define REVERSE_FOR_VERTICAL(X,Y) \
1392 SELECT_FOR_VERTICAL(X,Y) \
1394 SELECT_FOR_VERTICAL(Y,X)
1396 wxRect rect
= rectOrig
;
1398 bool isVertical
= ( dir
== wxLEFT
) || ( dir
== wxRIGHT
);
1400 // the current tab is drawn indented (to the top for default case) and
1401 // bigger than the other ones
1402 const wxSize indent
= GetTabIndent();
1403 if ( flags
& wxCONTROL_SELECTED
)
1405 rect
.Inflate( SELECT_FOR_VERTICAL( indent
.x
, 0),
1406 SELECT_FOR_VERTICAL( 0, indent
.y
));
1410 wxFAIL_MSG(_T("invaild notebook tab orientation"));
1417 rect
.height
+= indent
.y
;
1424 rect
.width
+= indent
.x
;
1429 // selected tab has different colour
1430 wxColour col
= flags
& wxCONTROL_SELECTED
1431 ? wxSCHEME_COLOUR(m_scheme
, SHADOW_IN
)
1432 : wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
);
1433 DrawSolidRect(dc
, col
, rect
);
1435 if ( flags
& wxCONTROL_FOCUSED
)
1437 // draw the focus rect
1438 wxRect rectBorder
= rect
;
1439 rectBorder
.Deflate(4, 3);
1440 if ( dir
== wxBOTTOM
)
1441 rectBorder
.Offset(0, -1);
1442 if ( dir
== wxRIGHT
)
1443 rectBorder
.Offset(-1, 0);
1445 DrawRect(dc
, &rectBorder
, m_penBlack
);
1448 // draw the text, image and the focus around them (if necessary)
1449 wxRect
rectLabel( REVERSE_FOR_VERTICAL(rect
.x
,rect
.y
),
1450 REVERSE_FOR_VERTICAL(rect
.width
,rect
.height
)
1452 rectLabel
.Deflate(1, 1);
1455 // draw it horizontally into memory and rotate for screen
1457 wxBitmap bitmapRotated
,
1458 bitmapMem( rectLabel
.x
+ rectLabel
.width
,
1459 rectLabel
.y
+ rectLabel
.height
);
1460 dcMem
.SelectObject(bitmapMem
);
1461 dcMem
.SetBackground(dc
.GetBackground());
1462 dcMem
.SetFont(dc
.GetFont());
1463 dcMem
.SetTextForeground(dc
.GetTextForeground());
1467 wxBitmap( wxImage( bitmap
.ConvertToImage() ).Rotate90(dir
==wxLEFT
) )
1470 #endif // wxUSE_IMAGE
1472 dcMem
.DrawLabel(label
, bitmapRotated
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1473 dcMem
.SelectObject(wxNullBitmap
);
1474 bitmapMem
= bitmapMem
.GetSubBitmap(rectLabel
);
1476 bitmapMem
= wxBitmap(wxImage(bitmapMem
.ConvertToImage()).Rotate90(dir
==wxRIGHT
))
1480 dc
.DrawBitmap(bitmapMem
, rectLabel
.y
, rectLabel
.x
, false);
1484 dc
.DrawLabel(label
, bitmap
, rectLabel
, wxALIGN_CENTRE
, indexAccel
);
1487 // now draw the tab itself
1488 wxCoord x
= SELECT_FOR_VERTICAL(rect
.x
,rect
.y
),
1489 y
= SELECT_FOR_VERTICAL(rect
.y
,rect
.x
),
1490 x2
= SELECT_FOR_VERTICAL(rect
.GetRight(),rect
.GetBottom()),
1491 y2
= SELECT_FOR_VERTICAL(rect
.GetBottom(),rect
.GetRight());
1497 // left orientation looks like top but IsVertical makes x and y reversed
1499 // top is not vertical so use coordinates in written order
1500 dc
.SetPen(m_penHighlight
);
1501 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y2
),
1502 REVERSE_FOR_VERTICAL(x
, y
));
1503 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
),
1504 REVERSE_FOR_VERTICAL(x2
, y
));
1506 dc
.SetPen(m_penBlack
);
1507 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y2
),
1508 REVERSE_FOR_VERTICAL(x2
, y
));
1510 dc
.SetPen(m_penDarkGrey
);
1511 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y2
),
1512 REVERSE_FOR_VERTICAL(x2
- 1, y
+ 1));
1514 if ( flags
& wxCONTROL_SELECTED
)
1516 dc
.SetPen(m_penLightGrey
);
1518 // overwrite the part of the border below this tab
1519 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1),
1520 REVERSE_FOR_VERTICAL(x2
- 1, y2
+ 1));
1522 // and the shadow of the tab to the left of us
1523 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
+ 2),
1524 REVERSE_FOR_VERTICAL(x
+ 1, y2
+ 1));
1529 // right orientation looks like bottom but IsVertical makes x and y reversed
1531 // bottom is not vertical so use coordinates in written order
1532 dc
.SetPen(m_penHighlight
);
1534 // we need to continue one pixel further to overwrite the corner of
1535 // the border for the selected tab
1536 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
, y
- (flags
& wxCONTROL_SELECTED
? 1 : 0)),
1537 REVERSE_FOR_VERTICAL(x
, y2
));
1539 // it doesn't work like this (TODO: implement it properly)
1541 // erase the corner of the tab to the right
1542 dc
.SetPen(m_penLightGrey
);
1543 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1544 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 2));
1545 dc
.DrawPoint(REVERSE_FOR_VERTICAL(x2
- 2, y
- 1));
1548 dc
.SetPen(m_penBlack
);
1549 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
),
1550 REVERSE_FOR_VERTICAL(x2
, y2
));
1551 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
, y
),
1552 REVERSE_FOR_VERTICAL(x2
, y2
));
1554 dc
.SetPen(m_penDarkGrey
);
1555 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 2, y2
- 1),
1556 REVERSE_FOR_VERTICAL(x2
- 1, y2
- 1));
1557 dc
.DrawLine(REVERSE_FOR_VERTICAL(x2
- 1, y
),
1558 REVERSE_FOR_VERTICAL(x2
- 1, y2
));
1560 if ( flags
& wxCONTROL_SELECTED
)
1562 dc
.SetPen(m_penLightGrey
);
1564 // overwrite the part of the (double!) border above this tab
1565 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 1),
1566 REVERSE_FOR_VERTICAL(x2
- 1, y
- 1));
1567 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y
- 2),
1568 REVERSE_FOR_VERTICAL(x2
- 1, y
- 2));
1570 // and the shadow of the tab to the left of us
1571 dc
.DrawLine(REVERSE_FOR_VERTICAL(x
+ 1, y2
- 1),
1572 REVERSE_FOR_VERTICAL(x
+ 1, y
- 1));
1578 #endif // wxUSE_NOTEBOOK
1580 // ----------------------------------------------------------------------------
1582 // ----------------------------------------------------------------------------
1586 wxSize
wxGTKRenderer::GetSliderThumbSize(const wxRect
& rect
,
1588 wxOrientation orient
) const
1590 static const wxCoord SLIDER_THUMB_LENGTH
= 30;
1594 wxRect rectShaft
= GetSliderShaftRect(rect
, lenThumb
, orient
);
1595 if ( orient
== wxHORIZONTAL
)
1597 size
.x
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.width
);
1598 size
.y
= rectShaft
.height
;
1602 size
.y
= wxMin(SLIDER_THUMB_LENGTH
, rectShaft
.height
);
1603 size
.x
= rectShaft
.width
;
1609 wxRect
wxGTKRenderer::GetSliderShaftRect(const wxRect
& rect
,
1610 int WXUNUSED(lenThumb
),
1611 wxOrientation
WXUNUSED(orient
),
1612 long WXUNUSED(style
)) const
1614 return rect
.Deflate(2*BORDER_THICKNESS
, 2*BORDER_THICKNESS
);
1617 void wxGTKRenderer::DrawSliderShaft(wxDC
& dc
,
1618 const wxRect
& rectOrig
,
1619 int WXUNUSED(lenThumb
),
1620 wxOrientation
WXUNUSED(orient
),
1622 long WXUNUSED(style
),
1625 wxRect rect
= rectOrig
;
1627 // draw the border first
1628 if ( flags
& wxCONTROL_FOCUSED
)
1630 DrawRect(dc
, &rect
, m_penBlack
);
1632 else // not focused, normal
1634 DrawAntiShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1637 DrawAntiShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
1639 // and the background
1640 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rect
);
1646 void wxGTKRenderer::DrawSliderThumb(wxDC
& dc
,
1647 const wxRect
& rectOrig
,
1648 wxOrientation orient
,
1649 int WXUNUSED(flags
),
1650 long WXUNUSED(style
))
1652 // draw the thumb border
1653 wxRect rect
= rectOrig
;
1654 DrawAntiRaisedBorder(dc
, &rect
);
1656 // draw the handle in the middle
1657 if ( orient
== wxVERTICAL
)
1659 rect
.height
= 2*BORDER_THICKNESS
;
1660 rect
.y
= rectOrig
.y
+ (rectOrig
.height
- rect
.height
) / 2;
1664 rect
.width
= 2*BORDER_THICKNESS
;
1665 rect
.x
= rectOrig
.x
+ (rectOrig
.width
- rect
.width
) / 2;
1668 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
1671 #endif // wxUSE_SLIDER
1675 // ----------------------------------------------------------------------------
1677 // ----------------------------------------------------------------------------
1679 // wxGTKMenuGeometryInfo: the wxMenuGeometryInfo used by wxGTKRenderer
1680 class WXDLLEXPORT wxGTKMenuGeometryInfo
: public wxMenuGeometryInfo
1683 virtual wxSize
GetSize() const { return m_size
; }
1685 wxCoord
GetLabelOffset() const { return m_ofsLabel
; }
1686 wxCoord
GetAccelOffset() const { return m_ofsAccel
; }
1688 wxCoord
GetItemHeight() const { return m_heightItem
; }
1691 // the total size of the menu
1694 // the offset of the start of the menu item label
1697 // the offset of the start of the accel label
1700 // the height of a normal (not separator) item
1701 wxCoord m_heightItem
;
1703 friend wxMenuGeometryInfo
*
1704 wxGTKRenderer::GetMenuGeometry(wxWindow
*, const wxMenu
&) const;
1707 // FIXME: all constants are hardcoded but shouldn't be
1708 static const wxCoord MENU_LEFT_MARGIN
= 9;
1709 static const wxCoord MENU_RIGHT_MARGIN
= 6;
1711 static const wxCoord MENU_HORZ_MARGIN
= 6;
1712 static const wxCoord MENU_VERT_MARGIN
= 3;
1714 // the margin around bitmap/check marks (on each side)
1715 static const wxCoord MENU_BMP_MARGIN
= 2;
1717 // the margin between the labels and accel strings
1718 static const wxCoord MENU_ACCEL_MARGIN
= 8;
1720 // the separator height in pixels: in fact, strangely enough, the real height
1721 // is 2 but Windows adds one extra pixel in the bottom margin, so take it into
1723 static const wxCoord MENU_SEPARATOR_HEIGHT
= 3;
1725 // the size of the standard checkmark bitmap
1726 static const wxCoord MENU_CHECK_SIZE
= 9;
1728 void wxGTKRenderer::DrawMenuBarItem(wxDC
& dc
,
1730 const wxString
& label
,
1734 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
);
1737 void wxGTKRenderer::DrawMenuItem(wxDC
& dc
,
1739 const wxMenuGeometryInfo
& gi
,
1740 const wxString
& label
,
1741 const wxString
& accel
,
1742 const wxBitmap
& bitmap
,
1746 const wxGTKMenuGeometryInfo
& geomInfo
= (const wxGTKMenuGeometryInfo
&)gi
;
1751 rect
.width
= geomInfo
.GetSize().x
;
1752 rect
.height
= geomInfo
.GetItemHeight();
1754 DoDrawMenuItem(dc
, rect
, label
, flags
, indexAccel
, accel
, bitmap
, &geomInfo
);
1757 void wxGTKRenderer::DoDrawMenuItem(wxDC
& dc
,
1758 const wxRect
& rectOrig
,
1759 const wxString
& label
,
1762 const wxString
& accel
,
1763 const wxBitmap
& bitmap
,
1764 const wxGTKMenuGeometryInfo
*geometryInfo
)
1766 wxRect rect
= rectOrig
;
1768 // draw the selected item specially
1769 if ( flags
& wxCONTROL_SELECTED
)
1772 DrawBorder(dc
, wxBORDER_RAISED
, rect
, flags
, &rectIn
);
1774 DrawBackground(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL_CURRENT
), rectIn
);
1777 rect
.Deflate(MENU_HORZ_MARGIN
, MENU_VERT_MARGIN
);
1779 // draw the bitmap: use the bitmap provided or the standard checkmark for
1780 // the checkable items
1783 wxBitmap bmp
= bitmap
;
1784 if ( !bmp
.Ok() && (flags
& wxCONTROL_CHECKABLE
) )
1786 bmp
= GetCheckBitmap(flags
);
1791 rect
.SetRight(geometryInfo
->GetLabelOffset());
1792 wxControlRenderer::DrawBitmap(dc
, bmp
, rect
);
1795 //else: menubar items don't have bitmaps
1800 rect
.x
= geometryInfo
->GetLabelOffset();
1801 rect
.SetRight(geometryInfo
->GetAccelOffset());
1804 DrawLabel(dc
, label
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
, indexAccel
);
1806 // draw the accel string
1807 if ( !accel
.empty() )
1809 // menubar items shouldn't have them
1810 wxCHECK_RET( geometryInfo
, _T("accel strings only valid for menus") );
1812 rect
.x
= geometryInfo
->GetAccelOffset();
1813 rect
.SetRight(geometryInfo
->GetSize().x
);
1815 // NB: no accel index here
1816 DrawLabel(dc
, accel
, rect
, flags
, wxALIGN_CENTRE_VERTICAL
);
1819 // draw the submenu indicator
1820 if ( flags
& wxCONTROL_ISSUBMENU
)
1822 wxCHECK_RET( geometryInfo
, _T("wxCONTROL_ISSUBMENU only valid for menus") );
1824 rect
.x
= geometryInfo
->GetSize().x
- MENU_RIGHT_MARGIN
;
1825 rect
.width
= MENU_RIGHT_MARGIN
;
1827 DrawArrow(dc
, wxRIGHT
, rect
, flags
);
1831 void wxGTKRenderer::DrawMenuSeparator(wxDC
& dc
,
1833 const wxMenuGeometryInfo
& geomInfo
)
1835 DrawHorizontalLine(dc
, y
+ MENU_VERT_MARGIN
, 0, geomInfo
.GetSize().x
);
1838 wxSize
wxGTKRenderer::GetMenuBarItemSize(const wxSize
& sizeText
) const
1840 wxSize size
= sizeText
;
1842 // TODO: make this configurable
1843 size
.x
+= 2*MENU_HORZ_MARGIN
;
1844 size
.y
+= 2*MENU_VERT_MARGIN
;
1849 wxMenuGeometryInfo
*wxGTKRenderer::GetMenuGeometry(wxWindow
*win
,
1850 const wxMenu
& menu
) const
1852 // prepare the dc: for now we draw all the items with the system font
1854 dc
.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
1856 // the height of a normal item
1857 wxCoord heightText
= dc
.GetCharHeight();
1862 // the max length of label and accel strings: the menu width is the sum of
1863 // them, even if they're for different items (as the accels should be
1866 // the max length of the bitmap is never 0 as Windows always leaves enough
1867 // space for a check mark indicator
1868 wxCoord widthLabelMax
= 0,
1870 widthBmpMax
= MENU_LEFT_MARGIN
;
1872 for ( wxMenuItemList::compatibility_iterator node
= menu
.GetMenuItems().GetFirst();
1874 node
= node
->GetNext() )
1876 // height of this item
1879 wxMenuItem
*item
= node
->GetData();
1880 if ( item
->IsSeparator() )
1882 h
= MENU_SEPARATOR_HEIGHT
;
1884 else // not separator
1889 dc
.GetTextExtent(item
->GetLabel(), &widthLabel
, NULL
);
1890 if ( widthLabel
> widthLabelMax
)
1892 widthLabelMax
= widthLabel
;
1896 dc
.GetTextExtent(item
->GetAccelString(), &widthAccel
, NULL
);
1897 if ( widthAccel
> widthAccelMax
)
1899 widthAccelMax
= widthAccel
;
1902 const wxBitmap
& bmp
= item
->GetBitmap();
1905 wxCoord widthBmp
= bmp
.GetWidth();
1906 if ( widthBmp
> widthBmpMax
)
1907 widthBmpMax
= widthBmp
;
1909 //else if ( item->IsCheckable() ): no need to check for this as
1910 // MENU_LEFT_MARGIN is big enough to show the check mark
1913 h
+= 2*MENU_VERT_MARGIN
;
1915 // remember the item position and height
1916 item
->SetGeometry(height
, h
);
1921 // bundle the metrics into a struct and return it
1922 wxGTKMenuGeometryInfo
*gi
= new wxGTKMenuGeometryInfo
;
1924 gi
->m_ofsLabel
= widthBmpMax
+ 2*MENU_BMP_MARGIN
;
1925 gi
->m_ofsAccel
= gi
->m_ofsLabel
+ widthLabelMax
;
1926 if ( widthAccelMax
> 0 )
1928 // if we actually have any accesl, add a margin
1929 gi
->m_ofsAccel
+= MENU_ACCEL_MARGIN
;
1932 gi
->m_heightItem
= heightText
+ 2*MENU_VERT_MARGIN
;
1934 gi
->m_size
.x
= gi
->m_ofsAccel
+ widthAccelMax
+ MENU_RIGHT_MARGIN
;
1935 gi
->m_size
.y
= height
;
1940 #endif // wxUSE_MENUS
1944 // ----------------------------------------------------------------------------
1946 // ----------------------------------------------------------------------------
1949 wxGTKRenderer::GetStatusBarBorders(wxCoord
* WXUNUSED(borderBetweenFields
)) const
1954 void wxGTKRenderer::DrawStatusField(wxDC
& WXUNUSED(dc
),
1955 const wxRect
& WXUNUSED(rect
),
1956 const wxString
& WXUNUSED(label
),
1957 int WXUNUSED(flags
), int WXUNUSED(style
))
1961 #endif // wxUSE_STATUSBAR
1963 // ----------------------------------------------------------------------------
1965 // ----------------------------------------------------------------------------
1967 void wxGTKRenderer::InitComboBitmaps()
1969 wxSize sizeArrow
= m_sizeScrollbarArrow
;
1975 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1977 m_bitmapsCombo
[n
].Create(sizeArrow
.x
, sizeArrow
.y
);
1980 static const int comboButtonFlags
[ComboState_Max
] =
1988 wxRect
rect(sizeArrow
);
1991 for ( n
= ComboState_Normal
; n
< ComboState_Max
; n
++ )
1993 int flags
= comboButtonFlags
[n
];
1995 dc
.SelectObject(m_bitmapsCombo
[n
]);
1996 DrawSolidRect(dc
, GetBackgroundColour(flags
), rect
);
1997 DrawArrow(dc
, wxDOWN
, rect
, flags
);
2001 void wxGTKRenderer::GetComboBitmaps(wxBitmap
*bmpNormal
,
2003 wxBitmap
*bmpPressed
,
2004 wxBitmap
*bmpDisabled
)
2006 if ( !m_bitmapsCombo
[ComboState_Normal
].Ok() )
2012 *bmpNormal
= m_bitmapsCombo
[ComboState_Normal
];
2014 *bmpFocus
= m_bitmapsCombo
[ComboState_Focus
];
2016 *bmpPressed
= m_bitmapsCombo
[ComboState_Pressed
];
2018 *bmpDisabled
= m_bitmapsCombo
[ComboState_Disabled
];
2021 // ----------------------------------------------------------------------------
2023 // ----------------------------------------------------------------------------
2025 void wxGTKRenderer::DrawArrowBorder(wxDC
& dc
,
2029 static const wxDirection sides
[] =
2031 wxUP
, wxLEFT
, wxRIGHT
, wxDOWN
2034 wxRect rect1
, rect2
, rectInner
;
2040 rectInner
.Inflate(-2);
2042 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), *rect
);
2044 // find the side not to draw and also adjust the rectangles to compensate
2046 wxDirection sideToOmit
;
2050 sideToOmit
= wxDOWN
;
2052 rectInner
.height
+= 1;
2060 rectInner
.height
+= 1;
2064 sideToOmit
= wxRIGHT
;
2066 rectInner
.width
+= 1;
2070 sideToOmit
= wxLEFT
;
2074 rectInner
.width
+= 1;
2078 wxFAIL_MSG(_T("unknown arrow direction"));
2082 // the outer rect first
2084 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2086 wxDirection side
= sides
[n
];
2087 if ( side
== sideToOmit
)
2090 DrawAntiShadedRectSide(dc
, rect1
, m_penDarkGrey
, m_penHighlight
, side
);
2093 // and then the inner one
2094 for ( n
= 0; n
< WXSIZEOF(sides
); n
++ )
2096 wxDirection side
= sides
[n
];
2097 if ( side
== sideToOmit
)
2100 DrawAntiShadedRectSide(dc
, rect2
, m_penBlack
, m_penGrey
, side
);
2106 void wxGTKRenderer::DrawScrollbarArrow(wxDC
& dc
,
2108 const wxRect
& rectArrow
,
2111 // first of all, draw the border around it - but we don't want the border
2112 // on the side opposite to the arrow point
2113 wxRect rect
= rectArrow
;
2114 DrawArrowBorder(dc
, &rect
, dir
);
2116 // then the arrow itself
2117 DrawArrow(dc
, dir
, rect
, flags
);
2120 // gtk_default_draw_arrow() takes ~350 lines and we can't do much better here
2121 // these people are just crazy :-(
2122 void wxGTKRenderer::DrawArrow(wxDC
& dc
,
2135 wxPoint ptArrow
[Point_Max
];
2137 wxColour colInside
= GetBackgroundColour(flags
);
2139 if ( flags
& wxCONTROL_DISABLED
)
2141 penShadow
[0] = m_penDarkGrey
;
2142 penShadow
[1] = m_penDarkGrey
;
2143 penShadow
[2] = wxNullPen
;
2144 penShadow
[3] = wxNullPen
;
2146 else if ( flags
& wxCONTROL_PRESSED
)
2148 penShadow
[0] = m_penDarkGrey
;
2149 penShadow
[1] = m_penHighlight
;
2150 penShadow
[2] = wxNullPen
;
2151 penShadow
[3] = m_penBlack
;
2153 else // normal arrow
2155 penShadow
[0] = m_penHighlight
;
2156 penShadow
[1] = m_penBlack
;
2157 penShadow
[2] = m_penDarkGrey
;
2158 penShadow
[3] = wxNullPen
;
2162 if ( dir
== wxUP
|| dir
== wxDOWN
)
2165 middle
= (rect
.GetRight() + rect
.GetLeft() + 1) / 2;
2169 middle
= (rect
.GetTop() + rect
.GetBottom() + 1) / 2;
2172 // draw the arrow interior
2173 dc
.SetPen(*wxTRANSPARENT_PEN
);
2174 dc
.SetBrush(colInside
);
2179 ptArrow
[Point_First
].x
= rect
.GetLeft();
2180 ptArrow
[Point_First
].y
= rect
.GetBottom();
2181 ptArrow
[Point_Second
].x
= middle
;
2182 ptArrow
[Point_Second
].y
= rect
.GetTop();
2183 ptArrow
[Point_Third
].x
= rect
.GetRight();
2184 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2188 ptArrow
[Point_First
] = rect
.GetPosition();
2189 ptArrow
[Point_Second
].x
= middle
;
2190 ptArrow
[Point_Second
].y
= rect
.GetBottom();
2191 ptArrow
[Point_Third
].x
= rect
.GetRight();
2192 ptArrow
[Point_Third
].y
= rect
.GetTop();
2196 ptArrow
[Point_First
].x
= rect
.GetRight();
2197 ptArrow
[Point_First
].y
= rect
.GetTop();
2198 ptArrow
[Point_Second
].x
= rect
.GetLeft();
2199 ptArrow
[Point_Second
].y
= middle
;
2200 ptArrow
[Point_Third
].x
= rect
.GetRight();
2201 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2205 ptArrow
[Point_First
] = rect
.GetPosition();
2206 ptArrow
[Point_Second
].x
= rect
.GetRight();
2207 ptArrow
[Point_Second
].y
= middle
;
2208 ptArrow
[Point_Third
].x
= rect
.GetLeft();
2209 ptArrow
[Point_Third
].y
= rect
.GetBottom();
2213 wxFAIL_MSG(_T("unknown arrow direction"));
2216 dc
.DrawPolygon(WXSIZEOF(ptArrow
), ptArrow
);
2218 // draw the arrow border
2219 dc
.SetPen(penShadow
[0]);
2223 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2224 dc
.DrawPoint(ptArrow
[Point_First
]);
2225 if ( penShadow
[3].Ok() )
2227 dc
.SetPen(penShadow
[3]);
2228 dc
.DrawLine(ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
,
2229 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2231 dc
.SetPen(penShadow
[1]);
2232 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2233 ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
);
2234 dc
.DrawPoint(ptArrow
[Point_Third
]);
2235 dc
.DrawLine(ptArrow
[Point_Third
].x
- 2, ptArrow
[Point_Third
].y
,
2236 ptArrow
[Point_First
].x
+ 1, ptArrow
[Point_First
].y
);
2237 if ( penShadow
[2].Ok() )
2239 dc
.SetPen(penShadow
[2]);
2240 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2241 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
+ 1);
2242 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1,
2243 ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
- 1);
2248 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Second
]);
2249 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
,
2250 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2251 if ( penShadow
[2].Ok() )
2253 dc
.SetPen(penShadow
[2]);
2254 dc
.DrawLine(ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
- 1,
2255 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
- 1);
2257 dc
.SetPen(penShadow
[1]);
2258 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2259 dc
.DrawPoint(ptArrow
[Point_Third
]);
2263 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_First
]);
2264 dc
.DrawPoint(ptArrow
[Point_First
]);
2265 if ( penShadow
[2].Ok() )
2267 dc
.SetPen(penShadow
[2]);
2268 dc
.DrawLine(ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
,
2269 ptArrow
[Point_First
].x
- 1, ptArrow
[Point_First
].y
+ 2);
2270 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2271 ptArrow
[Point_Second
].x
+ 2, ptArrow
[Point_Second
].y
+ 1);
2273 dc
.SetPen(penShadow
[1]);
2274 dc
.DrawLine(ptArrow
[Point_Third
].x
, ptArrow
[Point_Third
].y
,
2275 ptArrow
[Point_First
].x
, ptArrow
[Point_First
].y
+ 1);
2276 dc
.DrawLine(ptArrow
[Point_Second
].x
+ 1, ptArrow
[Point_Second
].y
+ 1,
2277 ptArrow
[Point_Third
].x
- 1, ptArrow
[Point_Third
].y
);
2281 dc
.DrawLine(ptArrow
[Point_First
], ptArrow
[Point_Third
]);
2282 dc
.DrawLine(ptArrow
[Point_First
].x
+ 2, ptArrow
[Point_First
].y
+ 1,
2283 ptArrow
[Point_Second
].x
, ptArrow
[Point_Second
].y
);
2284 dc
.SetPen(penShadow
[1]);
2285 dc
.DrawLine(ptArrow
[Point_Second
], ptArrow
[Point_Third
]);
2286 dc
.DrawPoint(ptArrow
[Point_Third
]);
2290 wxFAIL_MSG(_T("unknown arrow direction"));
2295 void wxGTKRenderer::DrawThumbBorder(wxDC
& dc
,
2297 wxOrientation orient
)
2299 if ( orient
== wxVERTICAL
)
2301 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2303 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2305 rect
->Inflate(-1, 0);
2307 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2309 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2311 rect
->Inflate(-1, 0);
2315 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2317 DrawAntiShadedRectSide(dc
, *rect
, m_penDarkGrey
, m_penHighlight
,
2319 rect
->Inflate(0, -1);
2321 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2323 DrawAntiShadedRectSide(dc
, *rect
, m_penBlack
, m_penGrey
,
2325 rect
->Inflate(0, -1);
2329 void wxGTKRenderer::DrawScrollbarThumb(wxDC
& dc
,
2330 wxOrientation orient
,
2334 // the thumb is never pressed never has focus border under GTK and the
2335 // scrollbar background never changes at all
2336 int flagsThumb
= flags
& ~(wxCONTROL_PRESSED
| wxCONTROL_FOCUSED
);
2338 // we don't want the border in the direction of the scrollbar movement
2339 wxRect rectThumb
= rect
;
2340 DrawThumbBorder(dc
, &rectThumb
, orient
);
2342 DrawButtonBorder(dc
, rectThumb
, flagsThumb
, &rectThumb
);
2343 DrawBackground(dc
, wxNullColour
, rectThumb
, flagsThumb
);
2346 void wxGTKRenderer::DrawScrollbarShaft(wxDC
& dc
,
2347 wxOrientation orient
,
2349 int WXUNUSED(flags
))
2351 wxRect rectBar
= rect
;
2352 DrawThumbBorder(dc
, &rectBar
, orient
);
2353 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, SCROLLBAR
), rectBar
);
2356 void wxGTKRenderer::DrawScrollCorner(wxDC
& dc
, const wxRect
& rect
)
2358 DrawSolidRect(dc
, wxSCHEME_COLOUR(m_scheme
, CONTROL
), rect
);
2362 wxRect
wxGTKRenderer::GetScrollbarRect(const wxScrollBar
*scrollbar
,
2363 wxScrollBar::Element elem
,
2366 // as GTK scrollbars can't be disabled, it makes no sense to remove the
2367 // thumb for a scrollbar with range 0 - instead, make it fill the entire
2369 if ( (elem
== wxScrollBar::Element_Thumb
) && !scrollbar
->GetRange() )
2371 elem
= wxScrollBar::Element_Bar_2
;
2374 return wxStdRenderer::GetScrollbarRect(scrollbar
, elem
, thumbPos
);
2377 #endif // wxUSE_SCROLLBAR
2379 // ----------------------------------------------------------------------------
2381 // ----------------------------------------------------------------------------
2383 void wxGTKRenderer::AdjustSize(wxSize
*size
, const wxWindow
*window
)
2386 if ( wxDynamicCast(window
, wxBitmapButton
) )
2391 #endif // wxUSE_BMPBUTTON
2392 #if wxUSE_BUTTON || wxUSE_TOGGLEBTN
2395 || wxDynamicCast(window
, wxButton
)
2396 # endif // wxUSE_BUTTON
2397 # if wxUSE_TOGGLEBTN
2398 || wxDynamicCast(window
, wxToggleButton
)
2399 # endif // wxUSE_TOGGLEBTN
2402 if ( !(window
->GetWindowStyle() & wxBU_EXACTFIT
) )
2404 // TODO: this is ad hoc...
2405 size
->x
+= 3*window
->GetCharWidth();
2406 wxCoord minBtnHeight
= 18;
2407 if ( size
->y
< minBtnHeight
)
2408 size
->y
= minBtnHeight
;
2410 // button border width
2414 #endif // wxUSE_BUTTON || wxUSE_TOGGLEBTN
2416 if ( wxDynamicCast(window
, wxScrollBar
) )
2418 // we only set the width of vert scrollbars and height of the
2420 if ( window
->GetWindowStyle() & wxSB_HORIZONTAL
)
2421 size
->y
= m_sizeScrollbarArrow
.x
;
2423 size
->x
= m_sizeScrollbarArrow
.x
;
2426 #endif // wxUSE_SCROLLBAR
2428 // take into account the border width
2429 wxRect rectBorder
= GetBorderDimensions(window
->GetBorder());
2430 size
->x
+= rectBorder
.x
+ rectBorder
.width
;
2431 size
->y
+= rectBorder
.y
+ rectBorder
.height
;
2435 // ----------------------------------------------------------------------------
2436 // top level windows
2437 // ----------------------------------------------------------------------------
2439 void wxGTKRenderer::DrawFrameTitleBar(wxDC
& WXUNUSED(dc
),
2440 const wxRect
& WXUNUSED(rect
),
2441 const wxString
& WXUNUSED(title
),
2442 const wxIcon
& WXUNUSED(icon
),
2443 int WXUNUSED(flags
),
2444 int WXUNUSED(specialButton
),
2445 int WXUNUSED(specialButtonFlag
))
2449 void wxGTKRenderer::DrawFrameBorder(wxDC
& WXUNUSED(dc
),
2450 const wxRect
& WXUNUSED(rect
),
2451 int WXUNUSED(flags
))
2455 void wxGTKRenderer::DrawFrameBackground(wxDC
& WXUNUSED(dc
),
2456 const wxRect
& WXUNUSED(rect
),
2457 int WXUNUSED(flags
))
2461 void wxGTKRenderer::DrawFrameTitle(wxDC
& WXUNUSED(dc
),
2462 const wxRect
& WXUNUSED(rect
),
2463 const wxString
& WXUNUSED(title
),
2464 int WXUNUSED(flags
))
2468 void wxGTKRenderer::DrawFrameIcon(wxDC
& WXUNUSED(dc
),
2469 const wxRect
& WXUNUSED(rect
),
2470 const wxIcon
& WXUNUSED(icon
),
2471 int WXUNUSED(flags
))
2475 void wxGTKRenderer::DrawFrameButton(wxDC
& WXUNUSED(dc
),
2476 wxCoord
WXUNUSED(x
),
2477 wxCoord
WXUNUSED(y
),
2478 int WXUNUSED(button
),
2479 int WXUNUSED(flags
))
2484 wxGTKRenderer::GetFrameClientArea(const wxRect
& rect
,
2485 int WXUNUSED(flags
)) const
2491 wxGTKRenderer::GetFrameTotalSize(const wxSize
& clientSize
,
2492 int WXUNUSED(flags
)) const
2497 wxSize
wxGTKRenderer::GetFrameMinSize(int WXUNUSED(flags
)) const
2502 wxSize
wxGTKRenderer::GetFrameIconSize() const
2504 return wxSize(wxDefaultCoord
, wxDefaultCoord
);
2508 wxGTKRenderer::HitTestFrame(const wxRect
& WXUNUSED(rect
),
2509 const wxPoint
& WXUNUSED(pt
),
2510 int WXUNUSED(flags
)) const
2512 return wxHT_TOPLEVEL_CLIENT_AREA
;
2516 // ----------------------------------------------------------------------------
2518 // ----------------------------------------------------------------------------
2520 /* Copyright (c) Julian Smart */
2521 static const char *error_xpm
[] = {
2522 /* columns rows colors chars-per-pixel */
2536 " ................. ",
2537 " ................... ",
2538 " ....................... ",
2539 " ......................... ",
2540 " ........................... ",
2541 " ...........................X ",
2542 " .............................X ",
2543 " ............................... ",
2544 " ...............................X ",
2545 " .................................X ",
2546 " .................................X ",
2547 " .................................XX ",
2548 " ...ooooooooooooooooooooooooooo...XX ",
2549 " ....ooooooooooooooooooooooooooo....X ",
2550 " ....ooooooooooooooooooooooooooo....X ",
2551 " ....ooooooooooooooooooooooooooo....XX ",
2552 " ....ooooooooooooooooooooooooooo....XX ",
2553 " ....ooooooooooooooooooooooooooo....XX ",
2554 " ...ooooooooooooooooooooooooooo...XXX ",
2555 " ...ooooooooooooooooooooooooooo...XXX ",
2556 " .................................XX ",
2557 " .................................XX ",
2558 " ...............................XXX ",
2559 " ...............................XXX ",
2560 " .............................XXX ",
2561 " ...........................XXXX ",
2562 " ...........................XXX ",
2563 " .........................XXX ",
2564 " .......................XXXX ",
2565 " X...................XXXXX ",
2566 " X.................XXXXX ",
2567 " X.............XXXXX ",
2568 " XXXX.....XXXXXXXX ",
2579 /* Copyright (c) Julian Smart */
2580 static const char *info_xpm
[] = {
2581 /* columns rows colors chars-per-pixel */
2605 " .XXXOXXXXXXXoo. ",
2606 " .XOOXXX+XXXXXo. ",
2607 " .XOOOXX+++XXXXoo. ",
2608 " .XOOXXX+++XXXXXo. ",
2609 " .XOOOXXX+++XXXXXXo. ",
2610 " .XOOXXXX+++XXXXXXo. ",
2611 " .XXXXXXX+++XXXXXXX. ",
2612 " .XXXXXXX+++XXXXXXo. ",
2613 " .XXXXXXX+++XXXXXoo. ",
2614 " .XXXXXX+++XXXXXo. ",
2615 " .XXXXXXX+XXXXXXo. ",
2616 " .XXXXXXXXXXXXo. ",
2617 " .XXXXX+++XXXoo. ",
2643 /* Copyright (c) Julian Smart */
2644 static const char *warning_xpm
[] = {
2645 /* columns rows colors chars-per-pixel */
2675 " ..XXXXO@#XXX... ",
2676 " ...XXXXO@#XXXX.. ",
2677 " ..XXXXXO@#XXXX... ",
2678 " ...XXXXXo@OXXXXX.. ",
2679 " ...XXXXXXo@OXXXXXX.. ",
2680 " ..XXXXXXX$@OXXXXXX... ",
2681 " ...XXXXXXXX@XXXXXXXX.. ",
2682 " ...XXXXXXXXXXXXXXXXXX... ",
2683 " ..XXXXXXXXXXOXXXXXXXXX.. ",
2684 " ...XXXXXXXXXO@#XXXXXXXXX.. ",
2685 " ..XXXXXXXXXXX#XXXXXXXXXX... ",
2686 " ...XXXXXXXXXXXXXXXXXXXXXXX.. ",
2687 " ...XXXXXXXXXXXXXXXXXXXXXXXX... ",
2688 " .............................. ",
2689 " .............................. ",
2707 /* Copyright (c) Julian Smart */
2708 static const char *question_xpm
[] = {
2709 /* columns rows colors chars-per-pixel */
2739 " ..XXXXoooooXXXO+ ",
2740 " ..XXooooooooooooX@.. ",
2741 " ..XoooooooooooooooXX#. ",
2742 " $%XoooooooooooooooooXX#. ",
2743 " &.XoooooooXXXXXXooooooXX.. ",
2744 " .XooooooXX.$...$XXoooooX*. ",
2745 " $.XoooooX%.$ .*oooooo=.. ",
2746 " .XooooooX.. -.XoooooX.. ",
2747 " .XoooooX..+ .XoooooX;. ",
2748 " ...XXXX..: .XoooooX;. ",
2749 " ........ >.XoooooX;. ",
2783 wxBitmap
wxGTKArtProvider::CreateBitmap(const wxArtID
& id
,
2784 const wxArtClient
& WXUNUSED(client
),
2785 const wxSize
& WXUNUSED(size
))
2787 if ( id
== wxART_INFORMATION
)
2788 return wxBitmap(info_xpm
);
2789 if ( id
== wxART_ERROR
)
2790 return wxBitmap(error_xpm
);
2791 if ( id
== wxART_WARNING
)
2792 return wxBitmap(warning_xpm
);
2793 if ( id
== wxART_QUESTION
)
2794 return wxBitmap(question_xpm
);
2795 return wxNullBitmap
;
2799 // ============================================================================
2801 // ============================================================================
2803 // ----------------------------------------------------------------------------
2804 // wxGTKInputHandler
2805 // ----------------------------------------------------------------------------
2807 bool wxGTKInputHandler::HandleKey(wxInputConsumer
* WXUNUSED(control
),
2808 const wxKeyEvent
& WXUNUSED(event
),
2809 bool WXUNUSED(pressed
))
2814 bool wxGTKInputHandler::HandleMouse(wxInputConsumer
*control
,
2815 const wxMouseEvent
& event
)
2817 // clicking on the control gives it focus
2818 if ( event
.ButtonDown() && wxWindow::FindFocus() != control
->GetInputWindow() )
2820 control
->GetInputWindow()->SetFocus();
2828 bool wxGTKInputHandler::HandleMouseMove(wxInputConsumer
*control
,
2829 const wxMouseEvent
& event
)
2831 if ( event
.Entering() )
2833 control
->GetInputWindow()->SetCurrent(true);
2835 else if ( event
.Leaving() )
2837 control
->GetInputWindow()->SetCurrent(false);
2849 // ----------------------------------------------------------------------------
2850 // wxGTKCheckboxInputHandler
2851 // ----------------------------------------------------------------------------
2853 bool wxGTKCheckboxInputHandler::HandleKey(wxInputConsumer
*control
,
2854 const wxKeyEvent
& event
,
2859 int keycode
= event
.GetKeyCode();
2860 if ( keycode
== WXK_SPACE
|| keycode
== WXK_RETURN
)
2862 control
->PerformAction(wxACTION_CHECKBOX_TOGGLE
);
2871 #endif // wxUSE_CHECKBOX
2875 // ----------------------------------------------------------------------------
2876 // wxGTKTextCtrlInputHandler
2877 // ----------------------------------------------------------------------------
2879 bool wxGTKTextCtrlInputHandler::HandleKey(wxInputConsumer
*control
,
2880 const wxKeyEvent
& event
,
2883 // handle only GTK-specific text bindings here, the others are handled in
2887 wxControlAction action
;
2888 int keycode
= event
.GetKeyCode();
2889 if ( event
.ControlDown() )
2894 action
= wxACTION_TEXT_HOME
;
2898 action
= wxACTION_TEXT_LEFT
;
2902 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_RIGHT
;
2906 action
= wxACTION_TEXT_END
;
2910 action
= wxACTION_TEXT_RIGHT
;
2914 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_LEFT
;
2918 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2922 action
= wxACTION_TEXT_DOWN
;
2926 action
= wxACTION_TEXT_UP
;
2930 //delete the entire line
2931 control
->PerformAction(wxACTION_TEXT_HOME
);
2932 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_END
;
2936 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_LEFT
;
2940 else if ( event
.AltDown() )
2945 action
= wxACTION_TEXT_WORD_LEFT
;
2949 action
<< wxACTION_TEXT_PREFIX_DEL
<< wxACTION_TEXT_WORD_RIGHT
;
2953 action
= wxACTION_TEXT_WORD_RIGHT
;
2958 if ( action
!= wxACTION_NONE
)
2960 control
->PerformAction(action
);
2966 return wxStdInputHandler::HandleKey(control
, event
, pressed
);
2969 #endif // wxUSE_TEXTCTRL