📄 treewin.cc
字号:
xScroll -= -xx / 50 + 1; } const int OUTCOME_LENGTH = 60; CalcScrolledPosition((int) (entry->X() * m_zoom + m_drawSettings.NodeSize() + OUTCOME_LENGTH), (int) (entry->Y() * m_zoom), &xx, &yy); if (xx > width) { xScroll += (xx - width) / 50 + 1; } if (xScroll < 0) { xScroll = 0; } else if (xScroll > GetScrollRange(wxHORIZONTAL)) { xScroll = GetScrollRange(wxHORIZONTAL); } CalcScrolledPosition((int) (entry->X() * m_zoom), (int) (entry->Y() * m_zoom - 20), &xx, &yy); if (yy < 0) { yScroll -= -yy / 50 + 1; } CalcScrolledPosition((int) (entry->X() * m_zoom), (int) (entry->Y() * m_zoom + 20), &xx, &yy); if (yy > height) { yScroll += (yy - height) / 50 + 1; } if (yScroll < 0) { yScroll = 0; } else if (yScroll > GetScrollRange(wxVERTICAL)) { yScroll = GetScrollRange(wxVERTICAL); } Scroll(xScroll, yScroll);}void TreeWindow::ProcessCursor(void){ if (m_parent->Cursor()) { NodeEntry *entry = m_layout.GetNodeEntry(m_parent->Cursor()); if (!entry) { m_parent->SetCursor(m_efg.RootNode()); entry = m_layout.GetNodeEntry(m_parent->Cursor()); } UpdateCursor(); EnsureCursorVisible(); } Refresh();}void TreeWindow::UpdateCursor(void){ NodeEntry *entry = m_layout.GetNodeEntry(m_parent->Cursor()); if (entry) { entry->SetCursor(true); }}gText TreeWindow::OutcomeAsString(const Node *n) const{ efgOutcome *outcome = n->Game()->GetOutcome(n); if (outcome) { const gArray<gNumber> &v = n->Game()->Payoff(outcome); gText tmp = "("; for (int i = v.First(); i <= v.Last(); i++) { if (i != 1) tmp += ","; /* if (DrawSettings().ColorCodedOutcomes()) tmp += ("\\C{"+ToText(DrawSettings().GetPlayerColor(i))+"}"); */ tmp += ToText(v[i], DrawSettings().NumDecimals()); } /* if (DrawSettings().ColorCodedOutcomes()) tmp += ("\\C{"+ToText(WX_COLOR_LIST_LENGTH-1)+"}"); */ tmp += ")"; return tmp; } else return "";}#include "bitmaps/copy.xpm"#include "bitmaps/move.xpm"void TreeWindow::OnMouseMotion(wxMouseEvent &p_event){ if (p_event.LeftIsDown() && p_event.Dragging()) { if (!m_dragImage) { int x, y; CalcUnscrolledPosition(p_event.GetX(), p_event.GetY(), &x, &y); x = (int) ((float) x / m_zoom); y = (int) ((float) y / m_zoom); Node *node = m_layout.NodeHitTest(x, y); if (node && m_efg.NumChildren(node) > 0) { m_dragSource = node; if (p_event.ControlDown()) { m_dragImage = new wxDragImage("Copy subtree", wxCursor(wxCURSOR_HAND)); m_dragMode = dragCOPY; } else { m_dragImage = new wxDragImage("Move subtree", wxCursor(wxCURSOR_HAND)); m_dragMode = dragMOVE; } m_dragImage->BeginDrag(wxPoint(0, 0), this); m_dragImage->Show(); m_dragImage->Move(p_event.GetPosition()); return; } } else { m_dragImage->Move(p_event.GetPosition()); } } else if (!p_event.LeftIsDown() && m_dragImage) { m_dragImage->Hide(); m_dragImage->EndDrag(); delete m_dragImage; m_dragImage = 0; int x, y; CalcUnscrolledPosition(p_event.GetX(), p_event.GetY(), &x, &y); x = (int) ((float) x / m_zoom); y = (int) ((float) y / m_zoom); Node *node = m_layout.NodeHitTest(x, y); if (node && node->NumChildren() == 0) { try { if (m_dragMode == dragCOPY) { m_efg.CopyTree(m_dragSource, node); m_parent->OnTreeChanged(true, false); } else if (m_dragMode == dragMOVE) { m_efg.MoveTree(m_dragSource, node); m_parent->OnTreeChanged(true, false); RefreshTree(); } else if (m_dragMode == dragOUTCOME) { node->Game()->SetOutcome(node, m_dragSource->Game()->GetOutcome(m_dragSource)); } } catch (gException &ex) { guiExceptionDialog(ex.Description(), this); } } }} //// Left mouse button click:// Without key modifiers, selects a node// With shift key, selects whole subtree (not yet implemented)// With control key, adds node to selection (not yet implemented)//void TreeWindow::OnLeftClick(wxMouseEvent &p_event){ int x, y; CalcUnscrolledPosition(p_event.GetX(), p_event.GetY(), &x, &y); x = (int) ((float) x / m_zoom); y = (int) ((float) y / m_zoom); Node *node = m_layout.NodeHitTest(x, y); m_parent->SetCursor(node); Refresh(); ProcessCursor();}//// Left mouse button double-click:// Sets selection, brings up node properties dialog//void TreeWindow::OnLeftDoubleClick(wxMouseEvent &p_event){ int x, y; CalcUnscrolledPosition(p_event.GetX(), p_event.GetY(), &x, &y); x = (int) ((float) x / m_zoom); y = (int) ((float) y / m_zoom); Node *node = m_layout.NodeHitTest(x, y); if (node) { m_parent->SetCursor(node); Refresh(); wxCommandEvent event; m_parent->OnEditNode(event); }}//// Right mouse-button click:// Set selection, display context-sensitive popup menu//void TreeWindow::OnRightClick(wxMouseEvent &p_event){ int x, y; CalcUnscrolledPosition(p_event.GetX(), p_event.GetY(), &x, &y); x = (int) ((float) x / m_zoom); y = (int) ((float) y / m_zoom); wxClientDC dc(this); PrepareDC(dc); dc.SetUserScale(m_zoom, m_zoom); Node *node = m_layout.NodeHitTest(x, y); if (node) { m_parent->SetCursor(node); Refresh(); PopupMenu(m_nodeMenu, p_event.GetX(), p_event.GetY()); } else { // If right-click doesn't hit anything, display generic game menu m_parent->SetCursor(0); Refresh(); PopupMenu(m_gameMenu, p_event.GetX(), p_event.GetY()); }}void TreeWindow::SupportChanged(void){ if (!m_layout.GetNodeEntry(m_parent->Cursor())) { m_parent->SetCursor(0); } RefreshTree(); Refresh();}void TreeWindow::SetCursorPosition(Node *p_cursor){ if (m_parent->Cursor()) { m_layout.GetNodeEntry(m_parent->Cursor())->SetCursor(false); m_layout.GetNodeEntry(m_parent->Cursor())->SetSelected(false); }}void TreeWindow::UpdateMenus(void){ Node *cursor = m_parent->Cursor(); m_nodeMenu->Enable(wxID_COPY, (cursor) ? true : false); m_nodeMenu->Enable(wxID_CUT, (cursor) ? true : false); m_nodeMenu->Enable(wxID_PASTE, (m_parent->CopyNode() || m_parent->CutNode()) ? true : false); m_nodeMenu->Enable(efgmenuEDIT_INSERT, (cursor) ? true : false); m_nodeMenu->Enable(efgmenuEDIT_REVEAL, (cursor && cursor->GetInfoset())); m_nodeMenu->Enable(efgmenuEDIT_MOVE, (cursor && cursor->GetInfoset())); m_nodeMenu->Enable(efgmenuEDIT_TOGGLE_SUBGAME, (cursor && m_efg.IsLegalSubgame(cursor) && cursor->GetParent())); m_nodeMenu->Enable(efgmenuEDIT_MARK_SUBGAME_TREE, (cursor && m_efg.IsLegalSubgame(cursor))); m_nodeMenu->Enable(efgmenuEDIT_UNMARK_SUBGAME_TREE, (cursor && m_efg.IsLegalSubgame(cursor))); m_nodeMenu->SetLabel(efgmenuEDIT_TOGGLE_SUBGAME, (cursor && cursor->GetParent() && m_efg.IsLegalSubgame(cursor) && cursor->GetSubgameRoot() == cursor) ? "Unmark subgame" : "Mark subgame");}//-----------------------------------------------------------------------// DISPLAY MENU HANDLER FUNCTIONS//-----------------------------------------------------------------------void TreeWindow::OnSize(wxSizeEvent &p_event){ if (m_layout.MaxX() == 0 || m_layout.MaxY() == 0) { m_layout.Layout(*m_parent->GetSupport()); } // This extra check because wxMSW seems to generate OnSize events // rather liberally (e.g., a size of (0,0) for minimizing the window) if (p_event.GetSize().GetWidth() == 0 || p_event.GetSize().GetHeight() == 0) { return; } /* double zoomx = ((double) p_event.GetSize().GetWidth() / (double) m_layout.MaxX()); double zoomy = ((double) p_event.GetSize().GetHeight() / (double) m_layout.MaxY()); zoomx = gmin(zoomx, 1.0); zoomy = gmin(zoomy, 1.0); m_zoom = gmin(zoomx, zoomy); */ AdjustScrollbarSteps(); Refresh();}template class gList<NodeEntry *>;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -