#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,
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 wxSize GetToolBarButtonSize(wxCoord *separator) const
{ if ( separator ) *separator = 5; return wxSize(16, 15); }
virtual wxSize GetToolBarMargin() const
- { return wxSize(6, 6); }
+ { return wxSize(4, 4); }
virtual wxRect GetTextTotalArea(const wxTextCtrl *text,
const wxRect& rect) const;
// 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)
return m_renderer;
}
+wxArtProvider *wxWin32Theme::GetArtProvider()
+{
+ if ( !m_artProvider )
+ {
+ m_artProvider = new wxWin32ArtProvider;
+ }
+
+ return m_artProvider;
+}
+
wxInputHandler *wxWin32Theme::GetDefaultInputHandler()
{
if ( !m_handlerDefault )
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));
break;
default:
+ {
+ // char *crash = NULL;
+ // *crash = 0;
wxFAIL_MSG(_T("unknown border type"));
// fall through
+ }
case wxBORDER_DEFAULT:
case wxBORDER_NONE:
}
else // a separator
{
- // TODO
+ // 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);
}
}
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 );
}
// ----------------------------------------------------------------------------
"....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;
}
// 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
// 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 =
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);
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);
+}