📄 splittree.cpp
字号:
/////////////////////////////////////////////////////////////////////////////// Name: splittree.cpp// Purpose: Classes to achieve a remotely-scrolled tree in a splitter// window that can be scrolled by a scrolled window higher in the// hierarchy// Author: Julian Smart// Modified by:// Created: 8/7/2000// RCS-ID: $Id: splittree.cpp,v 1.9 2002/02/28 18:30:35 julians Exp $// Copyright: (c) Julian Smart//// This program is part of the eCos host tools.//// This program is free software; you can redistribute it and/or modify it// under the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 of the License, or (at your option)// any later version.//// This program is distributed in the hope that it will be useful, but WITHOUT// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for// more details.//// You should have received a copy of the GNU General Public License along with// this program; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.///////////////////////////////////////////////////////////////////////////////// ============================================================================// declarations// ============================================================================// ----------------------------------------------------------------------------// headers// ----------------------------------------------------------------------------#ifdef __GNUG__#pragma implementation "splittree.h"#endif// For compilers that support precompilation, includes "wx/wx.h".#include "ecpch.h"#ifdef __WXMSW__#include "wx/msw/private.h"#endif#ifdef __BORLANDC__#pragma hdrstop#endif#include "wx/generic/treectlg.h"#include "splittree.h"#include <math.h>/** wxRemotelyScrolledTreeCtrl*/#if USE_GENERIC_TREECTRLIMPLEMENT_CLASS(wxRemotelyScrolledTreeCtrl, wxGenericTreeCtrl)#elseIMPLEMENT_CLASS(wxRemotelyScrolledTreeCtrl, wxTreeCtrl)#endif#if USE_GENERIC_TREECTRLBEGIN_EVENT_TABLE(wxRemotelyScrolledTreeCtrl, wxGenericTreeCtrl)#elseBEGIN_EVENT_TABLE(wxRemotelyScrolledTreeCtrl, wxTreeCtrl)#endifEVT_SIZE(wxRemotelyScrolledTreeCtrl::OnSize)EVT_TREE_ITEM_EXPANDED(-1, wxRemotelyScrolledTreeCtrl::OnExpand)EVT_TREE_ITEM_COLLAPSED(-1, wxRemotelyScrolledTreeCtrl::OnExpand)EVT_SCROLLWIN(wxRemotelyScrolledTreeCtrl::OnScroll)END_EVENT_TABLE()wxRemotelyScrolledTreeCtrl::wxRemotelyScrolledTreeCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pt, const wxSize& sz, long style): wxTreeCtrl(parent, id, pt, sz, style#if wxVERSION_NUMBER > 2301 & ~wxTR_ROW_LINES#endif ){ m_companionWindow = NULL;}wxRemotelyScrolledTreeCtrl::~wxRemotelyScrolledTreeCtrl(){}void wxRemotelyScrolledTreeCtrl::HideVScrollbar(){#ifdef __WXMSW__ if (!IsKindOf(CLASSINFO(wxGenericTreeCtrl))) { ::ShowScrollBar((HWND) GetHWND(), SB_VERT, FALSE); } else#endif { // Implicit in overriding SetScrollbars }}// Number of pixels per user unit (0 or -1 for no scrollbar)// Length of virtual canvas in user units// Length of page in user unitsvoid wxRemotelyScrolledTreeCtrl::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY, int noUnitsX, int noUnitsY, int xPos, int yPos, bool noRefresh){ if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) { wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; // Pass TRUE for noRefresh so that it doesn't // draw part of the tree as if the scroll view is // at zero vertically. win->wxGenericTreeCtrl::SetScrollbars(pixelsPerUnitX, pixelsPerUnitY, noUnitsX, 0, xPos, 0, /* noRefresh */ TRUE); ecScrolledWindow* scrolledWindow = GetScrolledWindow(); if (scrolledWindow) { scrolledWindow->SetScrollbars(0, pixelsPerUnitY, 0, noUnitsY, 0, yPos, noRefresh); } }}// In case we're using the generic tree control.int wxRemotelyScrolledTreeCtrl::GetScrollPos(int orient) const{ ecScrolledWindow* scrolledWindow = GetScrolledWindow(); if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) { wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; if (orient == wxHORIZONTAL) return win->wxGenericTreeCtrl::GetScrollPos(orient); else { return scrolledWindow->GetScrollPos(orient); } } return 0;}// In case we're using the generic tree control.// Get the view startvoid wxRemotelyScrolledTreeCtrl::GetViewStart(int *x, int *y) const{ ecScrolledWindow* scrolledWindow = GetScrolledWindow(); if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) { wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; int x1, y1, x2, y2; win->wxGenericTreeCtrl::GetViewStart(& x1, & y1); * x = x1; * y = y1; if (!scrolledWindow) return; scrolledWindow->GetViewStart(& x2, & y2); * y = y2; } else { // x is wrong since the horizontal scrollbar is controlled by the // tree control, but we probably don't need it. scrolledWindow->GetViewStart(x, y); }}// In case we're using the generic tree control.void wxRemotelyScrolledTreeCtrl::PrepareDC(wxDC& dc){ if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) { ecScrolledWindow* scrolledWindow = GetScrolledWindow(); wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; int startX, startY; GetViewStart(& startX, & startY); int xppu1, yppu1, xppu2, yppu2; win->wxGenericTreeCtrl::GetScrollPixelsPerUnit(& xppu1, & yppu1); scrolledWindow->GetScrollPixelsPerUnit(& xppu2, & yppu2); dc.SetDeviceOrigin( -startX * xppu1, -startY * yppu2 ); // dc.SetUserScale( win->GetScaleX(), win->GetScaleY() ); }}// Scroll to the given line (in scroll units where each unit is// the height of an item)void wxRemotelyScrolledTreeCtrl::ScrollToLine(int posHoriz, int posVert){#ifdef __WXMSW__ if (!IsKindOf(CLASSINFO(wxGenericTreeCtrl))) { UINT sbCode = SB_THUMBPOSITION; HWND vertScrollBar = 0; MSWDefWindowProc((WXUINT) WM_VSCROLL, MAKELONG(sbCode, posVert), (WXHWND) vertScrollBar); } else#endif { wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; win->Refresh(); /* Doesn't work yet because scrolling is ignored by Scroll int xppu, yppu; wxScrolledWindow* scrolledWindow = GetScrolledWindow(); if (scrolledWindow) { scrolledWindow->GetScrollPixelsPerUnit(& xppu, & yppu); win->Scroll(-1, posVert*yppu); } */ }}void wxRemotelyScrolledTreeCtrl::OnSize(wxSizeEvent& event){ HideVScrollbar(); AdjustRemoteScrollbars(); event.Skip();}void wxRemotelyScrolledTreeCtrl::OnExpand(wxTreeEvent& event){ AdjustRemoteScrollbars(); event.Skip(); // If we don't have this, we get some bits of lines still remaining if (event.GetEventType() == wxEVT_COMMAND_TREE_ITEM_COLLAPSED) Refresh(); // Pass on the event if (m_companionWindow) m_companionWindow->GetEventHandler()->ProcessEvent(event);}// Adjust the containing wxScrolledWindow's scrollbars appropriatelyvoid wxRemotelyScrolledTreeCtrl::AdjustRemoteScrollbars(){ if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) { // This is for the generic tree control. // It calls SetScrollbars which has been overridden // to adjust the parent scrolled window vertical // scrollbar. ((wxGenericTreeCtrl*) this)->AdjustMyScrollbars(); return; } else { // This is for the wxMSW tree control ecScrolledWindow* scrolledWindow = GetScrolledWindow(); if (scrolledWindow) { wxRect itemRect; if (GetBoundingRect(GetRootItem(), itemRect)) { // Actually, the real height seems to be 1 less than reported // (e.g. 16 instead of 16) int itemHeight = itemRect.GetHeight() - 1; int w, h; GetClientSize(&w, &h); wxRect rect(0, 0, 0, 0); CalcTreeSize(rect); double f = ((double) (rect.GetHeight()) / (double) itemHeight) ; int treeViewHeight = (int) ceil(f); int scrollPixelsPerLine = itemHeight; int scrollPos = - (itemRect.y / itemHeight); scrolledWindow->SetScrollbars(0, scrollPixelsPerLine, 0, treeViewHeight, 0, scrollPos); // Ensure that when a scrollbar becomes hidden or visible, // the contained window sizes are right. // Problem: this is called too early (?) wxSizeEvent event(scrolledWindow->GetSize(), scrolledWindow->GetId()); scrolledWindow->GetEventHandler()->ProcessEvent(event); } } }}// Calculate the area that contains both rectanglesstatic wxRect CombineRectangles(const wxRect& rect1, const wxRect& rect2){ wxRect rect; int right1 = rect1.GetRight(); int bottom1 = rect1.GetBottom(); int right2 = rect2.GetRight(); int bottom2 = rect2.GetBottom(); wxPoint topLeft = wxPoint(wxMin(rect1.x, rect2.x), wxMin(rect1.y, rect2.y)); wxPoint bottomRight = wxPoint(wxMax(right1, right2), wxMax(bottom1, bottom2)); rect.x = topLeft.x; rect.y = topLeft.y; rect.SetRight(bottomRight.x); rect.SetBottom(bottomRight.y); return rect;}// Calculate the tree overall size so we can set the scrollbar// correctly// static int g_count = 0;void wxRemotelyScrolledTreeCtrl::CalcTreeSize(wxRect& rect){ // g_count = 0; CalcTreeSize(GetRootItem(), rect);}void wxRemotelyScrolledTreeCtrl::CalcTreeSize(const wxTreeItemId& id, wxRect& rect){ // More efficient implementation would be to find the last item (but how?) // Q: is the bounding rect relative to the top of the virtual tree workspace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -