From: Václav Slavík Date: Sun, 23 Sep 2001 22:42:57 +0000 (+0000) Subject: partial implementation of wxTLW's decorations X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/24a23c35730c9dbf6006e45947792204b9417204 partial implementation of wxTLW's decorations git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11683 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/univ/colschem.h b/include/wx/univ/colschem.h index 7e3f5d7333..2b29bbe79a 100644 --- a/include/wx/univ/colschem.h +++ b/include/wx/univ/colschem.h @@ -57,6 +57,11 @@ public: SHADOW_HIGHLIGHT, SHADOW_IN, SHADOW_OUT, + + // the titlebar background colours for the normal and focused states + TITLEBAR, + TITLEBAR_ACTIVE, + TITLEBAR_TEXT, MAX }; diff --git a/include/wx/univ/renderer.h b/include/wx/univ/renderer.h index 5af129e218..e71426e6ee 100644 --- a/include/wx/univ/renderer.h +++ b/include/wx/univ/renderer.h @@ -245,6 +245,42 @@ public: wxCoord y, const wxMenuGeometryInfo& geomInfo) = 0; #endif + // draw complete frame/dialog titlebar + virtual void DrawFrameTitleBar(wxDC& dc, + const wxRect& rect, + const wxString& title, + const wxIcon& icon, + int flags, + int pressedButtons = 0) = 0; + + // draw frame borders + virtual void DrawFrameBorder(wxDC& dc, + const wxRect& rect, + int flags) = 0; + + // draw frame titlebar background + virtual void DrawFrameBackground(wxDC& dc, + const wxRect& rect, + int flags) = 0; + + // draw frame title + virtual void DrawFrameTitle(wxDC& dc, + const wxRect& rect, + const wxString& title, + int flags) = 0; + + // draw frame icon + virtual void DrawFrameIcon(wxDC& dc, + const wxRect& rect, + const wxIcon& icon, + int flags) = 0; + + // draw frame buttons + virtual void DrawFrameButton(wxDC& dc, + wxCoord x, wxCoord y, + int button, + int flags = 0) = 0; + // misc functions // -------------- @@ -348,6 +384,15 @@ public: virtual wxMenuGeometryInfo *GetMenuGeometry(wxWindow *win, const wxMenu& menu) const = 0; #endif + + // get client area rectangle of top level window (i.e. subtract + // decorations from given rectangle) + virtual wxRect GetFrameClientArea(const wxRect& rect, int flags) const = 0; + // get size of whole top level window, given size of its client area size + virtual wxSize GetFrameTotalSize(const wxSize& clientSize, int flags) const = 0; + // get titlebar icon size + virtual wxSize GetFrameIconSize() const = 0; + // virtual dtor for any base class virtual ~wxRenderer(); @@ -572,10 +617,41 @@ public: const wxMenuGeometryInfo& geomInfo) { m_renderer->DrawMenuSeparator(dc, y, geomInfo); } #endif + virtual void DrawFrameTitleBar(wxDC& dc, + const wxRect& rect, + const wxString& title, + const wxIcon& icon, + int flags, + int pressedButtons = 0) + { m_renderer->DrawFrameTitleBar(dc, rect, title, icon, flags, pressedButtons); } + virtual void DrawFrameBorder(wxDC& dc, + const wxRect& rect, + int flags) + { m_renderer->DrawFrameBorder(dc, rect, flags); } + virtual void DrawFrameBackground(wxDC& dc, + const wxRect& rect, + int flags) + { m_renderer->DrawFrameBackground(dc, rect, flags); } + virtual void DrawFrameTitle(wxDC& dc, + const wxRect& rect, + const wxString& title, + int flags) + { m_renderer->DrawFrameTitle(dc, rect, title, flags); } + virtual void DrawFrameIcon(wxDC& dc, + const wxRect& rect, + const wxIcon& icon, + int flags) + { m_renderer->DrawFrameIcon(dc, rect, icon, flags); } + virtual void DrawFrameButton(wxDC& dc, + wxCoord x, wxCoord y, + int button, + int flags = 0) + { m_renderer->DrawFrameButton(dc, x, y, button, flags); } + virtual void GetComboBitmaps(wxBitmap *bmpNormal, wxBitmap *bmpFocus, wxBitmap *bmpPressed, - wxBitmap *bmpDisabled) + wxBitmap *bmpDisabled) const { m_renderer->GetComboBitmaps(bmpNormal, bmpFocus, bmpPressed, bmpDisabled); } @@ -641,6 +717,13 @@ public: const wxMenu& menu) const { return m_renderer->GetMenuGeometry(win, menu); } #endif + virtual wxRect GetFrameClientArea(const wxRect& rect, int flags) const + { return m_renderer->GetFrameClientArea(rect, flags); } + virtual wxSize GetFrameTotalSize(const wxSize& clientSize, int flags) const + { return m_renderer->GetFrameTotalSize(clientSize, flags); } + virtual wxSize GetFrameIconSize() const + { return m_renderer->GetFrameIconSize(); } + protected: wxRenderer *m_renderer; }; diff --git a/include/wx/univ/toplevel.h b/include/wx/univ/toplevel.h index 5d2aa3161f..5ec1389c9f 100644 --- a/include/wx/univ/toplevel.h +++ b/include/wx/univ/toplevel.h @@ -15,12 +15,33 @@ #pragma interface "univtoplevel.h" #endif +#include "wx/univ/inpcons.h" + +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- + +// frame decorations type flags used in wxRenderer and wxColourScheme +enum +{ + wxTOPLEVEL_BORDER = 0x00000001, + wxTOPLEVEL_MAXIMIZED = 0x00000002, + wxTOPLEVEL_TITLEBAR = 0x00000004, + wxTOPLEVEL_RESIZEABLE = 0x00000008, + wxTOPLEVEL_ICON = 0x00000010, + wxTOPLEVEL_CLOSE_BUTTON = 0x00000020, + wxTOPLEVEL_MAXIMIZE_BUTTON = 0x00000040, + wxTOPLEVEL_MINIMIZE_BUTTON = 0x00000080, + wxTOPLEVEL_RESTORE_BUTTON = 0x00000100, + wxTOPLEVEL_HELP_BUTTON = 0x00000200, + wxTOPLEVEL_ACTIVE = 0x00000400 +}; //----------------------------------------------------------------------------- // wxTopLevelWindow //----------------------------------------------------------------------------- -class wxTopLevelWindow : public wxTopLevelWindowNative +class WXDLLEXPORT wxTopLevelWindow : public wxTopLevelWindowNative { public: // construction @@ -48,15 +69,32 @@ public: // implement base class pure virtuals virtual bool ShowFullScreen(bool show, long style = wxFULLSCREEN_ALL); + virtual wxPoint GetClientAreaOrigin() const; + virtual void DoGetClientSize(int *width, int *height) const; + virtual void DoSetClientSize(int width, int height); + virtual void SetIcon(const wxIcon& icon); // implementation from now on // -------------------------- - DECLARE_DYNAMIC_CLASS(wxTopLevelWindow) - protected: // common part of all ctors void Init(); + + // return wxTOPLEVEL_xxx combination based on current state of the frame + long GetDecorationsStyle() const; + + DECLARE_DYNAMIC_CLASS(wxTopLevelWindow) + DECLARE_EVENT_TABLE() + void OnNcPaint(wxPaintEvent& event); + + // TRUE if wxTLW should render decorations (aka titlebar) itself + static int ms_drawDecorations; + // true for currently active frame + bool m_isActive:1; + // version of icon for titlebar (16x16) + wxIcon m_titlebarIcon; + }; #endif // __WX_UNIV_TOPLEVEL_H__ diff --git a/src/univ/themes/gtk.cpp b/src/univ/themes/gtk.cpp index feebb01f7d..4a0bcfdcc8 100644 --- a/src/univ/themes/gtk.cpp +++ b/src/univ/themes/gtk.cpp @@ -205,6 +205,37 @@ public: wxCoord y, const wxMenuGeometryInfo& geomInfo); #endif + + virtual void DrawFrameTitleBar(wxDC& dc, + const wxRect& rect, + const wxString& title, + const wxIcon& icon, + int flags, + int pressedButtons = 0); + virtual void DrawFrameBorder(wxDC& dc, + const wxRect& rect, + int flags); + virtual void DrawFrameBackground(wxDC& dc, + const wxRect& rect, + int flags); + virtual void DrawFrameTitle(wxDC& dc, + const wxRect& rect, + const wxString& title, + int flags); + virtual void DrawFrameIcon(wxDC& dc, + const wxRect& rect, + const wxIcon& icon, + int flags); + virtual void DrawFrameButton(wxDC& dc, + wxCoord x, wxCoord y, + int button, + int flags = 0); + + // titlebars + virtual wxRect GetFrameClientArea(const wxRect& rect, int flags) const; + virtual wxSize GetFrameTotalSize(const wxSize& clientSize, int flags) const; + virtual wxSize GetFrameIconSize() const; + virtual void GetComboBitmaps(wxBitmap *bmpNormal, wxBitmap *bmpFocus, wxBitmap *bmpPressed, @@ -2339,6 +2370,69 @@ void wxGTKRenderer::AdjustSize(wxSize *size, const wxWindow *window) } } +// ---------------------------------------------------------------------------- +// top level windows +// ---------------------------------------------------------------------------- + +void wxGTKRenderer::DrawFrameTitleBar(wxDC& dc, + const wxRect& rect, + const wxString& title, + const wxIcon& icon, + int flags, + int pressedButtons = 0) +{ +} + +void wxGTKRenderer::DrawFrameBorder(wxDC& dc, + const wxRect& rect, + int flags) +{ +} + +void wxGTKRenderer::DrawFrameBackground(wxDC& dc, + const wxRect& rect, + int flags) +{ +} + +void wxGTKRenderer::DrawFrameTitle(wxDC& dc, + const wxRect& rect, + const wxString& title, + int flags) +{ +} + +void wxGTKRenderer::DrawFrameIcon(wxDC& dc, + const wxRect& rect, + const wxIcon& icon, + int flags) +{ +} + +void wxGTKRenderer::DrawFrameButton(wxDC& dc, + wxCoord x, wxCoord y, + int button, + int flags = 0) +{ +} + +wxRect wxGTKRenderer::GetFrameClientArea(const wxRect& rect, int flags) const +{ + return rect; +} + +wxSize wxGTKRenderer::GetFrameTotalSize(const wxSize& clientSize, int flags) const +{ + return clientSize; +} + +wxSize wxGTKRenderer::GetFrameIconSize() const +{ + return wxSize(-1, -1); +} + + + // ============================================================================ // wxInputHandler // ============================================================================ diff --git a/src/univ/themes/win32.cpp b/src/univ/themes/win32.cpp index bb41a825ae..2e2df86135 100644 --- a/src/univ/themes/win32.cpp +++ b/src/univ/themes/win32.cpp @@ -51,7 +51,7 @@ #include "wx/menu.h" #include "wx/univ/scrtimer.h" - +#include "wx/toplevel.h" #include "wx/univ/renderer.h" #include "wx/univ/inphand.h" #include "wx/univ/colschem.h" @@ -67,6 +67,12 @@ static const int BORDER_THICKNESS = 2; static const int FOCUS_RECT_OFFSET_X = 1; static const int FOCUS_RECT_OFFSET_Y = 1; +static const int FRAME_BORDER_THICKNESS = 3; +static const int RESIZEABLE_FRAME_BORDER_THICKNESS = 4; +static const int FRAME_TITLEBAR_HEIGHT = 18; +static const int FRAME_BUTTON_WIDTH = 16; +static const int FRAME_BUTTON_HEIGHT = 14; + enum IndicatorType { IndicatorType_Check, @@ -118,6 +124,16 @@ public: Arrow_StateMax }; + enum wxFrameButtonType + { + FrameButton_Close, + FrameButton_Minimize, + FrameButton_Maximize, + FrameButton_Restore, + FrameButton_Help, + FrameButton_Max + }; + // ctor wxWin32Renderer(const wxColourScheme *scheme); @@ -258,6 +274,35 @@ public: wxCoord y, const wxMenuGeometryInfo& geomInfo); #endif + // titlebars + virtual void DrawFrameTitleBar(wxDC& dc, + const wxRect& rect, + const wxString& title, + const wxIcon& icon, + int flags, + int pressedButtons = 0); + virtual void DrawFrameBorder(wxDC& dc, + const wxRect& rect, + int flags); + virtual void DrawFrameBackground(wxDC& dc, + const wxRect& rect, + int flags); + virtual void DrawFrameTitle(wxDC& dc, + const wxRect& rect, + const wxString& title, + int flags); + virtual void DrawFrameIcon(wxDC& dc, + const wxRect& rect, + const wxIcon& icon, + int flags); + virtual void DrawFrameButton(wxDC& dc, + wxCoord x, wxCoord y, + int button, + int flags = 0); + virtual wxRect GetFrameClientArea(const wxRect& rect, int flags) const; + virtual wxSize GetFrameTotalSize(const wxSize& clientSize, int flags) const; + virtual wxSize GetFrameIconSize() const; + virtual void GetComboBitmaps(wxBitmap *bmpNormal, wxBitmap *bmpFocus, wxBitmap *bmpPressed, @@ -412,6 +457,11 @@ private: m_penDarkGrey, m_penLightGrey, m_penHighlight; + + wxFont m_titlebarFont; + + // titlebar icons: + wxBitmap m_bmpFrameButtons[FrameButton_Max]; // first row is for the normal state, second - for the disabled wxBitmap m_bmpArrows[Arrow_StateMax][Arrow_Max]; @@ -539,6 +589,83 @@ private: // standard bitmaps // ---------------------------------------------------------------------------- +// frame buttons bitmaps + +static const char *frame_button_close_xpm[] = { +"12 10 2 1", +" c None", +". c black", +" ", +" .. .. ", +" .. .. ", +" .... ", +" .. ", +" .... ", +" .. .. ", +" .. .. ", +" ", +" "}; + +static const char *frame_button_help_xpm[] = { +"12 10 2 1", +" c None", +". c #000000", +" .... ", +" .. .. ", +" .. .. ", +" .. ", +" .. ", +" .. ", +" ", +" .. ", +" .. ", +" "}; + +static const char *frame_button_maximize_xpm[] = { +"12 10 2 1", +" c None", +". c #000000", +" ......... ", +" ......... ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" ......... ", +" "}; + +static const char *frame_button_minimize_xpm[] = { +"12 10 2 1", +" c None", +". c #000000", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ...... ", +" ...... ", +" "}; + +static const char *frame_button_restore_xpm[] = { +"12 10 2 1", +" c None", +". c #000000", +" ...... ", +" ...... ", +" . . ", +" ...... . ", +" ...... . ", +" . ... ", +" . . ", +" . . ", +" ...... ", +" "}; + // menu bitmaps static const char *checked_menu_xpm[] = { @@ -1123,6 +1250,10 @@ wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col) const case CONTROL_TEXT_DISABLED_SHADOW: case SHADOW_OUT: return wxColour(GetSysColor(COLOR_BTNSHADOW)); + + case TITLEBAR: return wxColour(GetSysColor(COLOR_INACTIVECAPTION)); + case TITLEBAR_ACTIVE: return wxColour(GetSysColor(COLOR_ACTIVECAPTION)); + case TITLEBAR_TEXT: return wxColour(GetSysColor(COLOR_CAPTIONTEXT)); #else // !__WXMSW__ // use the standard Windows colours elsewhere case WINDOW: return *wxWHITE; @@ -1141,13 +1272,17 @@ wxColour wxWin32ColourScheme::Get(wxWin32ColourScheme::StdColour col) const case SHADOW_DARK: return *wxBLACK; - case CONTROL_TEXT_DISABLED: - case SHADOW_HIGHLIGHT: return wxColour(0xe0e0e0); + case CONTROL_TEXT_DISABLED:return wxColour(0xe0e0e0); + case SHADOW_HIGHLIGHT: return wxColour(0xffffff); case SHADOW_IN: return wxColour(0xc0c0c0); case CONTROL_TEXT_DISABLED_SHADOW: case SHADOW_OUT: return wxColour(0x7f7f7f); + + case TITLEBAR: return wxColour(0xaeaaae); + case TITLEBAR_ACTIVE: return wxColour(0x820300); + case TITLEBAR_TEXT: return *wxWHITE; #endif // __WXMSW__ case MAX: @@ -1181,6 +1316,9 @@ wxWin32Renderer::wxWin32Renderer(const wxColourScheme *scheme) m_colHighlight = wxSCHEME_COLOUR(scheme, SHADOW_HIGHLIGHT); m_penHighlight = wxPen(m_colHighlight, 0, wxSOLID); + + m_titlebarFont = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT); + m_titlebarFont.SetWeight(wxFONTWEIGHT_BOLD); // init the arrow bitmaps static const size_t ARROW_WIDTH = 7; @@ -1351,6 +1489,13 @@ wxWin32Renderer::wxWin32Renderer(const wxColourScheme *scheme) m_bmpArrows[Arrow_Pressed][n] = m_bmpArrows[Arrow_Normal][n]; } + + // init the frame buttons bitmaps + m_bmpFrameButtons[FrameButton_Close] = wxBitmap(frame_button_close_xpm); + m_bmpFrameButtons[FrameButton_Minimize] = wxBitmap(frame_button_minimize_xpm); + m_bmpFrameButtons[FrameButton_Maximize] = wxBitmap(frame_button_maximize_xpm); + m_bmpFrameButtons[FrameButton_Restore] = wxBitmap(frame_button_restore_xpm); + m_bmpFrameButtons[FrameButton_Help] = wxBitmap(frame_button_help_xpm); } // ---------------------------------------------------------------------------- @@ -2948,6 +3093,192 @@ int wxWin32Renderer::PixelToScrollbar(const wxScrollBar *scrollbar, return StandardPixelToScrollbar(scrollbar, coord, m_sizeScrollbarArrow); } +// ---------------------------------------------------------------------------- +// top level windows +// ---------------------------------------------------------------------------- + +void wxWin32Renderer::DrawFrameTitleBar(wxDC& dc, + const wxRect& rect, + const wxString& title, + const wxIcon& icon, + int flags, + int pressedButtons = 0) +{ + if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) ) + { + DrawFrameBorder(dc, rect, flags); + } + if ( flags & wxTOPLEVEL_TITLEBAR ) + { + DrawFrameBackground(dc, rect, flags); + if ( flags & wxTOPLEVEL_ICON ) + DrawFrameIcon(dc, rect, icon, flags); + DrawFrameTitle(dc, rect, title, flags); + + wxRect client = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR); + wxCoord x,y; + x = client.GetRight() -2 - FRAME_BUTTON_WIDTH; + y = client.GetTop() + (FRAME_TITLEBAR_HEIGHT-FRAME_BUTTON_HEIGHT)/2; + + if ( flags & wxTOPLEVEL_CLOSE_BUTTON ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_CLOSE_BUTTON); + x -= FRAME_BUTTON_WIDTH + 2; + } + if ( flags & wxTOPLEVEL_MAXIMIZE_BUTTON ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_MAXIMIZE_BUTTON); + x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_RESTORE_BUTTON ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_RESTORE_BUTTON); + x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_MINIMIZE_BUTTON ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_MINIMIZE_BUTTON); + x -= FRAME_BUTTON_WIDTH; + } + if ( flags & wxTOPLEVEL_HELP_BUTTON ) + { + DrawFrameButton(dc, x, y, wxTOPLEVEL_HELP_BUTTON); + x -= FRAME_BUTTON_WIDTH; + } + } +} + +void wxWin32Renderer::DrawFrameBorder(wxDC& dc, + const wxRect& rect, + int flags) +{ + if ( !(flags & wxTOPLEVEL_BORDER) ) return; + + wxRect r(rect); + + DrawShadedRect(dc, &r, m_penLightGrey, m_penBlack); + DrawShadedRect(dc, &r, m_penHighlight, m_penDarkGrey); + DrawShadedRect(dc, &r, m_penLightGrey, m_penLightGrey); + if ( flags & wxTOPLEVEL_RESIZEABLE ) + DrawShadedRect(dc, &r, m_penLightGrey, m_penLightGrey); +} + +void wxWin32Renderer::DrawFrameBackground(wxDC& dc, + const wxRect& rect, + int flags) +{ + if ( !(flags & wxTOPLEVEL_TITLEBAR) ) return; + + wxColour col = (flags & wxTOPLEVEL_ACTIVE) ? + wxSCHEME_COLOUR(m_scheme, TITLEBAR_ACTIVE) : + wxSCHEME_COLOUR(m_scheme, TITLEBAR); + + wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR); + r.height = FRAME_TITLEBAR_HEIGHT; + + DrawBackground(dc, col, r); +} + +void wxWin32Renderer::DrawFrameTitle(wxDC& dc, + const wxRect& rect, + const wxString& title, + int flags) +{ + wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR); + r.height = FRAME_TITLEBAR_HEIGHT; + if ( flags & wxTOPLEVEL_ICON ) + r.x += FRAME_TITLEBAR_HEIGHT; + else + r.x += 1; + + dc.SetFont(m_titlebarFont); + dc.SetTextForeground(wxSCHEME_COLOUR(m_scheme, TITLEBAR_TEXT)); + dc.DrawLabel(title, wxNullBitmap, r, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL); +} + +void wxWin32Renderer::DrawFrameIcon(wxDC& dc, + const wxRect& rect, + const wxIcon& icon, + int flags) +{ + wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR); + dc.DrawIcon(icon, r.x, r.y); +} + +void wxWin32Renderer::DrawFrameButton(wxDC& dc, + wxCoord x, wxCoord y, + int button, + int flags = 0) +{ + wxRect r(x, y, FRAME_BUTTON_WIDTH, FRAME_BUTTON_HEIGHT); + + DrawShadedRect(dc, &r, m_penHighlight, m_penBlack); + DrawShadedRect(dc, &r, m_penLightGrey, m_penDarkGrey); + DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), r); + + size_t idx = 0; + switch (button) + { + case wxTOPLEVEL_CLOSE_BUTTON: idx = FrameButton_Close; break; + case wxTOPLEVEL_MAXIMIZE_BUTTON: idx = FrameButton_Maximize; break; + case wxTOPLEVEL_MINIMIZE_BUTTON: idx = FrameButton_Minimize; break; + case wxTOPLEVEL_RESTORE_BUTTON: idx = FrameButton_Restore; break; + case wxTOPLEVEL_HELP_BUTTON: idx = FrameButton_Help; break; + default: + wxFAIL_MSG(wxT("incorrect button specification")); + } + + dc.DrawBitmap(m_bmpFrameButtons[idx], r.x, r.y, TRUE); +} + + +wxRect wxWin32Renderer::GetFrameClientArea(const wxRect& rect, + int flags) const +{ + wxRect r(rect); + + if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) ) + { + int border = (flags & wxTOPLEVEL_RESIZEABLE) ? + RESIZEABLE_FRAME_BORDER_THICKNESS : + FRAME_BORDER_THICKNESS; + r.Inflate(-border); + } + if ( flags & wxTOPLEVEL_TITLEBAR ) + { + r.y += FRAME_TITLEBAR_HEIGHT; + r.height -= FRAME_TITLEBAR_HEIGHT; + } + + return r; +} + +wxSize wxWin32Renderer::GetFrameTotalSize(const wxSize& clientSize, + int flags) const +{ + wxSize s(clientSize); + + if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) ) + { + int border = (flags & wxTOPLEVEL_RESIZEABLE) ? + RESIZEABLE_FRAME_BORDER_THICKNESS : + FRAME_BORDER_THICKNESS; + s.x += 2*border; + s.y += 2*border; + } + if ( flags & wxTOPLEVEL_TITLEBAR ) + s.y += FRAME_TITLEBAR_HEIGHT; + + return s; +} + +wxSize wxWin32Renderer::GetFrameIconSize() const +{ + return wxSize(16, 16); +} + + + // ---------------------------------------------------------------------------- // text control geometry // ---------------------------------------------------------------------------- diff --git a/src/univ/topluniv.cpp b/src/univ/topluniv.cpp index d948509858..b592cbf6ab 100644 --- a/src/univ/topluniv.cpp +++ b/src/univ/topluniv.cpp @@ -27,6 +27,10 @@ #include "wx/defs.h" #include "wx/toplevel.h" +#include "wx/univ/renderer.h" +#include "wx/dcclient.h" +#include "wx/bitmap.h" +#include "wx/image.h" // ---------------------------------------------------------------------------- @@ -35,13 +39,20 @@ IMPLEMENT_DYNAMIC_CLASS(wxTopLevelWindow, wxWindow) +BEGIN_EVENT_TABLE(wxTopLevelWindow, wxTopLevelWindowNative) + EVT_NC_PAINT(wxTopLevelWindow::OnNcPaint) +END_EVENT_TABLE() + // ============================================================================ // implementation // ============================================================================ +int wxTopLevelWindow::ms_drawDecorations = -1; + void wxTopLevelWindow::Init() { + m_isActive = FALSE; } bool wxTopLevelWindow::Create(wxWindow *parent, @@ -52,13 +63,35 @@ bool wxTopLevelWindow::Create(wxWindow *parent, long style, const wxString &name) { + long styleOrig, exstyleOrig; + + if ( ms_drawDecorations == -1 ) + ms_drawDecorations = TRUE; + // FIXME_MGL -- this is temporary; we assume for now that native TLW + // can't do decorations, which is not true + + if ( ms_drawDecorations ) + { + styleOrig = style; + exstyleOrig = GetExtraStyle(); + style &= ~(wxCAPTION | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | + wxSYSTEM_MENU | wxRESIZE_BORDER | wxFRAME_TOOL_WINDOW | + wxTHICK_FRAME); + style = wxSIMPLE_BORDER; + SetExtraStyle(exstyleOrig & + ~(wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP)); + } + if ( !wxTopLevelWindowNative::Create(parent, id, title, pos, sizeOrig, style, name) ) return FALSE; - - // FIXME_MGL -- this is temporary; we assume for now that native TLW - // can do decorations, which is not true for MGL + if ( ms_drawDecorations ) + { + m_windowStyle = styleOrig; + m_exStyle = exstyleOrig; + } + return TRUE; } @@ -72,3 +105,135 @@ bool wxTopLevelWindow::ShowFullScreen(bool show, long style) // native decorations mode } +long wxTopLevelWindow::GetDecorationsStyle() const +{ + long style = 0; + + if ( m_windowStyle & wxCAPTION ) + { + style |= wxTOPLEVEL_TITLEBAR | wxTOPLEVEL_CLOSE_BUTTON; + if ( m_windowStyle & wxMINIMIZE_BOX ) + style |= wxTOPLEVEL_MINIMIZE_BUTTON; + if ( m_windowStyle & wxMAXIMIZE_BOX ) + style |= wxTOPLEVEL_MAXIMIZE_BUTTON; + if ( m_exStyle & (wxFRAME_EX_CONTEXTHELP | wxDIALOG_EX_CONTEXTHELP)) + style |= wxTOPLEVEL_HELP_BUTTON; + } + if ( (m_windowStyle & (wxSIMPLE_BORDER | wxNO_BORDER)) == 0 ) + style |= wxTOPLEVEL_BORDER; + if ( m_windowStyle & (wxRESIZE_BORDER | wxTHICK_FRAME) ) + style |= wxTOPLEVEL_RESIZEABLE; + + if ( IsMaximized() ) + style |= wxTOPLEVEL_MAXIMIZED; + if ( GetIcon().Ok() ) + style |= wxTOPLEVEL_ICON; + if ( /*m_isActive*/ 1 /* FIXME_MGL*/ ) + style |= wxTOPLEVEL_ACTIVE; + + return style; +} + +// ---------------------------------------------------------------------------- +// client area handling +// ---------------------------------------------------------------------------- + +wxPoint wxTopLevelWindow::GetClientAreaOrigin() const +{ + if ( ms_drawDecorations ) + { + int w, h; + wxTopLevelWindowNative::DoGetClientSize(&w, &h); + wxRect rect = wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(), + wxSize(w, h)); + rect = m_renderer->GetFrameClientArea(rect, + GetDecorationsStyle()); + return rect.GetPosition(); + } + else + { + return wxTopLevelWindowNative::GetClientAreaOrigin(); + } +} + +void wxTopLevelWindow::DoGetClientSize(int *width, int *height) const +{ + if ( ms_drawDecorations ) + { + int w, h; + wxTopLevelWindowNative::DoGetClientSize(&w, &h); + wxRect rect = wxRect(wxTopLevelWindowNative::GetClientAreaOrigin(), + wxSize(w, h)); + rect = m_renderer->GetFrameClientArea(rect, + GetDecorationsStyle()); + if ( width ) + *width = rect.width; + if ( height ) + *height = rect.height; + } + else + wxTopLevelWindowNative::DoGetClientSize(width, height); +} + +void wxTopLevelWindow::DoSetClientSize(int width, int height) +{ + if ( ms_drawDecorations ) + { + wxSize size = m_renderer->GetFrameTotalSize(wxSize(width, height), + GetDecorationsStyle()); + wxTopLevelWindowNative::DoSetClientSize(size.x, size.y); + } + else + wxTopLevelWindowNative::DoSetClientSize(width, height); +} + +void wxTopLevelWindow::OnNcPaint(wxPaintEvent& event) +{ + if ( !ms_drawDecorations || !m_renderer ) + event.Skip(); + else + { + // get the window rect + wxRect rect; + wxSize size = GetSize(); + rect.x = + rect.y = 0; + rect.width = size.x; + rect.height = size.y; + + wxWindowDC dc(this); + m_renderer->DrawFrameTitleBar(dc, rect, + GetTitle(), m_titlebarIcon, + GetDecorationsStyle()); + } +} + +// ---------------------------------------------------------------------------- +// icons +// ---------------------------------------------------------------------------- + +void wxTopLevelWindow::SetIcon(const wxIcon& icon) +{ + wxTopLevelWindowNative::SetIcon(icon); + if ( !m_renderer ) return; + + wxSize size = m_renderer->GetFrameIconSize(); + + if ( !icon.Ok() || size.x == -1 ) + m_titlebarIcon = icon; + else + { + wxBitmap bmp1; + bmp1.CopyFromIcon(icon); + if ( !bmp1.Ok() ) + m_titlebarIcon = wxNullIcon; + else if ( bmp1.GetWidth() == size.x && bmp1.GetHeight() == size.y ) + m_titlebarIcon = icon; + else + { + wxImage img = bmp1.ConvertToImage(); + img.Rescale(size.x, size.y); + m_titlebarIcon.CopyFromBitmap(wxBitmap(img)); + } + } +}