#include "wx/scrolbar.h"
#include "wx/slider.h"
#include "wx/textctrl.h"
+ #include "wx/toolbar.h"
#ifdef __WXMSW__
// for COLOR_* constants
#include "wx/spinbutt.h"
#include "wx/settings.h"
#include "wx/menu.h"
+#include "wx/artprov.h"
+#include "wx/toplevel.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"
virtual void DrawBackground(wxDC& dc,
const wxColour& col,
const wxRect& rect,
- int flags = 0);
+ int flags = 0,
+ wxWindow *window = NULL);
virtual void DrawLabel(wxDC& dc,
const wxString& label,
const wxRect& rect,
int flags = 0,
wxAlignment align = wxALIGN_LEFT,
int indexAccel = -1);
+ virtual void DrawToolBarButton(wxDC& dc,
+ const wxString& label,
+ const wxBitmap& bitmap,
+ const wxRect& rect,
+ int flags);
virtual void DrawTextLine(wxDC& dc,
const wxString& text,
const wxRect& rect,
virtual wxSize GetFrameIconSize() const;
virtual int HitTestFrame(const wxRect& rect, const wxPoint& pt, int flags) const;
- virtual wxIcon GetStdIcon(int which) const;
-
virtual void GetComboBitmaps(wxBitmap *bmpNormal,
wxBitmap *bmpFocus,
wxBitmap *bmpPressed,
virtual wxCoord GetCheckItemMargin() const
{ return 0; }
+ virtual wxSize GetToolBarButtonSize(wxCoord *separator) const
+ { if ( separator ) *separator = 5; return wxSize(16, 15); }
+ virtual wxSize GetToolBarMargin() const
+ { return wxSize(4, 4); }
+
virtual wxRect GetTextTotalArea(const wxTextCtrl *text,
- const wxRect& rect);
+ const wxRect& rect) const;
virtual wxRect GetTextClientArea(const wxTextCtrl *text,
const wxRect& rect,
- wxCoord *extraSpaceBeyond);
+ wxCoord *extraSpaceBeyond) const;
virtual wxSize GetTabIndent() const { return wxSize(2, 2); }
virtual wxSize GetTabPadding() const { return wxSize(6, 5); }
// DrawButtonBorder() helper
void DoDrawBackground(wxDC& dc,
const wxColour& col,
- const wxRect& rect);
+ const wxRect& rect,
+ wxWindow *window = NULL );
// DrawBorder() helpers: all of them shift and clip the DC after drawing
// the border
bool m_isOnGrip;
};
+class wxWin32SystemMenuEvtHandler;
+
class wxWin32FrameInputHandler : public wxStdFrameInputHandler
{
public:
- wxWin32FrameInputHandler(wxInputHandler *handler)
- : wxStdFrameInputHandler(handler) { }
+ wxWin32FrameInputHandler(wxInputHandler *handler);
+ ~wxWin32FrameInputHandler();
virtual bool HandleMouse(wxInputConsumer *control,
const wxMouseEvent& event);
+
+ virtual bool HandleActivation(wxInputConsumer *consumer, bool activated);
+
+ void PopupSystemMenu(wxTopLevelWindow *window, const wxPoint& pos) const;
+
+private:
+ // was the mouse over the grip last time we checked?
+ wxWin32SystemMenuEvtHandler *m_menuHandler;
};
// ----------------------------------------------------------------------------
virtual wxColour GetBackground(wxWindow *win) const;
};
+// ----------------------------------------------------------------------------
+// wxWin32ArtProvider
+// ----------------------------------------------------------------------------
+
+class wxWin32ArtProvider : public wxArtProvider
+{
+protected:
+ virtual wxBitmap CreateBitmap(const wxArtID& id,
+ const wxArtClient& client,
+ const wxSize& size);
+};
+
// ----------------------------------------------------------------------------
// wxWin32Theme
// ----------------------------------------------------------------------------
virtual ~wxWin32Theme();
virtual wxRenderer *GetRenderer();
+ virtual wxArtProvider *GetArtProvider();
virtual wxInputHandler *GetInputHandler(const wxString& control);
virtual wxColourScheme *GetColourScheme();
wxInputHandler *GetDefaultInputHandler();
wxWin32Renderer *m_renderer;
+
+ wxWin32ArtProvider *m_artProvider;
// the names of the already created handlers and the handlers themselves
// (these arrays are synchronized)
m_scheme = NULL;
m_renderer = NULL;
m_handlerDefault = NULL;
+ m_artProvider = NULL;
}
wxWin32Theme::~wxWin32Theme()
delete m_renderer;
delete m_scheme;
+ wxArtProvider::RemoveProvider(m_artProvider);
}
wxRenderer *wxWin32Theme::GetRenderer()
return m_renderer;
}
+wxArtProvider *wxWin32Theme::GetArtProvider()
+{
+ if ( !m_artProvider )
+ {
+ m_artProvider = new wxWin32ArtProvider;
+ }
+
+ return m_artProvider;
+}
+
wxInputHandler *wxWin32Theme::GetDefaultInputHandler()
{
if ( !m_handlerDefault )
else if ( control == wxINP_HANDLER_STATUSBAR )
handler = new wxWin32StatusBarInputHandler(GetDefaultInputHandler());
#endif // wxUSE_STATUSBAR
+#if wxUSE_TOOLBAR
+ else if ( control == wxINP_HANDLER_TOOLBAR )
+ handler = new wxStdToolbarInputHandler(GetDefaultInputHandler());
+#endif // wxUSE_TOOLBAR
else if ( control == wxINP_HANDLER_TOPLEVEL )
handler = new wxWin32FrameInputHandler(GetDefaultInputHandler());
else
case CONTROL_TEXT: return wxColour(GetSysColor(COLOR_BTNTEXT));
- case SCROLLBAR: return wxColour(GetSysColor(COLOR_SCROLLBAR));
- case SCROLLBAR_PRESSED: return wxColour(GetSysColor(COLOR_HIGHLIGHT));
+#if defined(COLOR_3DLIGHT)
+ case SCROLLBAR: return wxColour(GetSysColor(COLOR_3DLIGHT));
+#else
+ case SCROLLBAR: return wxColour(0xe0e0e0);
+#endif
+ case SCROLLBAR_PRESSED: return wxColour(GetSysColor(COLOR_BTNTEXT));
case HIGHLIGHT: return wxColour(GetSysColor(COLOR_HIGHLIGHT));
case HIGHLIGHT_TEXT: return wxColour(GetSysColor(COLOR_HIGHLIGHTTEXT));
case TITLEBAR_ACTIVE: return wxColour(GetSysColor(COLOR_ACTIVECAPTION));
case TITLEBAR_TEXT: return wxColour(GetSysColor(COLOR_INACTIVECAPTIONTEXT));
case TITLEBAR_ACTIVE_TEXT: return wxColour(GetSysColor(COLOR_CAPTIONTEXT));
-
+
case DESKTOP: return wxColour(0x808000);
#else // !__WXMSW__
// use the standard Windows colours elsewhere
break;
default:
+ {
+ // char *crash = NULL;
+ // *crash = 0;
wxFAIL_MSG(_T("unknown border type"));
// fall through
+ }
case wxBORDER_DEFAULT:
case wxBORDER_NONE:
0); // no focus rect offset for checkboxes
}
+void wxWin32Renderer::DrawToolBarButton(wxDC& dc,
+ const wxString& label,
+ const wxBitmap& bitmap,
+ const wxRect& rectOrig,
+ int flags)
+{
+ if ( !label.empty() || bitmap.Ok() )
+ {
+ wxRect rect = rectOrig;
+ rect.Deflate(BORDER_THICKNESS);
+
+ if ( flags & wxCONTROL_PRESSED )
+ {
+ DrawBorder(dc, wxBORDER_SUNKEN, rect, flags);
+ }
+ else if ( flags & wxCONTROL_CURRENT )
+ {
+ DrawBorder(dc, wxBORDER_RAISED, rect, flags);
+ }
+
+ dc.DrawLabel(label, bitmap, rect, wxALIGN_CENTRE);
+ }
+ else // a separator
+ {
+ // leave a small gap aroudn the line, also account for the toolbar
+ // border itself
+ DrawVerticalLine(dc, rectOrig.x + rectOrig.width/2,
+ rectOrig.y + 2*BORDER_THICKNESS,
+ rectOrig.GetBottom() - BORDER_THICKNESS);
+ }
+}
+
// ----------------------------------------------------------------------------
// text control
// ----------------------------------------------------------------------------
void wxWin32Renderer::DoDrawBackground(wxDC& dc,
const wxColour& col,
- const wxRect& rect)
+ const wxRect& rect,
+ wxWindow *window )
{
wxBrush brush(col, wxSOLID);
dc.SetBrush(brush);
void wxWin32Renderer::DrawBackground(wxDC& dc,
const wxColour& col,
const wxRect& rect,
- int flags)
+ int flags,
+ wxWindow *window )
{
// just fill it with the given or default bg colour
wxColour colBg = col.Ok() ? col : wxSCHEME_COLOUR(m_scheme, CONTROL);
- DoDrawBackground(dc, colBg, rect);
+ DoDrawBackground(dc, colBg, rect, window );
}
// ----------------------------------------------------------------------------
dc.SetFont(m_titlebarFont);
dc.SetTextForeground(col);
-
+
wxCoord textW;
dc.GetTextExtent(title, &textW, NULL);
if ( textW > r.width )
s << title[i];
}
s << wxT("...");
- dc.DrawLabel(s, wxNullBitmap, r,
+ dc.DrawLabel(s, wxNullBitmap, r,
wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL);
}
else
- dc.DrawLabel(title, wxNullBitmap, r,
+ dc.DrawLabel(title, wxNullBitmap, r,
wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL);
}
"....ddddddddddddddddddddddddddd.",
".....ddddddddddddddddddddddddd.."};
-wxIcon wxWin32Renderer::GetStdIcon(int which) const
+wxBitmap wxWin32ArtProvider::CreateBitmap(const wxArtID& id,
+ const wxArtClient& WXUNUSED(client),
+ const wxSize& WXUNUSED(size))
{
- switch(which)
- {
- case wxICON_INFORMATION:
- return wxIcon(info_xpm);
-
- case wxICON_QUESTION:
- return wxIcon(question_xpm);
-
- case wxICON_EXCLAMATION:
- return wxIcon(warning_xpm);
-
- default:
- wxFAIL_MSG(wxT("requested non existent standard icon"));
- // still fall through
-
- case wxICON_HAND:
- return wxIcon(error_xpm);
- }
+ if ( id == wxART_INFORMATION )
+ return wxBitmap(info_xpm);
+ if ( id == wxART_ERROR )
+ return wxBitmap(error_xpm);
+ if ( id == wxART_WARNING )
+ return wxBitmap(warning_xpm);
+ if ( id == wxART_QUESTION )
+ return wxBitmap(question_xpm);
+ return wxNullBitmap;
}
}
wxRect wxWin32Renderer::GetTextTotalArea(const wxTextCtrl *text,
- const wxRect& rect)
+ const wxRect& rect) const
{
wxRect rectTotal = rect;
wxRect wxWin32Renderer::GetTextClientArea(const wxTextCtrl *text,
const wxRect& rect,
- wxCoord *extraSpaceBeyond)
+ wxCoord *extraSpaceBeyond) const
{
wxRect rectText = rect;
if ( event.ButtonDown() )
{
wxWindow *win = control->GetInputWindow();
-
- if ( wxWindow::FindFocus() != control->GetInputWindow() )
+
+ if (( wxWindow::FindFocus() != control->GetInputWindow() ) &&
+ ( win->AcceptsFocus() ) )
{
win->SetFocus();
// if we're scrolling the scrollbar because the arrow or the shaft was
// pressed, check that the mouse stays on the same scrollbar element
+#if 0
+ // Always let thumb jump back if we leave the scrollbar
if ( event.Moving() )
{
ht = m_renderer->HitTestScrollbar(scrollbar, event.GetPosition());
{
ht = wxHT_NOWHERE;
}
+#else
+ // Jump back only if we get far away from it
+ wxPoint pos = event.GetPosition();
+ if (scrollbar->HasFlag( wxVERTICAL ))
+ {
+ if (pos.x > -40 && pos.x < scrollbar->GetSize().x+40)
+ pos.x = 5;
+ }
+ else
+ {
+ if (pos.y > -40 && pos.y < scrollbar->GetSize().y+40)
+ pos.y = 5;
+ }
+ ht = m_renderer->HitTestScrollbar(scrollbar, pos );
+#endif
// if we're dragging the thumb and the mouse stays in the scrollbar, it
// is still ok - we only want to catch the case when the mouse leaves
bool wxWin32StatusBarInputHandler::IsOnGrip(wxWindow *statbar,
const wxPoint& pt) const
{
- wxTopLevelWindow *parentTLW = wxDynamicCast(statbar->GetParent(), wxTopLevelWindow);
-
if ( statbar->HasFlag(wxST_SIZEGRIP) &&
- statbar->GetParent()->HasFlag(wxRESIZE_BORDER) &&
- parentTLW && !parentTLW->IsMaximized() )
+ statbar->GetParent()->HasFlag(wxRESIZE_BORDER) )
{
- wxSize sizeSbar = statbar->GetSize();
+ wxTopLevelWindow *
+ parentTLW = wxDynamicCast(statbar->GetParent(), wxTopLevelWindow);
+
+ wxCHECK_MSG( parentTLW, FALSE,
+ _T("the status bar should be a child of a TLW") );
- return (sizeSbar.x - pt.x) < (wxCoord)STATUSBAR_GRIP_SIZE &&
- (sizeSbar.y - pt.y) < (wxCoord)STATUSBAR_GRIP_SIZE;
+ // a maximized window can't be resized anyhow
+ if ( !parentTLW->IsMaximized() )
+ {
+ // VZ: I think that the standard Windows behaviour is to only
+ // show the resizing cursor when the mouse is on top of the
+ // grip itself but apparently different Windows versions behave
+ // differently (?) and it seems a better UI to allow resizing
+ // the status bar even when the mouse is above the grip
+ wxSize sizeSbar = statbar->GetSize();
+
+ int diff = sizeSbar.x - pt.x;
+ return diff >= 0 && diff < (wxCoord)STATUSBAR_GRIP_SIZE;
+ }
}
return FALSE;
// wxWin32FrameInputHandler
// ----------------------------------------------------------------------------
+class wxWin32SystemMenuEvtHandler : public wxEvtHandler
+{
+public:
+ wxWin32SystemMenuEvtHandler(wxWin32FrameInputHandler *handler);
+
+ void Attach(wxInputConsumer *consumer);
+ void Detach();
+
+private:
+ DECLARE_EVENT_TABLE()
+ void OnSystemMenu(wxCommandEvent &event);
+ void OnCloseFrame(wxCommandEvent &event);
+ void OnClose(wxCloseEvent &event);
+
+ wxWin32FrameInputHandler *m_inputHnd;
+ wxTopLevelWindow *m_wnd;
+ wxAcceleratorTable m_oldAccelTable;
+};
+
+wxWin32SystemMenuEvtHandler::wxWin32SystemMenuEvtHandler(
+ wxWin32FrameInputHandler *handler)
+{
+ m_inputHnd = handler;
+ m_wnd = NULL;
+}
+
+void wxWin32SystemMenuEvtHandler::Attach(wxInputConsumer *consumer)
+{
+ wxASSERT_MSG( m_wnd == NULL, _T("can't attach the handler twice!") );
+
+ m_wnd = wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
+ m_wnd->PushEventHandler(this);
+
+ // VS: This code relies on using generic implementation of
+ // wxAcceleratorTable in wxUniv!
+ wxAcceleratorTable table = *m_wnd->GetAcceleratorTable();
+ m_oldAccelTable = table;
+ table.Add(wxAcceleratorEntry(wxACCEL_ALT, WXK_SPACE, wxID_SYSTEM_MENU));
+ table.Add(wxAcceleratorEntry(wxACCEL_ALT, WXK_F4, wxID_CLOSE_FRAME));
+ m_wnd->SetAcceleratorTable(table);
+}
+
+void wxWin32SystemMenuEvtHandler::Detach()
+{
+ if ( m_wnd )
+ {
+ m_wnd->SetAcceleratorTable(m_oldAccelTable);
+ m_wnd->RemoveEventHandler(this);
+ m_wnd = NULL;
+ }
+}
+
+BEGIN_EVENT_TABLE(wxWin32SystemMenuEvtHandler, wxEvtHandler)
+ EVT_MENU(wxID_SYSTEM_MENU, wxWin32SystemMenuEvtHandler::OnSystemMenu)
+ EVT_MENU(wxID_CLOSE_FRAME, wxWin32SystemMenuEvtHandler::OnCloseFrame)
+ EVT_CLOSE(wxWin32SystemMenuEvtHandler::OnClose)
+END_EVENT_TABLE()
+
+void wxWin32SystemMenuEvtHandler::OnSystemMenu(wxCommandEvent &WXUNUSED(event))
+{
+ int border = ((m_wnd->GetWindowStyle() & wxRESIZE_BORDER) &&
+ !m_wnd->IsMaximized()) ?
+ RESIZEABLE_FRAME_BORDER_THICKNESS :
+ FRAME_BORDER_THICKNESS;
+ wxPoint pt = m_wnd->GetClientAreaOrigin();
+ pt.x = -pt.x + border;
+ pt.y = -pt.y + border + FRAME_TITLEBAR_HEIGHT;
+
+ wxAcceleratorTable table = *m_wnd->GetAcceleratorTable();
+ m_wnd->SetAcceleratorTable(wxNullAcceleratorTable);
+ m_inputHnd->PopupSystemMenu(m_wnd, pt);
+ m_wnd->SetAcceleratorTable(table);
+}
+
+void wxWin32SystemMenuEvtHandler::OnCloseFrame(wxCommandEvent &WXUNUSED(event))
+{
+ m_wnd->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
+ wxTOPLEVEL_BUTTON_CLOSE);
+}
+
+void wxWin32SystemMenuEvtHandler::OnClose(wxCloseEvent &event)
+{
+ m_wnd = NULL;
+ event.Skip();
+}
+
+
+wxWin32FrameInputHandler::wxWin32FrameInputHandler(wxInputHandler *handler)
+ : wxStdFrameInputHandler(handler)
+{
+ m_menuHandler = new wxWin32SystemMenuEvtHandler(this);
+}
+
+wxWin32FrameInputHandler::~wxWin32FrameInputHandler()
+{
+ if ( m_menuHandler )
+ {
+ m_menuHandler->Detach();
+ delete m_menuHandler;
+ }
+}
+
bool wxWin32FrameInputHandler::HandleMouse(wxInputConsumer *consumer,
const wxMouseEvent& event)
{
- if ( event.LeftDClick() )
+ if ( event.LeftDClick() || event.LeftDown() || event.RightDown() )
{
- wxTopLevelWindow *tlw =
+ wxTopLevelWindow *tlw =
wxStaticCast(consumer->GetInputWindow(), wxTopLevelWindow);
long hit = tlw->HitTest(event.GetPosition());
- if ( hit == wxHT_TOPLEVEL_TITLEBAR )
+ if ( event.LeftDClick() && hit == wxHT_TOPLEVEL_TITLEBAR )
{
- tlw->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
- tlw->IsMaximized() ?
- wxTOPLEVEL_BUTTON_RESTORE :
- wxTOPLEVEL_BUTTON_MAXIMIZE);
+ tlw->PerformAction(wxACTION_TOPLEVEL_BUTTON_CLICK,
+ tlw->IsMaximized() ? wxTOPLEVEL_BUTTON_RESTORE
+ : wxTOPLEVEL_BUTTON_MAXIMIZE);
return TRUE;
}
+ else if ( tlw->GetWindowStyle() & wxSYSTEM_MENU )
+ {
+ if ( (event.LeftDown() && hit == wxHT_TOPLEVEL_ICON) ||
+ (event.RightDown() &&
+ (hit == wxHT_TOPLEVEL_TITLEBAR ||
+ hit == wxHT_TOPLEVEL_ICON)) )
+ {
+ PopupSystemMenu(tlw, event.GetPosition());
+ return TRUE;
+ }
+ }
}
return wxStdFrameInputHandler::HandleMouse(consumer, event);
}
+void wxWin32FrameInputHandler::PopupSystemMenu(wxTopLevelWindow *window,
+ const wxPoint& pos) const
+{
+ wxMenu *menu = new wxMenu;
+
+ if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
+ menu->Append(wxID_RESTORE_FRAME , _("&Restore"));
+ menu->Append(wxID_MOVE_FRAME , _("&Move"));
+ if ( window->GetWindowStyle() & wxRESIZE_BORDER )
+ menu->Append(wxID_RESIZE_FRAME , _("&Size"));
+ if ( wxSystemSettings::HasFeature(wxSYS_CAN_ICONIZE_FRAME) )
+ menu->Append(wxID_ICONIZE_FRAME , _("Mi&nimize"));
+ if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
+ menu->Append(wxID_MAXIMIZE_FRAME , _("Ma&ximize"));
+ menu->AppendSeparator();
+ menu->Append(wxID_CLOSE_FRAME, _("Close\tAlt-F4"));
+
+ if ( window->GetWindowStyle() & wxMAXIMIZE_BOX )
+ {
+ if ( window->IsMaximized() )
+ {
+ menu->Enable(wxID_MAXIMIZE_FRAME, FALSE);
+ menu->Enable(wxID_MOVE_FRAME, FALSE);
+ if ( window->GetWindowStyle() & wxRESIZE_BORDER )
+ menu->Enable(wxID_RESIZE_FRAME, FALSE);
+ }
+ else
+ menu->Enable(wxID_RESTORE_FRAME, FALSE);
+ }
+
+ window->PopupMenu(menu, pos);
+ delete menu;
+}
+
+bool wxWin32FrameInputHandler::HandleActivation(wxInputConsumer *consumer,
+ bool activated)
+{
+ if ( consumer->GetInputWindow()->GetWindowStyle() & wxSYSTEM_MENU )
+ {
+ // always detach if active frame changed:
+ m_menuHandler->Detach();
+
+ if ( activated )
+ {
+ m_menuHandler->Attach(consumer);
+ }
+ }
+
+ return wxStdFrameInputHandler::HandleActivation(consumer, activated);
+}