Rewrote wxToolBar another time.

Other minor tweaks.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14874 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2002-03-30 21:18:39 +00:00
parent f4fefc232b
commit 34d26f42b1
6 changed files with 186 additions and 149 deletions

View File

@@ -67,6 +67,10 @@ public:
virtual void SetToolShortHelp(int id, const wxString& helpString); virtual void SetToolShortHelp(int id, const wxString& helpString);
virtual void SetMargins(int x, int y);
void SetMargins(const wxSize& size)
{ SetMargins((int) size.x, (int) size.y); }
protected: protected:
// common part of all ctors // common part of all ctors
void Init(); void Init();
@@ -110,15 +114,6 @@ protected:
// vertical toolbar, left/right for a horizontal one // vertical toolbar, left/right for a horizontal one
void GetRectLimits(const wxRect& rect, wxCoord *start, wxCoord *end) const; void GetRectLimits(const wxRect& rect, wxCoord *start, wxCoord *end) const;
// wxButton actions: all these use m_toolPressed and can only be called if
// we have one
void Toggle();
void Press();
void Release();
// this one used m_toolCurrent
void Click();
private: private:
// have we calculated the positions of our tools? // have we calculated the positions of our tools?
bool m_needsLayout; bool m_needsLayout;
@@ -129,14 +124,8 @@ private:
// the total size of all toolbar elements // the total size of all toolbar elements
wxCoord m_maxWidth, wxCoord m_maxWidth,
m_maxHeight; m_maxHeight;
// the tool over which the mouse currently is or NULL
wxToolBarToolBase *m_toolCurrent;
// the tool which currently has the mouse capture (i.e. the one user is
// pressing) or NULL
wxToolBarTool *m_toolPressed;
private:
DECLARE_DYNAMIC_CLASS(wxToolBar) DECLARE_DYNAMIC_CLASS(wxToolBar)
}; };
@@ -145,7 +134,7 @@ private:
// click into button press/release actions // click into button press/release actions
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
class WXDLLEXPORT wxStdToolbarInputHandler : public wxStdButtonInputHandler class WXDLLEXPORT wxStdToolbarInputHandler : public wxStdInputHandler
{ {
public: public:
wxStdToolbarInputHandler(wxInputHandler *inphand); wxStdToolbarInputHandler(wxInputHandler *inphand);
@@ -158,6 +147,11 @@ public:
virtual bool HandleMouseMove(wxInputConsumer *consumer, const wxMouseEvent& event); virtual bool HandleMouseMove(wxInputConsumer *consumer, const wxMouseEvent& event);
virtual bool HandleFocus(wxInputConsumer *consumer, const wxFocusEvent& event); virtual bool HandleFocus(wxInputConsumer *consumer, const wxFocusEvent& event);
virtual bool HandleActivation(wxInputConsumer *consumer, bool activated); virtual bool HandleActivation(wxInputConsumer *consumer, bool activated);
private:
wxWindow *m_winCapture;
wxToolBarToolBase *m_toolCapture;
wxToolBarToolBase *m_toolLast;
}; };
#endif // _WX_UNIV_TOOLBAR_H_ #endif // _WX_UNIV_TOOLBAR_H_

View File

@@ -152,7 +152,8 @@ private:
const int ID_TOOLBAR = 500; const int ID_TOOLBAR = 500;
static const long TOOLBAR_STYLE = wxTB_FLAT | wxTB_DOCKABLE | wxTB_TEXT; static const long TOOLBAR_STYLE = wxTB_FLAT | wxTB_DOCKABLE | wxTB_TEXT ;
// static const long TOOLBAR_STYLE = 0;
enum enum
{ {

View File

@@ -236,9 +236,9 @@ void wxButton::SetImageLabel(const wxBitmap& bitmap)
void wxButton::SetImageMargins(wxCoord x, wxCoord y) void wxButton::SetImageMargins(wxCoord x, wxCoord y)
{ {
m_marginBmpX = x; m_marginBmpX = x + 2;
m_marginBmpY = y; m_marginBmpY = y + 2;
SetBestSize(wxDefaultSize); SetBestSize(wxDefaultSize);
} }

View File

@@ -428,6 +428,10 @@ void wxControlRenderer::DrawLabel(const wxBitmap& bitmap,
if ( bitmap.Ok() ) if ( bitmap.Ok() )
{ {
rectLabel.Inflate(-marginX, -marginY); rectLabel.Inflate(-marginX, -marginY);
// I don't know why this is necessary. RR.
rectLabel.x ++;
rectLabel.y ++;
} }
wxControl *ctrl = wxStaticCast(m_window, wxControl); wxControl *ctrl = wxStaticCast(m_window, wxControl);

View File

@@ -354,7 +354,7 @@ public:
virtual wxSize GetToolBarButtonSize(wxCoord *separator) const virtual wxSize GetToolBarButtonSize(wxCoord *separator) const
{ if ( separator ) *separator = 5; return wxSize(16, 15); } { if ( separator ) *separator = 5; return wxSize(16, 15); }
virtual wxSize GetToolBarMargin() const virtual wxSize GetToolBarMargin() const
{ return wxSize(6, 6); } { return wxSize(4, 4); }
virtual wxRect GetTextTotalArea(const wxTextCtrl *text, virtual wxRect GetTextTotalArea(const wxTextCtrl *text,
const wxRect& rect) const; const wxRect& rect) const;

View File

@@ -73,6 +73,9 @@ public:
// not pressed yet // not pressed yet
m_isInverted = FALSE; m_isInverted = FALSE;
// mouse not here yet
m_underMouse = FALSE;
} }
// is this tool pressed, even temporarily? (this is different from being // is this tool pressed, even temporarily? (this is different from being
@@ -85,6 +88,10 @@ public:
// press the tool temporarily by inverting its toggle state // press the tool temporarily by inverting its toggle state
void Invert() { m_isInverted = !m_isInverted; } void Invert() { m_isInverted = !m_isInverted; }
// Set underMouse
void SetUnderMouse( bool under = TRUE ) { m_underMouse = under; }
bool IsUnderMouse() { return m_underMouse; }
public: public:
// the tool position (the size is known by the toolbar itself) // the tool position (the size is known by the toolbar itself)
@@ -94,6 +101,9 @@ public:
private: private:
// TRUE if the tool is pressed // TRUE if the tool is pressed
bool m_isInverted; bool m_isInverted;
// TRUE if the tool is under the mouse
bool m_underMouse;
}; };
// ============================================================================ // ============================================================================
@@ -117,9 +127,6 @@ void wxToolBar::Init()
m_maxWidth = m_maxWidth =
m_maxHeight = 0; m_maxHeight = 0;
m_toolPressed = NULL;
m_toolCurrent = NULL;
wxRenderer *renderer = GetRenderer(); wxRenderer *renderer = GetRenderer();
SetToolBitmapSize(renderer->GetToolBarButtonSize(&m_widthSeparator)); SetToolBitmapSize(renderer->GetToolBarButtonSize(&m_widthSeparator));
@@ -150,6 +157,13 @@ wxToolBar::~wxToolBar()
{ {
} }
void wxToolBar::SetMargins(int x, int y)
{
// This required for similar visual effects under
// native platforms and wxUniv.
wxToolBarBase::SetMargins( x + 2, y + 2 );
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxToolBar tool-related methods // wxToolBar tool-related methods
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -458,7 +472,7 @@ void wxToolBar::DoDraw(wxControlRenderer *renderer)
node; node;
node = node->GetNext() ) node = node->GetNext() )
{ {
wxToolBarToolBase *tool = node->GetData(); wxToolBarTool *tool = (wxToolBarTool*) node->GetData();
wxRect rectTool = GetToolRect(tool); wxRect rectTool = GetToolRect(tool);
wxCoord startTool, endTool; wxCoord startTool, endTool;
GetRectLimits(rectTool, &startTool, &endTool); GetRectLimits(rectTool, &startTool, &endTool);
@@ -474,14 +488,14 @@ void wxToolBar::DoDraw(wxControlRenderer *renderer)
// we're beyond the area to redraw, nothing left to do // we're beyond the area to redraw, nothing left to do
break; break;
} }
// deal with the flags // deal with the flags
int flags = 0; int flags = 0;
if ( tool->IsEnabled() ) if ( tool->IsEnabled() )
{ {
// the toolbars without wxTB_FLAT don't react to the mouse hovering // The toolbars without wxTB_FLAT don't react to the mouse hovering
if ( HasFlag(wxTB_FLAT) && (tool == m_toolCurrent) ) if ( !HasFlag(wxTB_FLAT) || tool->IsUnderMouse() )
flags |= wxCONTROL_CURRENT; flags |= wxCONTROL_CURRENT;
} }
else // disabled tool else // disabled tool
@@ -489,17 +503,17 @@ void wxToolBar::DoDraw(wxControlRenderer *renderer)
flags |= wxCONTROL_DISABLED; flags |= wxCONTROL_DISABLED;
} }
if ( tool == m_toolPressed ) //if ( tool == m_toolCaptured )
flags |= wxCONTROL_FOCUSED; // flags |= wxCONTROL_FOCUSED;
if ( ((wxToolBarTool *)tool)->IsPressed() ) if ( tool->IsPressed() )
flags |= wxCONTROL_PRESSED; flags = wxCONTROL_PRESSED;
wxString label; wxString label;
wxBitmap bitmap; wxBitmap bitmap;
if ( !tool->IsSeparator() ) if ( !tool->IsSeparator() )
{ {
label = tool->GetLabel(); // label = tool->GetLabel();
bitmap = tool->GetBitmap(); bitmap = tool->GetBitmap();
} }
//else: leave both the label and the bitmap invalid to draw a separator //else: leave both the label and the bitmap invalid to draw a separator
@@ -512,116 +526,75 @@ void wxToolBar::DoDraw(wxControlRenderer *renderer)
// wxToolBar actions // wxToolBar actions
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void wxToolBar::Press()
{
wxCHECK_RET( m_toolCurrent, _T("no tool to press?") );
wxLogTrace(_T("toolbar"),
_T("Button '%s' pressed."),
m_toolCurrent->GetShortHelp().c_str());
// this is the tool whose state is going to change
m_toolPressed = (wxToolBarTool *)m_toolCurrent;
// we must toggle it regardless of whether it is a checkable tool or not,
// so use Invert() and not Toggle() here
m_toolPressed->Invert();
RefreshTool(m_toolPressed);
}
void wxToolBar::Release()
{
wxCHECK_RET( m_toolPressed, _T("no tool to release?") );
wxLogTrace(_T("toolbar"),
_T("Button '%s' released."),
m_toolCurrent->GetShortHelp().c_str());
wxASSERT_MSG( m_toolPressed->IsInverted(), _T("release unpressed button?") );
m_toolPressed->Invert();
RefreshTool(m_toolPressed);
}
void wxToolBar::Toggle()
{
m_toolCurrent = m_toolPressed;
Release();
Click();
}
void wxToolBar::Click()
{
wxCHECK_RET( m_toolCurrent, _T("no tool to click?") );
bool isToggled;
if ( m_toolCurrent->CanBeToggled() )
{
m_toolCurrent->Toggle();
RefreshTool(m_toolCurrent);
isToggled = m_toolCurrent->IsToggled();
}
else // simple non-checkable tool
{
isToggled = FALSE;
}
OnLeftClick(m_toolCurrent->GetId(), isToggled);
}
bool wxToolBar::PerformAction(const wxControlAction& action, bool wxToolBar::PerformAction(const wxControlAction& action,
long numArg, long numArg,
const wxString& strArg) const wxString& strArg)
{ {
wxToolBarTool *tool = (wxToolBarTool*) FindById(numArg);
if ( action == wxACTION_TOOLBAR_TOGGLE ) if ( action == wxACTION_TOOLBAR_TOGGLE )
Toggle(); {
PerformAction( wxACTION_BUTTON_RELEASE, numArg );
PerformAction( wxACTION_BUTTON_CLICK, numArg );
}
else if ( action == wxACTION_TOOLBAR_PRESS ) else if ( action == wxACTION_TOOLBAR_PRESS )
Press(); {
wxLogTrace(_T("toolbar"), _T("Button '%s' pressed."), tool->GetShortHelp().c_str());
tool->Invert();
RefreshTool( tool );
}
else if ( action == wxACTION_TOOLBAR_RELEASE ) else if ( action == wxACTION_TOOLBAR_RELEASE )
Release(); {
wxLogTrace(_T("toolbar"), _T("Button '%s' released."), tool->GetShortHelp().c_str());
wxASSERT_MSG( tool->IsInverted(), _T("release unpressed button?") );
tool->Invert();
RefreshTool( tool );
}
else if ( action == wxACTION_TOOLBAR_CLICK ) else if ( action == wxACTION_TOOLBAR_CLICK )
Click(); {
bool isToggled;
if ( tool->CanBeToggled() )
{
tool->Toggle();
RefreshTool( tool );
isToggled = tool->IsToggled();
}
else // simple non-checkable tool
{
isToggled = FALSE;
}
OnLeftClick( tool->GetId(), isToggled );
}
else if ( action == wxACTION_TOOLBAR_ENTER ) else if ( action == wxACTION_TOOLBAR_ENTER )
{ {
wxToolBarToolBase *toolCurrentOld = m_toolCurrent; wxCHECK_MSG( tool, FALSE, _T("no tool to enter?") );
m_toolCurrent = FindById((int)numArg);
if ( HasFlag(wxTB_FLAT) && tool->IsEnabled() )
if ( m_toolCurrent != toolCurrentOld )
{ {
// the appearance of the current tool only changes for the flat tool->SetUnderMouse( TRUE );
// toolbars
if ( HasFlag(wxTB_FLAT) ) if ( !tool->IsToggled() )
{ RefreshTool( tool );
// and only if the tool was/is enabled
if ( toolCurrentOld && toolCurrentOld->IsEnabled() )
RefreshTool(toolCurrentOld);
if ( m_toolCurrent )
{
if ( m_toolCurrent->IsEnabled() )
RefreshTool(m_toolCurrent);
}
else
{
wxFAIL_MSG( _T("no current tool in wxACTION_TOOLBAR_ENTER?") );
}
}
} }
} }
else if ( action == wxACTION_TOOLBAR_LEAVE ) else if ( action == wxACTION_TOOLBAR_LEAVE )
{ {
if ( m_toolCurrent ) wxCHECK_MSG( tool, FALSE, _T("no tool to leave?") );
if ( HasFlag(wxTB_FLAT) && tool->IsEnabled() )
{ {
wxToolBarToolBase *toolCurrentOld = m_toolCurrent; tool->SetUnderMouse( FALSE );
m_toolCurrent = NULL;
if ( !tool->IsToggled() )
RefreshTool(toolCurrentOld); RefreshTool( tool );
} }
} }
else else
@@ -635,8 +608,11 @@ bool wxToolBar::PerformAction(const wxControlAction& action,
// ============================================================================ // ============================================================================
wxStdToolbarInputHandler::wxStdToolbarInputHandler(wxInputHandler *handler) wxStdToolbarInputHandler::wxStdToolbarInputHandler(wxInputHandler *handler)
: wxStdButtonInputHandler(handler) : wxStdInputHandler(handler)
{ {
m_winCapture = NULL;
m_toolCapture = NULL;
m_toolLast = NULL;
} }
bool wxStdToolbarInputHandler::HandleKey(wxInputConsumer *consumer, bool wxStdToolbarInputHandler::HandleKey(wxInputConsumer *consumer,
@@ -651,39 +627,96 @@ bool wxStdToolbarInputHandler::HandleKey(wxInputConsumer *consumer,
bool wxStdToolbarInputHandler::HandleMouse(wxInputConsumer *consumer, bool wxStdToolbarInputHandler::HandleMouse(wxInputConsumer *consumer,
const wxMouseEvent& event) const wxMouseEvent& event)
{ {
// don't let the base class press the disabled buttons but simply ignore
// all events on them
wxToolBar *tbar = wxStaticCast(consumer->GetInputWindow(), wxToolBar); wxToolBar *tbar = wxStaticCast(consumer->GetInputWindow(), wxToolBar);
wxToolBarToolBase *tool = tbar->FindToolForPosition(event.GetX(), event.GetY()); wxToolBarToolBase *tool = tbar->FindToolForPosition(event.GetX(), event.GetY());
if ( !tool || !tool->IsEnabled() ) if ( event.Button(1) )
return TRUE; {
if ( !tool || !tool->IsEnabled() )
return TRUE;
return wxStdButtonInputHandler::HandleMouse(consumer, event); if ( event.LeftDown() || event.LeftDClick() )
{
m_winCapture = tbar;
m_winCapture->CaptureMouse();
m_toolCapture = tool;
consumer->PerformAction( wxACTION_BUTTON_PRESS, tool->GetId() );
return TRUE;
}
else if ( event.LeftUp() )
{
if ( m_winCapture )
{
m_winCapture->ReleaseMouse();
m_winCapture = NULL;
}
if ( tool == m_toolCapture )
{
// this will generate a click event
consumer->PerformAction( wxACTION_BUTTON_TOGGLE, tool->GetId() );
m_toolCapture = NULL;
return TRUE;
}
//else: the mouse was released outside the tool or in
// a different tool
m_toolCapture = NULL;
}
//else: don't do anything special about the double click
}
return wxStdInputHandler::HandleMouse(consumer, event);
} }
bool wxStdToolbarInputHandler::HandleMouseMove(wxInputConsumer *consumer, bool wxStdToolbarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
const wxMouseEvent& event) const wxMouseEvent& event)
{ {
if ( !wxStdButtonInputHandler::HandleMouseMove(consumer, event) ) if ( !wxStdInputHandler::HandleMouseMove(consumer, event) )
{ {
wxToolBarToolBase *tool; wxToolBar *tbar = wxStaticCast(consumer->GetInputWindow(), wxToolBar);
wxToolBarTool *tool;
if ( event.Leaving() ) if ( event.Leaving() )
{ {
// We cannot possibly be over a tool when
// leaving the toolbar
tool = NULL; tool = NULL;
} }
else else
{ {
wxToolBar *tbar = wxStaticCast(consumer->GetInputWindow(), wxToolBar); tool = (wxToolBarTool*) tbar->FindToolForPosition( event.GetX(), event.GetY() );
tool = tbar->FindToolForPosition(event.GetX(), event.GetY());
} }
if ( tool ) if ((tool) && (tool == m_toolLast))
consumer->PerformAction(wxACTION_TOOLBAR_ENTER, tool->GetId()); {
// Still over the same tool as last time
return TRUE;
}
if (m_toolLast)
{
// Leave old tool if any
consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolLast->GetId() );
}
if (m_toolCapture && (m_toolCapture != tool))
m_toolLast = NULL;
else else
consumer->PerformAction(wxACTION_TOOLBAR_LEAVE); m_toolLast = tool;
if (m_toolLast)
{
// Enter new tool if any
consumer->PerformAction( wxACTION_TOOLBAR_ENTER, m_toolLast->GetId() );
}
return TRUE; return TRUE;
} }
@@ -693,8 +726,11 @@ bool wxStdToolbarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
bool wxStdToolbarInputHandler::HandleFocus(wxInputConsumer *consumer, bool wxStdToolbarInputHandler::HandleFocus(wxInputConsumer *consumer,
const wxFocusEvent& event) const wxFocusEvent& event)
{ {
// we shouldn't be left with a highlighted button if (m_toolCapture)
consumer->PerformAction(wxACTION_TOOLBAR_LEAVE); {
// We shouldn't be left with a highlighted button
consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolCapture->GetId() );
}
return TRUE; return TRUE;
} }
@@ -702,9 +738,11 @@ bool wxStdToolbarInputHandler::HandleFocus(wxInputConsumer *consumer,
bool wxStdToolbarInputHandler::HandleActivation(wxInputConsumer *consumer, bool wxStdToolbarInputHandler::HandleActivation(wxInputConsumer *consumer,
bool activated) bool activated)
{ {
// as above if (m_toolCapture && !activated)
if ( !activated ) {
consumer->PerformAction(wxACTION_TOOLBAR_LEAVE); // We shouldn't be left with a highlighted button
consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolCapture->GetId() );
}
return TRUE; return TRUE;
} }