📄 dynamicsash.cpp
字号:
#ifdef __WXMSW__
&& ! wxIsKindOf(win, wxMDIChildFrame) // not top-level but still a frame
#endif
)
{
win = win->GetParent();
}
return win;
}
wxScrollBar *
wxDynamicSashWindowImpl::FindScrollBar(const wxWindow *child, int vert) const
{
if (m_child[0] == NULL && m_leaf == NULL)
return NULL;
if (!m_child[0])
{
return m_leaf->FindScrollBar(child, vert);
}
wxScrollBar *ret = m_child[0]->FindScrollBar(child, vert);
if (!ret)
ret = m_child[1]->FindScrollBar(child, vert);
return ret;
}
void wxDynamicSashWindowImpl::ConstrainChildren(int px, int py)
{
wxLayoutConstraints *layout = new wxLayoutConstraints();
layout->left.SameAs(m_container, wxLeft);
layout->top.SameAs(m_container, wxTop);
if (m_split == DSR_HORIZONTAL_TAB)
{
layout->right.SameAs(m_container, wxRight);
layout->height.PercentOf(m_container, wxHeight, py);
}
else
{
layout->bottom.SameAs(m_container, wxBottom);
layout->width.PercentOf(m_container, wxWidth, px);
}
m_child[0]->m_container->SetConstraints(layout);
layout = new wxLayoutConstraints();
layout->right.SameAs(m_container, wxRight);
layout->bottom.SameAs(m_container, wxBottom);
if (m_split == DSR_HORIZONTAL_TAB)
{
layout->top.Below(m_child[0]->m_container, 1);
layout->left.SameAs(m_container, wxLeft);
}
else
{
layout->left.RightOf(m_child[0]->m_container, 1);
layout->top.SameAs(m_container, wxTop);
}
m_child[1]->m_container->SetConstraints(layout);
}
void wxDynamicSashWindowImpl::Unify(int panel)
{
int other = panel == 0 ? 1 : 0;
if (m_child[panel]->m_leaf)
{
wxDynamicSashWindowImpl *child[2];
child[0] = m_child[0];
child[1] = m_child[1];
m_child[0] = m_child[1] = NULL;
m_leaf = new wxDynamicSashWindowLeaf(this);
m_leaf->Create();
m_leaf->m_child = child[panel]->m_leaf->m_child;
m_leaf->m_vscroll->SetScrollbar(child[panel]->m_leaf->m_vscroll->GetThumbPosition(),
child[panel]->m_leaf->m_vscroll->GetThumbSize(),
child[panel]->m_leaf->m_vscroll->GetRange(),
child[panel]->m_leaf->m_vscroll->GetPageSize());
m_leaf->m_hscroll->SetScrollbar(child[panel]->m_leaf->m_hscroll->GetThumbPosition(),
child[panel]->m_leaf->m_hscroll->GetThumbSize(),
child[panel]->m_leaf->m_hscroll->GetRange(),
child[panel]->m_leaf->m_hscroll->GetPageSize());
m_add_child_target = NULL;
wxDynamicSashReparentEvent event(m_leaf);
m_leaf->ProcessEvent(event);
delete child[0];
delete child[1];
m_split = DSR_NONE;
wxDynamicSashUnifyEvent unify(m_leaf->m_child);
m_leaf->m_child->ProcessEvent(unify);
}
else
{
m_split = m_child[panel]->m_split;
delete m_child[other];
wxDynamicSashWindowImpl *child_panel = m_child[panel];
m_child[0] = child_panel->m_child[0];
m_child[1] = child_panel->m_child[1];
m_child[0]->m_parent = this;
m_child[1]->m_parent = this;
m_add_child_target = NULL;
m_child[0]->m_container->Reparent(m_container);
m_child[1]->m_container->Reparent(m_container);
child_panel->m_child[0] = child_panel->m_child[1] = NULL;
delete child_panel;
wxSize size = m_container->GetSize();
wxSize child_size = m_child[0]->m_container->GetSize();
ConstrainChildren(child_size.GetWidth() * 100 / size.GetWidth(),
child_size.GetHeight() * 100 / size.GetHeight());
m_container->Layout();
}
}
void wxDynamicSashWindowImpl::Split(int px, int py)
{
m_add_child_target = NULL;
m_child[0] = new wxDynamicSashWindowImpl(m_window);
m_child[0]->m_container = new wxWindow(m_container, wxID_ANY);
m_child[0]->m_parent = this;
m_child[0]->m_top = m_top;
m_child[0]->Create();
if (m_leaf->m_child)
{
m_leaf->m_child->Reparent(m_container);
m_child[0]->AddChild(m_leaf->m_child);
}
m_child[1] = new wxDynamicSashWindowImpl(m_window);
m_child[1]->m_container = new wxWindow(m_container, wxID_ANY);
m_child[1]->m_parent = this;
m_child[1]->m_top = m_top;
m_child[1]->Create();
m_split = m_dragging;
ConstrainChildren(px, py);
m_top->m_add_child_target = m_child[1];
wxDynamicSashSplitEvent split(m_child[0]->m_leaf->m_child);
m_child[0]->m_leaf->m_child->ProcessEvent(split);
m_child[0]->m_leaf->m_vscroll->SetScrollbar(m_leaf->m_vscroll->GetThumbPosition(),
m_leaf->m_vscroll->GetThumbSize(),
m_leaf->m_vscroll->GetRange(),
m_leaf->m_vscroll->GetPageSize());
m_child[0]->m_leaf->m_hscroll->SetScrollbar(m_leaf->m_hscroll->GetThumbPosition(),
m_leaf->m_hscroll->GetThumbSize(),
m_leaf->m_hscroll->GetRange(),
m_leaf->m_hscroll->GetPageSize());
m_child[1]->m_leaf->m_vscroll->SetScrollbar(m_leaf->m_vscroll->GetThumbPosition(),
m_leaf->m_vscroll->GetThumbSize(),
m_leaf->m_vscroll->GetRange(),
m_leaf->m_vscroll->GetPageSize());
m_child[1]->m_leaf->m_hscroll->SetScrollbar(m_leaf->m_hscroll->GetThumbPosition(),
m_leaf->m_hscroll->GetThumbSize(),
m_leaf->m_hscroll->GetRange(),
m_leaf->m_hscroll->GetPageSize());
delete m_leaf;
m_leaf = NULL;
m_container->Layout();
}
/* This code is called when you finish resizing a view by dragging the
corner tab, but I think this implementation is lousy and will surprise
the user more often than it will do what they are trying to do. What
I really need to be doing here is do a rewrite such that *no* sashes
move except the ones immediately to the bottom and right of this window,
and handle the case where you resize a window larger than it's neighbors
by destroying the neighbors.
But this will do for now. */
void wxDynamicSashWindowImpl::Resize(int x, int y)
{
wxDynamicSashWindowImpl *h_parent = FindParent(DSR_BOTTOM_EDGE);
wxDynamicSashWindowImpl *v_parent = FindParent(DSR_RIGHT_EDGE);
int h_unify = -1;
int v_unify = -1;
wxWindow *frame = FindFrame();
if (x < 0)
x = 0;
if (y < 0)
y = 0;
if (h_parent)
{
m_container->ClientToScreen(NULL, &y);
h_parent->m_container->ScreenToClient(NULL, &y);
int py = (int)((y * 100) / h_parent->m_container->GetSize().GetHeight() + 0.5);
if (py < 10)
{
wxDynamicSashWindowImpl *ho_parent = FindParent(DSR_TOP_EDGE);
if (ho_parent)
{
if (FindUpperParent(h_parent, ho_parent) == ho_parent)
{
h_unify = 1;
}
else
{
py = (int)((ho_parent->m_child[0]->m_container->GetSize().GetHeight() * 100)
/ h_parent->m_container->GetSize().GetHeight() + 0.5);
h_parent->m_child[0]->m_container->GetConstraints()->height.PercentOf(
h_parent->m_container, wxHeight, py);
h_parent = ho_parent;
h_unify = 0;
}
}
else
{
h_unify = 1;
}
}
else if (py > 90)
{
h_unify = 0;
}
else
{
h_parent->m_child[0]->m_container->GetConstraints()->height.PercentOf(
h_parent->m_container, wxHeight, py);
h_parent->m_container->Layout();
}
}
else
{
int do_resize = 1;
h_parent = FindParent(DSR_TOP_EDGE);
if (h_parent)
{
int py = (int)((y * 100) /
(h_parent->m_container->GetSize().GetHeight() +
y - m_container->GetSize().GetHeight()) + 0.5);
if (py < 10)
h_unify = 0;
}
else if (y < 64)
{
do_resize = 0;
}
if (do_resize)
{
wxSize size = frame->GetSize();
frame->SetSize(size.GetWidth(), size.GetHeight() + y - m_container->GetSize().GetHeight());
}
}
if (v_parent)
{
m_container->ClientToScreen(&x, NULL);
v_parent->m_container->ScreenToClient(&x, NULL);
int px = (int)((x * 100) / v_parent->m_container->GetSize().GetWidth() + 0.5);
if (px < 10)
{
wxDynamicSashWindowImpl *vo_parent = FindParent(DSR_LEFT_EDGE);
if (vo_parent)
{
if (FindUpperParent(v_parent, vo_parent) == vo_parent)
{
v_unify = 1;
}
else
{
px = (int)((vo_parent->m_child[0]->m_container->GetSize().GetWidth() * 100)
/ v_parent->m_container->GetSize().GetWidth() + 0.5);
v_parent->m_child[0]->m_container->GetConstraints()->width.PercentOf(
v_parent->m_container, wxWidth, px);
v_parent = vo_parent;
v_unify = 0;
}
}
else
{
v_unify = 1;
}
}
else if (px > 90)
{
v_unify = 0;
}
else
{
v_parent->m_child[0]->m_container->GetConstraints()->width.PercentOf(
v_parent->m_container, wxWidth, px);
v_parent->m_container->Layout();
}
}
else
{
int do_resize = 1;
v_parent = FindParent(DSR_LEFT_EDGE);
if (v_parent)
{
int px = (int)((x * 100) /
(v_parent->m_container->GetSize().GetWidth() +
x - m_container->GetSize().GetWidth()) + 0.5);
if (px < 10)
v_unify = 0;
}
else if (x < 64)
{
do_resize = 0;
}
if (do_resize)
{
wxSize size = frame->GetSize();
frame->SetSize(size.GetWidth() + x - m_container->GetSize().GetWidth(), size.GetHeight());
}
}
if (h_unify != -1 && v_unify != -1)
{
wxDynamicSashWindowImpl *parent = FindUpperParent(h_parent, v_parent);
if (parent == h_parent)
{
h_parent->Unify(h_unify);
}
else
{
v_parent->Unify(v_unify);
}
}
else if (h_unify != -1)
{
h_parent->Unify(h_unify);
}
else if (v_unify != -1)
{
v_parent->Unify(v_unify);
}
}
void wxDynamicSashWindowImpl::OnSize(wxSizeEvent &event)
{
m_container->Layout();
if (m_leaf)
m_leaf->OnSize(event);
}
void wxDynamicSashWindowImpl::OnPaint(wxPaintEvent &event)
{
if (m_leaf)
m_leaf->OnPaint(event);
else
{
wxPaintDC dc(m_container);
dc.SetBackground(wxBrush(m_container->GetBackgroundColour(), wxSOLID));
dc.Clear();
}
}
void wxDynamicSashWindowImpl::OnMouseMove(wxMouseEvent &event)
{
if (m_dragging)
{
DrawSash(m_drag_x, m_drag_y);
m_drag_x = event.m_x; m_drag_y = event.m_y;
DrawSash(m_drag_x, m_drag_y);
}
else if (m_leaf)
{
m_leaf->OnMouseMove(event);
}
}
void wxDynamicSashWindowImpl::OnLeave(wxMouseEvent &event)
{
if (m_leaf)
m_leaf->OnLeave(event);
}
void wxDynamicSashWindowImpl::OnPress(wxMouseEvent &event)
{
if (m_leaf)
{
m_leaf->OnPress(event);
}
else
{
m_dragging = m_split;
m_drag_x = event.m_x;
m_drag_y = event.m_y;
DrawSash(m_drag_x, m_drag_y);
m_container->CaptureMouse();
}
}
void wxDynamicSashWindowImpl::OnRelease(wxMouseEvent &event)
{
if ((m_dragging == DSR_CORNER) &&
(m_window->GetWindowStyle() & wxDS_DRAG_CORNER) != 0)
{
DrawSash(m_drag_x, m_drag_y);
m_container->ReleaseMouse();
Resize(event.m_x, event.m_y);
m_dragging = DSR_NONE;
}
else if (m_dragging)
{
DrawSash(m_drag_x, m_drag_y);
m_container->ReleaseMouse();
wxSize size = m_container->GetSize();
int px = (int)((event.m_x * 100) / size.GetWidth() + 0.5);
int py = (int)((event.m_y * 100) / size.GetHeight() + 0.5);
if ((m_dragging == DSR_HORIZONTAL_TAB && py >= 10 && py <= 90)
|| (m_dragging == DSR_VERTICAL_TAB && px >= 10 && px <= 90))
{
if (m_child[0] == NULL)
{
Split(px, py);
}
else
{
/* It would be nice if moving *this* sash didn't implicitly move
the sashes of our children (if any). But this will do. */
wxLayoutConstraints *layout = m_child[0]->m_container->GetConstraints();
if (m_split == DSR_HORIZONTAL_TAB)
{
layout->height.PercentOf(m_container, wxHeight, py);
}
else
{
layout->width.PercentOf(m_container, wxWidth, px);
}
m_container->Layout();
}
}
else
{
if (m_child[0] != NULL)
{
if ((m_dragging == DSR_HORIZONTAL_TAB && py <= 10)
|| (m_dragging == DSR_VERTICAL_TAB && px <= 10))
{
Unify(1);
}
else
{
Unify(0);
}
}
}
wxCursor cursor;
if (m_split == DSR_HORIZONTAL_TAB)
cursor = wxCursor(wxCURSOR_SIZENS);
else if (m_split == DSR_VERTICAL_TAB)
cursor = wxCursor(wxCURSOR_SIZEWE);
else
cursor = wxCursor(wxCURSOR_ARROW);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -