toolbar.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 890 行 · 第 1/2 页
CPP
890 行
// calculate the positions of all elements
for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
node;
node = node->GetNext() )
{
wxToolBarTool *tool = (wxToolBarTool *) node->GetData();
tool->m_x = x;
tool->m_y = y;
// TODO ugly number fiddling
if (tool->IsButton())
{
*pCur += widthTool;
}
else if (tool->IsSeparator())
{
*pCur += m_widthSeparator;
}
else if (!IsVertical()) // horizontal control
{
wxControl *control = tool->GetControl();
wxSize size = control->GetSize();
tool->m_y += (m_defaultHeight - size.y)/2;
tool->m_width = size.x;
tool->m_height = size.y;
*pCur += tool->m_width;
}
*pCur += margin;
}
// calculate the total toolbar size
wxCoord xMin = m_defaultWidth + 2*m_xMargin,
yMin = m_defaultHeight + 2*m_yMargin;
m_maxWidth = x < xMin ? xMin : x;
m_maxHeight = y < yMin ? yMin : y;
}
wxSize wxToolBar::DoGetBestClientSize() const
{
return wxSize(m_maxWidth, m_maxHeight);
}
void wxToolBar::DoSetSize(int x, int y, int width, int height, int sizeFlags)
{
int old_width, old_height;
GetSize(&old_width, &old_height);
wxToolBarBase::DoSetSize(x, y, width, height, sizeFlags);
// Correct width and height if needed.
if ( width == wxDefaultCoord || height == wxDefaultCoord )
{
int tmp_width, tmp_height;
GetSize(&tmp_width, &tmp_height);
if ( width == wxDefaultCoord )
width = tmp_width;
if ( height == wxDefaultCoord )
height = tmp_height;
}
// We must refresh the frame size when the toolbar changes size
// otherwise the toolbar can be shown incorrectly
if ( old_width != width || old_height != height )
{
// But before we send the size event check it
// we have a frame that is not being deleted.
wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
if ( frame && !frame->IsBeingDeleted() )
{
frame->SendSizeEvent();
}
}
}
// ----------------------------------------------------------------------------
// wxToolBar drawing
// ----------------------------------------------------------------------------
void wxToolBar::RefreshTool(wxToolBarToolBase *tool)
{
RefreshRect(GetToolRect(tool));
}
void wxToolBar::GetRectLimits(const wxRect& rect,
wxCoord *start,
wxCoord *end) const
{
wxCHECK_RET( start && end, _T("NULL pointer in GetRectLimits") );
if ( IsVertical() )
{
*start = rect.GetTop();
*end = rect.GetBottom();
}
else // horizontal
{
*start = rect.GetLeft();
*end = rect.GetRight();
}
}
void wxToolBar::DoDraw(wxControlRenderer *renderer)
{
// prepare the variables used below
wxDC& dc = renderer->GetDC();
wxRenderer *rend = renderer->GetRenderer();
// dc.SetFont(GetFont()); -- uncomment when we support labels
// draw the border separating us from the menubar (if there is no menubar
// we probably shouldn't draw it?)
if ( !IsVertical() )
{
rend->DrawHorizontalLine(dc, 0, 0, GetClientSize().x);
}
// get the update rect and its limits depending on the orientation
wxRect rectUpdate = GetUpdateClientRect();
wxCoord start, end;
GetRectLimits(rectUpdate, &start, &end);
// and redraw all the tools intersecting it
for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
node;
node = node->GetNext() )
{
wxToolBarTool *tool = (wxToolBarTool*) node->GetData();
wxRect rectTool = GetToolRect(tool);
wxCoord startTool, endTool;
GetRectLimits(rectTool, &startTool, &endTool);
if ( endTool < start )
{
// we're still to the left of the area to redraw
continue;
}
if ( startTool > end )
{
// we're beyond the area to redraw, nothing left to do
break;
}
if (tool->IsSeparator() && !HasFlag(wxTB_FLAT))
{
// Draw separators only in flat mode
continue;
}
// deal with the flags
int flags = 0;
if ( tool->IsEnabled() )
{
// The toolbars without wxTB_FLAT don't react to the mouse hovering
if ( !HasFlag(wxTB_FLAT) || tool->IsUnderMouse() )
flags |= wxCONTROL_CURRENT;
}
else // disabled tool
{
flags |= wxCONTROL_DISABLED;
}
//if ( tool == m_toolCaptured )
// flags |= wxCONTROL_FOCUSED;
if ( tool->IsPressed() )
flags = wxCONTROL_PRESSED;
wxString label;
wxBitmap bitmap;
if ( !tool->IsSeparator() )
{
// label = tool->GetLabel();
bitmap = tool->GetBitmap();
}
//else: leave both the label and the bitmap invalid to draw a separator
if ( !tool->IsControl() )
{
rend->DrawToolBarButton(dc, label, bitmap, rectTool, flags, tool->GetStyle());
}
else // control
{
wxControl *control = tool->GetControl();
control->Move(tool->m_x, tool->m_y);
}
}
}
// ----------------------------------------------------------------------------
// wxToolBar actions
// ----------------------------------------------------------------------------
bool wxToolBar::PerformAction(const wxControlAction& action,
long numArg,
const wxString& strArg)
{
wxToolBarTool *tool = (wxToolBarTool*) FindById(numArg);
if (!tool)
return false;
if ( action == wxACTION_TOOLBAR_TOGGLE )
{
PerformAction( wxACTION_BUTTON_RELEASE, numArg );
PerformAction( wxACTION_BUTTON_CLICK, numArg );
// Write by Danny Raynor to change state again.
// Check button still pressed or not
if( tool->IsInverted() )
{
PerformAction( wxACTION_TOOLBAR_RELEASE, numArg );
}
// Set mouse leave toolbar button range (If still in the range,
// toolbar button would get focus again
PerformAction( wxACTION_TOOLBAR_LEAVE, numArg );
}
else if ( action == wxACTION_TOOLBAR_PRESS )
{
wxLogTrace(_T("toolbar"), _T("Button '%s' pressed."), tool->GetShortHelp().c_str());
tool->Invert();
RefreshTool( tool );
}
else if ( action == wxACTION_TOOLBAR_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 )
{
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 )
{
wxCHECK_MSG( tool, false, _T("no tool to enter?") );
if ( HasFlag(wxTB_FLAT) && tool->IsEnabled() )
{
tool->SetUnderMouse( true );
if ( !tool->IsToggled() )
RefreshTool( tool );
}
}
else if ( action == wxACTION_TOOLBAR_LEAVE )
{
wxCHECK_MSG( tool, false, _T("no tool to leave?") );
if ( HasFlag(wxTB_FLAT) && tool->IsEnabled() )
{
tool->SetUnderMouse( false );
if ( !tool->IsToggled() )
RefreshTool( tool );
}
}
else
return wxControl::PerformAction(action, numArg, strArg);
return true;
}
// ============================================================================
// wxStdToolbarInputHandler implementation
// ============================================================================
wxStdToolbarInputHandler::wxStdToolbarInputHandler(wxInputHandler *handler)
: wxStdInputHandler(handler)
{
m_winCapture = NULL;
m_toolCapture = NULL;
m_toolLast = NULL;
}
bool wxStdToolbarInputHandler::HandleKey(wxInputConsumer *consumer,
const wxKeyEvent& event,
bool pressed)
{
// TODO: when we have a current button we should allow the arrow
// keys to move it
return wxStdInputHandler::HandleKey(consumer, event, pressed);
}
bool wxStdToolbarInputHandler::HandleMouse(wxInputConsumer *consumer,
const wxMouseEvent& event)
{
wxToolBar *tbar = wxStaticCast(consumer->GetInputWindow(), wxToolBar);
wxToolBarToolBase *tool = tbar->FindToolForPosition(event.GetX(), event.GetY());
if ( event.Button(1) )
{
if ( event.LeftDown() || event.LeftDClick() )
{
if ( !tool || !tool->IsEnabled() )
return true;
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 (m_toolCapture)
{
if ( tool == m_toolCapture )
consumer->PerformAction( wxACTION_BUTTON_TOGGLE, m_toolCapture->GetId() );
else
consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolCapture->GetId() );
}
m_toolCapture = NULL;
return true;
}
//else: don't do anything special about the double click
}
return wxStdInputHandler::HandleMouse(consumer, event);
}
bool wxStdToolbarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
const wxMouseEvent& event)
{
if ( !wxStdInputHandler::HandleMouseMove(consumer, event) )
{
wxToolBar *tbar = wxStaticCast(consumer->GetInputWindow(), wxToolBar);
wxToolBarTool *tool;
if ( event.Leaving() )
{
// We cannot possibly be over a tool when
// leaving the toolbar
tool = NULL;
}
else
{
tool = (wxToolBarTool*) tbar->FindToolForPosition( event.GetX(), event.GetY() );
}
if (m_toolCapture)
{
// During capture we only care of the captured tool
if (tool && (tool != m_toolCapture))
tool = NULL;
if (tool == m_toolLast)
return true;
if (tool)
consumer->PerformAction( wxACTION_BUTTON_PRESS, m_toolCapture->GetId() );
else
consumer->PerformAction( wxACTION_BUTTON_RELEASE, m_toolCapture->GetId() );
m_toolLast = tool;
}
else
{
if (tool == m_toolLast)
return true;
if (m_toolLast)
{
// Leave old tool if any
consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolLast->GetId() );
}
if (tool)
{
// Enter new tool if any
consumer->PerformAction( wxACTION_TOOLBAR_ENTER, tool->GetId() );
}
m_toolLast = tool;
}
return true;
}
return false;
}
bool wxStdToolbarInputHandler::HandleFocus(wxInputConsumer *consumer,
const wxFocusEvent& WXUNUSED(event))
{
if ( m_toolCapture )
{
// We shouldn't be left with a highlighted button
consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolCapture->GetId() );
}
return true;
}
bool wxStdToolbarInputHandler::HandleActivation(wxInputConsumer *consumer,
bool activated)
{
if (m_toolCapture && !activated)
{
// We shouldn't be left with a highlighted button
consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolCapture->GetId() );
}
return true;
}
#endif // wxUSE_TOOLBAR
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?