📄 dynamicsash.cpp
字号:
m_container->SetCursor(cursor);
m_dragging = DSR_NONE;
}
else if (m_leaf)
{
m_leaf->OnRelease(event);
}
}
// ============================================================================
// wxDynamicSashWindowLeaf
// ============================================================================
wxDynamicSashWindowLeaf::wxDynamicSashWindowLeaf(wxDynamicSashWindowImpl *impl)
{
m_impl = impl;
m_hscroll =
m_vscroll = NULL;
m_child = NULL;
}
wxDynamicSashWindowLeaf::~wxDynamicSashWindowLeaf()
{
m_hscroll->SetEventHandler(m_hscroll);
m_vscroll->SetEventHandler(m_vscroll);
m_hscroll->Destroy();
m_vscroll->Destroy();
m_viewport->Destroy();
}
bool wxDynamicSashWindowLeaf::Create()
{
m_hscroll = new wxScrollBar();
m_vscroll = new wxScrollBar();
m_viewport = new wxWindow();
wxDynamicSashWindowImpl *add_child_target = m_impl->m_add_child_target;
m_impl->m_add_child_target = NULL;
bool success = m_hscroll->Create(m_impl->m_container, wxID_ANY,
wxDefaultPosition, wxDefaultSize,
wxSB_HORIZONTAL);
if ( success )
success = m_vscroll->Create(m_impl->m_container, wxID_ANY,
wxDefaultPosition, wxDefaultSize,
wxSB_VERTICAL);
if ( success )
success = m_viewport->Create(m_impl->m_container, wxID_ANY);
if ( !success )
return false;
m_impl->m_add_child_target = add_child_target;
wxCursor cursor(wxCURSOR_ARROW);
m_hscroll->SetCursor(cursor);
m_vscroll->SetCursor(cursor);
m_viewport->SetCursor(cursor);
// the viewport must resize its child when it is itself resized, but it's
// more convenient to do it in our own method instead of deriving a new
// class just for this: this is why we pass this as last Connect() argument
m_viewport->Connect(wxEVT_SIZE,
wxSizeEventHandler(wxDynamicSashWindowLeaf::OnViewSize),
NULL, this);
Connect(wxEVT_DYNAMIC_SASH_REPARENT,
wxEventHandler(wxDynamicSashWindowLeaf::OnReparent));
if (m_impl->m_window->GetWindowStyle() & wxDS_MANAGE_SCROLLBARS)
{
m_hscroll->SetEventHandler(this);
m_vscroll->SetEventHandler(this);
Connect(wxEVT_SET_FOCUS,
wxFocusEventHandler(wxDynamicSashWindowLeaf::OnFocus));
Connect(wxEVT_SCROLL_TOP,
wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
Connect(wxEVT_SCROLL_BOTTOM,
wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
Connect(wxEVT_SCROLL_LINEUP,
wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
Connect(wxEVT_SCROLL_LINEDOWN,
wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
Connect(wxEVT_SCROLL_PAGEUP,
wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
Connect(wxEVT_SCROLL_PAGEDOWN,
wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
Connect(wxEVT_SCROLL_THUMBTRACK,
wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
Connect(wxEVT_SCROLL_THUMBRELEASE,
wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
}
wxLayoutConstraints *layout = new wxLayoutConstraints();
if (!layout)
return false;
wxSize size = m_hscroll->GetBestSize();
layout->left.SameAs(m_impl->m_container, wxLeft, 10);
layout->right.LeftOf(m_vscroll);
layout->bottom.SameAs(m_impl->m_container, wxBottom, 3);
layout->height.Absolute(size.GetHeight());
m_hscroll->SetConstraints(layout);
layout = new wxLayoutConstraints();
if (!layout)
return false;
size = m_vscroll->GetBestSize();
layout->top.SameAs(m_impl->m_container, wxTop, 10);
layout->bottom.Above(m_hscroll);
layout->right.SameAs(m_impl->m_container, wxRight, 3);
layout->width.Absolute(size.GetWidth());
m_vscroll->SetConstraints(layout);
layout = new wxLayoutConstraints();
if (!layout)
return false;
layout->left.SameAs(m_impl->m_container, wxLeft, 3);
layout->right.LeftOf(m_vscroll);
layout->top.SameAs(m_impl->m_container, wxTop, 3);
layout->bottom.Above(m_hscroll);
m_viewport->SetConstraints(layout);
m_impl->m_container->Layout();
return true;
}
void wxDynamicSashWindowLeaf::AddChild(wxWindow *window)
{
if (m_child)
m_child->Destroy();
m_child = window;
wxDynamicSashReparentEvent event(this);
AddPendingEvent(event);
}
DynamicSashRegion wxDynamicSashWindowLeaf::GetRegion(int x, int y)
{
wxSize size = m_impl->m_container->GetSize();
int w = size.GetWidth();
int h = size.GetHeight();
size = m_hscroll->GetSize();
int sh = size.GetHeight();
size = m_vscroll->GetSize();
int sw = size.GetWidth();
if (x >= w - sw - 3 && x < w && y >= h - sh - 3 && y < h)
return DSR_CORNER;
if (x >= 3 && x < 10 && y >= h - sh - 3 && y < h - 2)
return DSR_VERTICAL_TAB;
if (x >= w - sw - 3 && x < w - 2 && y >= 3 && y < 10)
return DSR_HORIZONTAL_TAB;
if (x < 3)
return DSR_LEFT_EDGE;
if (y < 3)
return DSR_TOP_EDGE;
if (x >= w - 2)
return DSR_RIGHT_EDGE;
if (y >= h - 2)
return DSR_BOTTOM_EDGE;
return DSR_NONE;
}
void wxDynamicSashWindowLeaf::ResizeChild(const wxSize& size)
{
if (m_child)
{
if (m_impl->m_window->HasFlag(wxDS_MANAGE_SCROLLBARS))
{
wxSize best_size = m_child->GetBestSize();
if (best_size.GetWidth() < size.GetWidth())
best_size.SetWidth(size.GetWidth());
if (best_size.GetHeight() < size.GetHeight())
best_size.SetHeight(size.GetHeight());
m_child->SetSize(best_size);
int hpos = m_hscroll->GetThumbPosition();
int vpos = m_vscroll->GetThumbPosition();
if (hpos < 0)
hpos = 0;
if (vpos < 0)
vpos = 0;
if (hpos > best_size.GetWidth() - size.GetWidth())
hpos = best_size.GetWidth() - size.GetWidth();
if (vpos > best_size.GetHeight() - size.GetHeight())
vpos = best_size.GetHeight() - size.GetHeight();
m_hscroll->SetScrollbar(hpos, size.GetWidth(),
best_size.GetWidth(), size.GetWidth());
m_vscroll->SetScrollbar(vpos, size.GetHeight(),
best_size.GetHeight(), size.GetHeight());
// Umm, the scrollbars are doing something insane under GTK+ and subtracting
// one from the position I pass in. This works around that.
m_hscroll->SetThumbPosition(hpos + hpos - m_hscroll->GetThumbPosition());
m_vscroll->SetThumbPosition(vpos + vpos - m_vscroll->GetThumbPosition());
wxPoint pos = m_child->GetPosition();
m_viewport->ScrollWindow(-hpos - pos.x, -vpos - pos.y);
}
else // !wxDS_MANAGE_SCROLLBARS
{
m_child->SetSize(size);
}
}
}
wxScrollBar *
wxDynamicSashWindowLeaf::FindScrollBar(const wxWindow *child, int vert) const
{
if (m_child == child)
{
return vert ? m_vscroll : m_hscroll;
}
return NULL;
}
void wxDynamicSashWindowLeaf::OnSize(wxSizeEvent &WXUNUSED(event))
{
m_impl->m_container->Refresh();
}
void wxDynamicSashWindowLeaf::OnViewSize(wxSizeEvent &WXUNUSED(event))
{
if ( m_viewport )
ResizeChild(m_viewport->GetSize());
}
void wxDynamicSashWindowLeaf::OnPaint(wxPaintEvent &WXUNUSED(event))
{
wxPaintDC dc(m_impl->m_container);
dc.SetBackground(wxBrush(m_impl->m_container->GetBackgroundColour(), wxSOLID));
dc.Clear();
wxPen highlight(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT), 1, wxSOLID);
wxPen shadow(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW), 1, wxSOLID);
wxPen black(*wxBLACK, 1, wxSOLID);
wxSize size = m_impl->m_container->GetSize();
int w = size.GetWidth();
int h = size.GetHeight();
size = m_hscroll->GetSize();
int sh = size.GetHeight();
size = m_vscroll->GetSize();
int sw = size.GetWidth();
dc.SetPen(shadow);
dc.DrawLine(1, 1, 1, h - 2);
dc.DrawLine(1, 1, w - 2, 1);
dc.SetPen(black);
dc.DrawLine(2, 2, 2, h - 3);
dc.DrawLine(2, 2, w - 3, 2);
dc.SetPen(highlight);
dc.DrawLine(w - 2, 2, w - 2, h - sh - 2);
dc.DrawLine(w - 2, h - sh - 2, w - sw - 2, h - sh - 2);
dc.DrawLine(w - sw - 2, h - sh - 2, w - sw - 2, h - 2);
dc.DrawLine(w - sw - 2, h - 2, 2, h - 2);
dc.SetPen(highlight);
dc.DrawLine(w - sw - 2, 8, w - sw - 2, 4);
dc.DrawLine(w - sw - 2, 4, w - 5, 4);
dc.SetPen(shadow);
dc.DrawLine(w - 5, 4, w - 5, 8);
dc.DrawLine(w - 5, 8, w - sw - 2, 8);
dc.SetPen(black);
dc.DrawLine(w - 4, 3, w - 4, 9);
dc.DrawLine(w - 4, 9, w - sw - 3, 9);
dc.SetPen(highlight);
dc.DrawLine(4, h - 5, 4, h - sh - 2);
dc.DrawLine(4, h - sh - 2, 8, h - sh - 2);
dc.SetPen(shadow);
dc.DrawLine(8, h - sh - 2, 8, h - 5);
dc.DrawLine(8, h - 5, 4, h - 5);
dc.SetPen(black);
dc.DrawLine(9, h - sh - 3, 9, h - 4);
dc.DrawLine(9, h - 4, 3, h - 4);
int cy = (h - sh + h - 6) / 2 + 1;
int cx = (w - sw + w - 6) / 2 + 1;
int sy = cy;
while (sy > h - sh)
sy -= 4;
int sx = cx;
while (sx > w - sw)
sx -= 4;
int x, y;
for (y = sy; y < h - 2; y += 4)
{
for (x = sx; x < w - 2; x += 4)
{
if (x - cx >= -(y - cy))
{
dc.SetPen(highlight);
dc.DrawPoint(x, y);
dc.SetPen(shadow);
dc.DrawPoint(x + 1, y + 1);
}
}
}
}
void wxDynamicSashWindowLeaf::OnScroll(wxScrollEvent &WXUNUSED(event))
{
int nx = -m_hscroll->GetThumbPosition();
int ny = -m_vscroll->GetThumbPosition();
if (m_child)
{
wxPoint pos = m_child->GetPosition();
m_viewport->ScrollWindow(nx - pos.x, ny - pos.y);
}
}
void wxDynamicSashWindowLeaf::OnFocus(wxFocusEvent &event)
{
if ( event.GetEventObject() == m_hscroll ||
event.GetEventObject() == m_vscroll )
{
m_child->SetFocus();
}
}
void wxDynamicSashWindowLeaf::OnMouseMove(wxMouseEvent &event)
{
if (m_impl->m_dragging)
return;
DynamicSashRegion region = GetRegion(event.m_x, event.m_y);
wxCursor cursor(wxCURSOR_ARROW);
if (region == DSR_HORIZONTAL_TAB)
{
cursor = wxCursor(wxCURSOR_SIZENS);
}
else if (region == DSR_VERTICAL_TAB)
{
cursor = wxCursor(wxCURSOR_SIZEWE);
}
else if ((region == DSR_CORNER) &&
(m_impl->m_window->GetWindowStyle() & wxDS_DRAG_CORNER) != 0)
{
cursor = wxCursor(wxCURSOR_SIZENWSE);
}
else if (region == DSR_LEFT_EDGE || region == DSR_TOP_EDGE
|| region == DSR_RIGHT_EDGE || region == DSR_BOTTOM_EDGE)
{
if (m_impl->FindParent(region))
{
if (region == DSR_LEFT_EDGE || region == DSR_RIGHT_EDGE)
{
cursor = wxCursor(wxCURSOR_SIZEWE);
}
else
{
cursor = wxCursor(wxCURSOR_SIZENS);
}
}
}
m_impl->m_container->SetCursor(cursor);
}
void wxDynamicSashWindowLeaf::OnLeave(wxMouseEvent &WXUNUSED(event))
{
wxCursor cursor(wxCURSOR_ARROW);
m_impl->m_container->SetCursor(cursor);
}
void wxDynamicSashWindowLeaf::OnPress(wxMouseEvent &event)
{
DynamicSashRegion region = GetRegion(event.m_x, event.m_y);
if ((region == DSR_CORNER) && (m_impl->m_window->GetWindowStyle() & wxDS_DRAG_CORNER) == 0)
return;
if (region == DSR_HORIZONTAL_TAB || region == DSR_VERTICAL_TAB || region == DSR_CORNER)
{
m_impl->m_dragging = region;
m_impl->m_drag_x = event.m_x;
m_impl->m_drag_y = event.m_y;
m_impl->DrawSash(event.m_x, event.m_y);
m_impl->m_container->CaptureMouse();
}
else if (region == DSR_LEFT_EDGE || region == DSR_TOP_EDGE
|| region == DSR_RIGHT_EDGE || region == DSR_BOTTOM_EDGE)
{
wxDynamicSashWindowImpl *parent = m_impl->FindParent(region);
if (parent)
{
int x = event.m_x;
int y = event.m_y;
m_impl->m_container->ClientToScreen(&x, &y);
parent->m_container->ScreenToClient(&x, &y);
parent->m_dragging = parent->m_split;
parent->m_drag_x = x;
parent->m_drag_y = y;
parent->DrawSash(x, y);
parent->m_container->CaptureMouse();
}
}
}
void wxDynamicSashWindowLeaf::OnRelease(wxMouseEvent &WXUNUSED(event))
{
}
void wxDynamicSashWindowLeaf::OnReparent(wxEvent &WXUNUSED(event))
{
if (m_child)
{
m_child->Reparent(m_viewport);
}
ResizeChild(m_viewport->GetSize());
}
// ============================================================================
// events
// ============================================================================
wxDynamicSashSplitEvent::wxDynamicSashSplitEvent()
{
m_eventObject = NULL;
m_eventType = wxEVT_DYNAMIC_SASH_SPLIT;
}
wxDynamicSashSplitEvent::wxDynamicSashSplitEvent(wxObject *object)
{
m_eventObject = object;
m_eventType = wxEVT_DYNAMIC_SASH_SPLIT;
}
IMPLEMENT_DYNAMIC_CLASS(wxDynamicSashSplitEvent, wxCommandEvent)
wxDynamicSashUnifyEvent::wxDynamicSashUnifyEvent()
{
m_eventObject = NULL;
m_eventType = wxEVT_DYNAMIC_SASH_UNIFY;
}
wxDynamicSashUnifyEvent::wxDynamicSashUnifyEvent(wxObject *object)
{
m_eventObject = object;
m_eventType = wxEVT_DYNAMIC_SASH_UNIFY;
}
IMPLEMENT_DYNAMIC_CLASS(wxDynamicSashUnifyEvent, wxCommandEvent)
wxDynamicSashReparentEvent::wxDynamicSashReparentEvent()
{
m_eventObject = NULL;
m_eventType = wxEVT_DYNAMIC_SASH_REPARENT;
}
wxDynamicSashReparentEvent::wxDynamicSashReparentEvent(wxObject *object)
{
m_eventObject = object;
m_eventType = wxEVT_DYNAMIC_SASH_REPARENT;
}
wxDynamicSashReparentEvent::wxDynamicSashReparentEvent(const wxDynamicSashReparentEvent& evt)
: wxEvent(evt)
{
}
IMPLEMENT_DYNAMIC_CLASS(wxDynamicSashReparentEvent, wxEvent)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -