X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1724915f18ca8887521e28cbfdaa05a7fdaa3c04..349efbaa89b499557d9a26320bcbd9b012aac9d2:/contrib/src/gizmos/splittree.cpp?ds=sidebyside diff --git a/contrib/src/gizmos/splittree.cpp b/contrib/src/gizmos/splittree.cpp index 6d307776fc..86d7b72060 100644 --- a/contrib/src/gizmos/splittree.cpp +++ b/contrib/src/gizmos/splittree.cpp @@ -19,7 +19,7 @@ // headers // ---------------------------------------------------------------------------- #ifdef __GNUG__ - #pragma interface "splittree.cpp" + #pragma implementation "splittree.h" #endif // For compilers that support precompilation, includes "wx/wx.h". @@ -35,9 +35,15 @@ #include "wx/wx.h" #endif +#ifdef __WXMSW__ +#include +#include "wx/msw/winundef.h" +#endif + #include "wx/generic/treectlg.h" #include "wx/gizmos/splittree.h" +#include /* * wxRemotelyScrolledTreeCtrl @@ -55,7 +61,6 @@ BEGIN_EVENT_TABLE(wxRemotelyScrolledTreeCtrl, wxGenericTreeCtrl) BEGIN_EVENT_TABLE(wxRemotelyScrolledTreeCtrl, wxTreeCtrl) #endif EVT_SIZE(wxRemotelyScrolledTreeCtrl::OnSize) - EVT_PAINT(wxRemotelyScrolledTreeCtrl::OnPaint) EVT_TREE_ITEM_EXPANDED(-1, wxRemotelyScrolledTreeCtrl::OnExpand) EVT_TREE_ITEM_COLLAPSED(-1, wxRemotelyScrolledTreeCtrl::OnExpand) EVT_SCROLLWIN(wxRemotelyScrolledTreeCtrl::OnScroll) @@ -65,6 +70,7 @@ wxRemotelyScrolledTreeCtrl::wxRemotelyScrolledTreeCtrl(wxWindow* parent, wxWindo const wxSize& sz, long style): wxTreeCtrl(parent, id, pt, sz, style) { + m_companionWindow = NULL; } wxRemotelyScrolledTreeCtrl::~wxRemotelyScrolledTreeCtrl() @@ -106,13 +112,34 @@ void wxRemotelyScrolledTreeCtrl::SetScrollbars(int pixelsPerUnitX, int pixelsPer } } +// In case we're using the generic tree control. +int wxRemotelyScrolledTreeCtrl::GetScrollPos(int orient) const +{ + wxScrolledWindow* 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 start void wxRemotelyScrolledTreeCtrl::GetViewStart(int *x, int *y) const { + wxScrolledWindow* scrolledWindow = GetScrolledWindow(); + if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) { - wxScrolledWindow* scrolledWindow = GetScrolledWindow(); wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; int x1, y1, x2, y2; @@ -124,6 +151,12 @@ void wxRemotelyScrolledTreeCtrl::GetViewStart(int *x, int *y) const 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. @@ -143,7 +176,7 @@ void wxRemotelyScrolledTreeCtrl::PrepareDC(wxDC& dc) scrolledWindow->GetScrollPixelsPerUnit(& xppu2, & yppu2); dc.SetDeviceOrigin( -startX * xppu1, -startY * yppu2 ); - dc.SetUserScale( win->GetScaleX(), win->GetScaleY() ); + // dc.SetUserScale( win->GetScaleX(), win->GetScaleY() ); } } @@ -190,54 +223,57 @@ void wxRemotelyScrolledTreeCtrl::OnExpand(wxTreeEvent& event) // 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 appropriately void wxRemotelyScrolledTreeCtrl::AdjustRemoteScrollbars() { - // WILL THIS BE DONE AUTOMATICALLY BY THE GENERIC TREE CONTROL? -/* - -Problem with remote-scrolling the generic tree control. It relies -on PrepareDC for adjusting the device origin, which in turn takes -values from wxScrolledWindow: which we've turned off in order to use -a different scrollbar :-( So we could override PrepareDC and use -the _other_ scrolled window's position instead. -Note also ViewStart would need to be overridden. -Plus, wxGenericTreeCtrl::OnPaint will reset the device origin. - -*/ - - // Assumption: wxGenericTreeCtrl will adjust the scrollbars automatically, - // since it'll call SetScrollbars and we've defined this to Do The Right Thing. 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; - - wxScrolledWindow* scrolledWindow = GetScrolledWindow(); - if (scrolledWindow) + } + else { - wxRect itemRect; - if (GetBoundingRect(GetRootItem(), itemRect)) + // This is for the wxMSW tree control + wxScrolledWindow* scrolledWindow = GetScrolledWindow(); + if (scrolledWindow) { - int itemHeight = itemRect.GetHeight(); - - int w, h; - GetClientSize(&w, &h); - - wxRect rect(0, 0, 0, 0); - CalcTreeSize(rect); - int treeViewHeight = rect.GetHeight()/itemHeight; - - 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); + 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); + } } } } @@ -271,11 +307,8 @@ void wxRemotelyScrolledTreeCtrl::CalcTreeSize(wxRect& rect) CalcTreeSize(GetRootItem(), rect); } -void wxRemotelyScrolledTreeCtrl::CalcTreeSize(wxTreeItemId& id, wxRect& rect) +void wxRemotelyScrolledTreeCtrl::CalcTreeSize(const wxTreeItemId& id, wxRect& rect) { - // TODO: implement GetFirst/NextVisibleItem - // for wxGenericTreeCtrl, plus GetBoundingRect. - // 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 // or the top of the window? How would we convert? @@ -307,53 +340,127 @@ wxScrolledWindow* wxRemotelyScrolledTreeCtrl::GetScrolledWindow() const return NULL; } -void wxRemotelyScrolledTreeCtrl::OnPaint(wxPaintEvent& event) +void wxRemotelyScrolledTreeCtrl::OnScroll(wxScrollWinEvent& event) { - wxPaintDC dc(this); + int orient = event.GetOrientation(); + if (orient == wxHORIZONTAL) + { + event.Skip(); + return; + } + wxScrolledWindow* scrollWin = GetScrolledWindow(); + if (!scrollWin) + return; + + int x, y; + scrollWin->GetViewStart(& x, & y); + + ScrollToLine(-1, y); +} - wxTreeCtrl::OnPaint(event); +/* + * wxTreeCompanionWindow + * + * A window displaying values associated with tree control items. + */ - // Reset the device origin since it may have been set - dc.SetDeviceOrigin(0, 0); +IMPLEMENT_CLASS(wxTreeCompanionWindow, wxWindow) - wxSize sz = GetClientSize(); +BEGIN_EVENT_TABLE(wxTreeCompanionWindow, wxWindow) + EVT_PAINT(wxTreeCompanionWindow::OnPaint) + EVT_SCROLLWIN(wxTreeCompanionWindow::OnScroll) + EVT_TREE_ITEM_EXPANDED(-1, wxTreeCompanionWindow::OnExpand) + EVT_TREE_ITEM_COLLAPSED(-1, wxTreeCompanionWindow::OnExpand) +END_EVENT_TABLE() + +wxTreeCompanionWindow::wxTreeCompanionWindow(wxWindow* parent, wxWindowID id, + const wxPoint& pos, + const wxSize& sz, + long style): + wxWindow(parent, id, pos, sz, style) +{ + m_treeCtrl = NULL; +} - wxPen pen(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID); +void wxTreeCompanionWindow::DrawItem(wxDC& dc, wxTreeItemId id, const wxRect& rect) +{ + // TEST CODE +#if 1 + if (m_treeCtrl) + { + wxString text = m_treeCtrl->GetItemText(id); + dc.SetTextForeground(* wxBLACK); + dc.SetBackgroundMode(wxTRANSPARENT); + + int textW, textH; + dc.GetTextExtent(text, & textW, & textH); + + int x = 5; + int y = rect.GetY() + wxMax(0, (rect.GetHeight() - textH) / 2); + + dc.DrawText(text, x, y); + } +#endif +} + +void wxTreeCompanionWindow::OnPaint(wxPaintEvent& event) +{ + wxPaintDC dc(this); + + if (!m_treeCtrl) + return; + + wxPen pen(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID); dc.SetPen(pen); dc.SetBrush(* wxTRANSPARENT_BRUSH); + wxFont font(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + dc.SetFont(font); + wxSize clientSize = GetClientSize(); wxRect itemRect; - if (GetBoundingRect(GetRootItem(), itemRect)) + int cy=0; + wxTreeItemId h, lastH; + for(h=m_treeCtrl->GetFirstVisibleItem();h;h=m_treeCtrl->GetNextVisible(h)) { - int itemHeight = itemRect.GetHeight(); - wxRect rcClient = GetRect(); - int cy=0; - wxTreeItemId h; - for(h=GetFirstVisibleItem();h;h=GetNextVisible(h)) + if (m_treeCtrl->GetBoundingRect(h, itemRect)) { - dc.DrawLine(rcClient.x, cy, rcClient.x + rcClient.width, cy); - cy += itemHeight; + cy = itemRect.GetTop(); + wxRect drawItemRect(0, cy, clientSize.x, itemRect.GetHeight()); + + lastH = h; + + // Draw the actual item + DrawItem(dc, h, drawItemRect); + dc.DrawLine(0, cy, clientSize.x, cy); } - dc.DrawLine(rcClient.x, cy, rcClient.x + rcClient.width, cy); + } + if (lastH.IsOk() && m_treeCtrl->GetBoundingRect(lastH, itemRect)) + { + cy = itemRect.GetBottom(); + dc.DrawLine(0, cy, clientSize.x, cy); } } -void wxRemotelyScrolledTreeCtrl::OnScroll(wxScrollWinEvent& event) +void wxTreeCompanionWindow::OnScroll(wxScrollWinEvent& event) { int orient = event.GetOrientation(); if (orient == wxHORIZONTAL) { - // Don't 'skip' or we'd get into infinite recursion + event.Skip(); return; } - wxScrolledWindow* scrollWin = GetScrolledWindow(); - if (!scrollWin) + if (!m_treeCtrl) return; - int x, y; - scrollWin->GetViewStart(& x, & y); + // TODO: scroll the window physically instead of just refreshing. + Refresh(TRUE); +} - ScrollToLine(-1, y); +void wxTreeCompanionWindow::OnExpand(wxTreeEvent& event) +{ + // TODO: something more optimized than simply refresh the whole + // window when the tree is expanded/collapsed. Tricky. + Refresh(); } /* @@ -471,9 +578,12 @@ void wxSplitterScrolledWindow::OnScroll(wxScrollWinEvent& event) // don't cause an infinite loop static bool inOnScroll = FALSE; if (inOnScroll) + { + event.Skip(); return; + } inOnScroll = TRUE; - + int orient = event.GetOrientation(); int nScrollInc = CalcScrollInc(event); @@ -485,8 +595,13 @@ void wxSplitterScrolledWindow::OnScroll(wxScrollWinEvent& event) if (orient == wxHORIZONTAL) { + inOnScroll = FALSE; + event.Skip(); + return; +#if 0 int newPos = m_xScrollPosition + nScrollInc; SetScrollPos(wxHORIZONTAL, newPos, TRUE ); +#endif } else {