diff --git a/src/univ/themes/gtk.cpp b/src/univ/themes/gtk.cpp index ec14525c64..7dddfa2cdd 100644 --- a/src/univ/themes/gtk.cpp +++ b/src/univ/themes/gtk.cpp @@ -51,6 +51,7 @@ #include "wx/spinbutt.h" #include "wx/toplevel.h" #include "wx/artprov.h" +#include "wx/image.h" #include "wx/univ/renderer.h" #include "wx/univ/inphand.h" @@ -1742,13 +1743,23 @@ void wxGTKRenderer::DrawTab(wxDC& dc, int flags, int indexAccel) { + #define SELECT_FOR_VERTICAL(X,Y) ( isVertical ? Y : X ) + #define REVERSE_FOR_VERTICAL(X,Y) \ + SELECT_FOR_VERTICAL(X,Y) \ + , \ + SELECT_FOR_VERTICAL(Y,X) + wxRect rect = rectOrig; + bool isVertical = ( dir == wxLEFT ) || ( dir == wxRIGHT ); + // the current tab is drawn indented (to the top for default case) and // bigger than the other ones const wxSize indent = GetTabIndent(); if ( flags & wxCONTROL_SELECTED ) { + rect.Inflate( SELECT_FOR_VERTICAL( indent.x , 0), + SELECT_FOR_VERTICAL( 0, indent.y )); switch ( dir ) { default: @@ -1756,19 +1767,17 @@ void wxGTKRenderer::DrawTab(wxDC& dc, // fall through case wxTOP: - rect.Inflate(indent.x, 0); rect.y -= indent.y; - rect.height += indent.y; - break; - + // fall through case wxBOTTOM: - rect.Inflate(indent.x, 0); rect.height += indent.y; break; case wxLEFT: + rect.x -= indent.x; + // fall through case wxRIGHT: - wxFAIL_MSG(_T("TODO")); + rect.width += indent.x; break; } } @@ -1786,87 +1795,129 @@ void wxGTKRenderer::DrawTab(wxDC& dc, rectBorder.Deflate(4, 3); if ( dir == wxBOTTOM ) rectBorder.Offset(0, -1); + if ( dir == wxRIGHT ) + rectBorder.Offset(-1, 0); DrawRect(dc, &rectBorder, m_penBlack); } // draw the text, image and the focus around them (if necessary) - wxRect rectLabel = rect; + wxRect rectLabel( REVERSE_FOR_VERTICAL(rect.x,rect.y), + REVERSE_FOR_VERTICAL(rect.width,rect.height) + ); rectLabel.Deflate(1, 1); - dc.DrawLabel(label, bitmap, rectLabel, wxALIGN_CENTRE, indexAccel); + if ( isVertical ) + { + // draw it horizontally into memory and rotate for screen + wxMemoryDC dcMem; + wxBitmap bitmapRotated, + bitmapMem( rectLabel.x + rectLabel.width, + rectLabel.y + rectLabel.height ); + dcMem.SelectObject(bitmapMem); + dcMem.SetBackground(dc.GetBackground()); + dcMem.SetFont(dc.GetFont()); + dcMem.SetTextForeground(dc.GetTextForeground()); + dcMem.Clear(); + bitmapRotated = wxBitmap( wxImage( bitmap.ConvertToImage() ).Rotate90(dir==wxLEFT) ); + dcMem.DrawLabel(label, bitmapRotated, rectLabel, wxALIGN_CENTRE, indexAccel); + dcMem.SelectObject(wxNullBitmap); + bitmapMem = bitmapMem.GetSubBitmap(rectLabel); + bitmapMem = wxBitmap(wxImage(bitmapMem.ConvertToImage()).Rotate90(dir==wxRIGHT)); + dc.DrawBitmap(bitmapMem, rectLabel.y, rectLabel.x, false); + } + else + { + dc.DrawLabel(label, bitmap, rectLabel, wxALIGN_CENTRE, indexAccel); + } // now draw the tab itself - wxCoord x = rect.x, - y = rect.y, - x2 = rect.GetRight(), - y2 = rect.GetBottom(); + wxCoord x = SELECT_FOR_VERTICAL(rect.x,rect.y), + y = SELECT_FOR_VERTICAL(rect.y,rect.x), + x2 = SELECT_FOR_VERTICAL(rect.GetRight(),rect.GetBottom()), + y2 = SELECT_FOR_VERTICAL(rect.GetBottom(),rect.GetRight()); switch ( dir ) { default: + // default is top + case wxLEFT: + // left orientation looks like top but IsVertical makes x and y reversed case wxTOP: + // top is not vertical so use coordinates in written order dc.SetPen(m_penHighlight); - dc.DrawLine(x, y2, x, y); - dc.DrawLine(x + 1, y, x2, y); + dc.DrawLine(REVERSE_FOR_VERTICAL(x, y2), + REVERSE_FOR_VERTICAL(x, y)); + dc.DrawLine(REVERSE_FOR_VERTICAL(x + 1, y), + REVERSE_FOR_VERTICAL(x2, y)); dc.SetPen(m_penBlack); - dc.DrawLine(x2, y2, x2, y); + dc.DrawLine(REVERSE_FOR_VERTICAL(x2, y2), + REVERSE_FOR_VERTICAL(x2, y)); dc.SetPen(m_penDarkGrey); - dc.DrawLine(x2 - 1, y2, x2 - 1, y + 1); + dc.DrawLine(REVERSE_FOR_VERTICAL(x2 - 1, y2), + REVERSE_FOR_VERTICAL(x2 - 1, y + 1)); if ( flags & wxCONTROL_SELECTED ) { dc.SetPen(m_penLightGrey); // overwrite the part of the border below this tab - dc.DrawLine(x + 1, y2 + 1, x2 - 1, y2 + 1); + dc.DrawLine(REVERSE_FOR_VERTICAL(x + 1, y2 + 1), + REVERSE_FOR_VERTICAL(x2 - 1, y2 + 1)); // and the shadow of the tab to the left of us - dc.DrawLine(x + 1, y + 2, x + 1, y2 + 1); + dc.DrawLine(REVERSE_FOR_VERTICAL(x + 1, y + 2), + REVERSE_FOR_VERTICAL(x + 1, y2 + 1)); } break; + case wxRIGHT: + // right orientation looks like bottom but IsVertical makes x and y reversed case wxBOTTOM: + // bottom is not vertical so use coordinates in written order dc.SetPen(m_penHighlight); // we need to continue one pixel further to overwrite the corner of // the border for the selected tab - dc.DrawLine(x, y - (flags & wxCONTROL_SELECTED ? 1 : 0), - x, y2); + dc.DrawLine(REVERSE_FOR_VERTICAL(x, y - (flags & wxCONTROL_SELECTED ? 1 : 0)), + REVERSE_FOR_VERTICAL(x, y2)); // it doesn't work like this (TODO: implement it properly) #if 0 // erase the corner of the tab to the right dc.SetPen(m_penLightGrey); - dc.DrawPoint(x2 - 1, y - 2); - dc.DrawPoint(x2 - 2, y - 2); - dc.DrawPoint(x2 - 2, y - 1); + dc.DrawPoint(REVERSE_FOR_VERTICAL(x2 - 1, y - 2)); + dc.DrawPoint(REVERSE_FOR_VERTICAL(x2 - 2, y - 2)); + dc.DrawPoint(REVERSE_FOR_VERTICAL(x2 - 2, y - 1)); #endif // 0 dc.SetPen(m_penBlack); - dc.DrawLine(x + 1, y2, x2, y2); - dc.DrawLine(x2, y, x2, y2); + dc.DrawLine(REVERSE_FOR_VERTICAL(x + 1, y2), + REVERSE_FOR_VERTICAL(x2, y2)); + dc.DrawLine(REVERSE_FOR_VERTICAL(x2, y), + REVERSE_FOR_VERTICAL(x2, y2)); dc.SetPen(m_penDarkGrey); - dc.DrawLine(x + 2, y2 - 1, x2 - 1, y2 - 1); - dc.DrawLine(x2 - 1, y, x2 - 1, y2); + dc.DrawLine(REVERSE_FOR_VERTICAL(x + 2, y2 - 1), + REVERSE_FOR_VERTICAL(x2 - 1, y2 - 1)); + dc.DrawLine(REVERSE_FOR_VERTICAL(x2 - 1, y), + REVERSE_FOR_VERTICAL(x2 - 1, y2)); if ( flags & wxCONTROL_SELECTED ) { dc.SetPen(m_penLightGrey); // overwrite the part of the (double!) border above this tab - dc.DrawLine(x + 1, y - 1, x2 - 1, y - 1); - dc.DrawLine(x + 1, y - 2, x2 - 1, y - 2); + dc.DrawLine(REVERSE_FOR_VERTICAL(x + 1, y - 1), + REVERSE_FOR_VERTICAL(x2 - 1, y - 1)); + dc.DrawLine(REVERSE_FOR_VERTICAL(x + 1, y - 2), + REVERSE_FOR_VERTICAL(x2 - 1, y - 2)); // and the shadow of the tab to the left of us - dc.DrawLine(x + 1, y2 - 1, x + 1, y - 1); + dc.DrawLine(REVERSE_FOR_VERTICAL(x + 1, y2 - 1), + REVERSE_FOR_VERTICAL(x + 1, y - 1)); } break; - - case wxLEFT: - case wxRIGHT: - wxFAIL_MSG(_T("TODO")); } } diff --git a/src/univ/themes/win32.cpp b/src/univ/themes/win32.cpp index af2f0c4a28..e5760cca77 100644 --- a/src/univ/themes/win32.cpp +++ b/src/univ/themes/win32.cpp @@ -2503,9 +2503,8 @@ void wxWin32Renderer::DrawTab(wxDC& dc, const wxSize indent = GetTabIndent(); if ( flags & wxCONTROL_SELECTED ) { - rect.Inflate( isVertical ? 0 : indent.x, - isVertical ? indent.y : 0 - ); + rect.Inflate( SELECT_FOR_VERTICAL( indent.x , 0), + SELECT_FOR_VERTICAL( 0, indent.y )); switch ( dir ) { default: