📄 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.35 2005/09/23 12:47:48 MR Exp $// Copyright: (c) Julian Smart// Licence: wxWindows licence/////////////////////////////////////////////////////////////////////////////// ============================================================================// declarations// ============================================================================// ----------------------------------------------------------------------------// headers// ----------------------------------------------------------------------------// For compilers that support precompilation, includes "wx/wx.h".#include "wx/wxprec.h"#ifdef __BORLANDC__ #pragma hdrstop#endif// for all others, include the necessary headers (this file is usually all you// need because it includes almost all "standard" wxWidgets headers)#ifndef WX_PRECOMP #include "wx/wx.h"#endif#ifdef __WXMSW__#include <windows.h>#include "wx/msw/winundef.h"#endif#include "wx/gizmos/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)#endif EVT_SIZE(wxRemotelyScrolledTreeCtrl::OnSize) EVT_PAINT(wxRemotelyScrolledTreeCtrl::OnPaint) EVT_TREE_ITEM_EXPANDED(wxID_ANY, wxRemotelyScrolledTreeCtrl::OnExpand) EVT_TREE_ITEM_COLLAPSED(wxID_ANY, 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 & ~wxTR_ROW_LINES){ m_companionWindow = NULL; // We draw the row lines ourself so they match what's done // by the companion window. That is why the flag is turned // off above, so wxGenericTreeCtrl doesn't draw them in a // different colour. m_drawRowLines = (style & wxTR_ROW_LINES) != 0;}wxRemotelyScrolledTreeCtrl::~wxRemotelyScrolledTreeCtrl(){}void wxRemotelyScrolledTreeCtrl::HideVScrollbar(){#if defined(__WXMSW__)#if USE_GENERIC_TREECTRL if (!IsKindOf(CLASSINFO(wxGenericTreeCtrl)))#endif { ::ShowScrollBar((HWND) GetHWND(), SB_VERT, false); }#if USE_GENERIC_TREECTRL else { // Implicit in overriding SetScrollbars }#endif#endif}// 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( #if USE_GENERIC_TREECTRL || !defined(__WXMSW__) int pixelsPerUnitX, int pixelsPerUnitY, int noUnitsX, int noUnitsY, int xPos, int yPos, bool noRefresh #else int WXUNUSED(pixelsPerUnitX), int WXUNUSED(pixelsPerUnitY), int WXUNUSED(noUnitsX), int WXUNUSED(noUnitsY), int WXUNUSED(xPos), int WXUNUSED(yPos), bool WXUNUSED(noRefresh) #endif ){#if USE_GENERIC_TREECTRL || !defined(__WXMSW__) if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) { wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; win->wxGenericTreeCtrl::SetScrollbars(pixelsPerUnitX, pixelsPerUnitY, noUnitsX, 0, xPos, 0, /* noRefresh */ true); wxScrolledWindow* scrolledWindow = GetScrolledWindow(); if (scrolledWindow) { scrolledWindow->SetScrollbars(0, pixelsPerUnitY, 0, noUnitsY, 0, yPos, noRefresh); } }#endif}// In case we're using the generic tree control.int wxRemotelyScrolledTreeCtrl::GetScrollPos( #if USE_GENERIC_TREECTRL || !defined(__WXMSW__) int orient #else int WXUNUSED(orient) #endif ) const{#if USE_GENERIC_TREECTRL || !defined(__WXMSW__) // this condition fixes extsitence of warning but wxScrolledWindow* scrolledWindow = // but GetScrolledWindow is still executed in case internally does something#endif GetScrolledWindow();#if USE_GENERIC_TREECTRL || !defined(__WXMSW__) if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) { wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; if (orient == wxHORIZONTAL) return win->wxGenericTreeCtrl::GetScrollPos(orient); else { return scrolledWindow->GetScrollPos(orient); } }#endif return 0;}// In case we're using the generic tree control.// Get the view startvoid wxRemotelyScrolledTreeCtrl::GetViewStart(int *x, int *y) const{ wxScrolledWindow* scrolledWindow = GetScrolledWindow();#if USE_GENERIC_TREECTRL || !defined(__WXMSW__) 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#endif { // 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( #if USE_GENERIC_TREECTRL || !defined(__WXMSW__) wxDC& dc #else wxDC& WXUNUSED(dc) #endif ){#if USE_GENERIC_TREECTRL || !defined(__WXMSW__) if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) { wxScrolledWindow* 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() ); }#endif}// Scroll to the given line (in scroll units where each unit is// the height of an item)void wxRemotelyScrolledTreeCtrl::ScrollToLine(int WXUNUSED(posHoriz), int posVert){#ifdef __WXMSW__#if USE_GENERIC_TREECTRL if (!IsKindOf(CLASSINFO(wxGenericTreeCtrl)))#endif // USE_GENERIC_TREECTRL { UINT sbCode = SB_THUMBPOSITION; HWND vertScrollBar = 0; MSWDefWindowProc((WXUINT) WM_VSCROLL, MAKELONG(sbCode, posVert), (WXLPARAM) vertScrollBar); }#if USE_GENERIC_TREECTRL else#endif // USE_GENERIC_TREECTRL#endif // __WXMSW__#if USE_GENERIC_TREECTRL || !defined(__WXMSW__) { 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); } */ }#endif // USE_GENERIC_TREECTRL || !defined(__WXMSW__) wxUnusedVar(posVert);}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);}void wxRemotelyScrolledTreeCtrl::OnPaint(wxPaintEvent& event){ wxPaintDC dc(this); wxTreeCtrl::OnPaint(event); if (! m_drawRowLines) return; // Reset the device origin since it may have been set dc.SetDeviceOrigin(0, 0); wxPen pen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID); dc.SetPen(pen); dc.SetBrush(* wxTRANSPARENT_BRUSH); wxSize clientSize = GetClientSize(); wxRect itemRect; wxTreeItemId h, lastH; for (h=GetFirstVisibleItem(); h.IsOk(); h=GetNextVisible(h)) { if (GetBoundingRect(h, itemRect)) { int cy = itemRect.GetTop(); dc.DrawLine(0, cy, clientSize.x, cy); lastH = h; } if (! IsVisible(h)) break; } if (lastH.IsOk() && GetBoundingRect(lastH, itemRect)) { int cy = itemRect.GetBottom(); dc.DrawLine(0, cy, clientSize.x, cy); }}// Adjust the containing wxScrolledWindow's scrollbars appropriatelyvoid wxRemotelyScrolledTreeCtrl::AdjustRemoteScrollbars(){#if USE_GENERIC_TREECTRL || !defined(__WXMSW__) 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#endif { // This is for the wxMSW tree control wxScrolledWindow* scrolledWindow = GetScrolledWindow(); if (scrolledWindow) { wxRect itemRect; if (GetBoundingRect(GetFirstVisibleItem(), 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 rectangles
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -