From: John L. <jr...@us...> - 2005-06-06 23:06:28
|
Update of /cvsroot/wxlua/wxLua/modules/wxluadebug/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14733/wxLua/modules/wxluadebug/src Added Files: debug.cpp splttree.cpp staktree.cpp Log Message: moved files to the modules directory structure --- NEW FILE: splttree.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 // Created: 8/7/2000 // Modified by: J. Winwood, to fix a few bugs and also add a second // splitter and scrolled window (three columns rather than two). // Copyright: (c) Julian Smart // (c) 2002 Lomtick Software. All rights reserved. // Licence: wxWidgets licence ///////////////////////////////////////////////////////////////////////////// // ============================================================================ // declarations // ============================================================================ // ---------------------------------------------------------------------------- // headers // ---------------------------------------------------------------------------- #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "splttree.h" #endif // 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 "wxlua/splttree.h" #include <math.h> static wxTreeItemId defaultTreeItemId; /* * wxRemotelyScrolledTreeCtrl */ #if USE_GENERIC_TREECTRL IMPLEMENT_CLASS(wxRemotelyScrolledTreeCtrl, wxGenericTreeCtrl) #else IMPLEMENT_CLASS(wxRemotelyScrolledTreeCtrl, wxTreeCtrl) #endif #if USE_GENERIC_TREECTRL BEGIN_EVENT_TABLE(wxRemotelyScrolledTreeCtrl, wxGenericTreeCtrl) #else 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) EVT_TREE_SEL_CHANGED(-1, wxRemotelyScrolledTreeCtrl::OnSelChanged) 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_lastTreeItemId(defaultTreeItemId) { m_firstCompanionWindow = NULL; m_secondCompanionWindow = 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 units void wxRemotelyScrolledTreeCtrl::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY, int noUnitsX, int noUnitsY, int xPos, int yPos, bool noRefresh) { #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); scrolledWindow->AdjustScrollbars(); // FIXME - this is for the broken wxWindow's wxScrolledWindow } } #else # ifdef UNREFERENCED_PARAMETER UNREFERENCED_PARAMETER(pixelsPerUnitX); UNREFERENCED_PARAMETER(pixelsPerUnitY); UNREFERENCED_PARAMETER(noUnitsX); UNREFERENCED_PARAMETER(noUnitsY); UNREFERENCED_PARAMETER(xPos); UNREFERENCED_PARAMETER(yPos); UNREFERENCED_PARAMETER(noRefresh); # endif #endif } // In case we're using the generic tree control. int wxRemotelyScrolledTreeCtrl::GetScrollPos(int orient) const { #if USE_GENERIC_TREECTRL || !defined(__WXMSW__) wxScrolledWindow* scrolledWindow = GetScrolledWindow(); if (IsKindOf(CLASSINFO(wxGenericTreeCtrl))) { wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; if (orient == wxHORIZONTAL) return win->wxGenericTreeCtrl::GetScrollPos(orient); else return scrolledWindow->GetScrollPos(orient); } #else # ifdef UNREFERENCED_PARAMETER UNREFERENCED_PARAMETER(orient); # endif #endif 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 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(wxDC& dc) { #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() ); } #else # ifdef UNREFERENCED_PARAMETER UNREFERENCED_PARAMETER(dc); # endif #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 { UINT sbCode = SB_THUMBPOSITION; HWND vertScrollBar = 0; #if wxMINOR_VERSION < 5 MSWDefWindowProc((WXUINT) WM_VSCROLL, MAKELONG(sbCode, posVert), (WXHWND) vertScrollBar); #else MSWDefWindowProc((WXUINT) WM_VSCROLL, MAKELONG(sbCode, posVert), (WXLPARAM) vertScrollBar); #endif } #if USE_GENERIC_TREECTRL else #endif #endif #if USE_GENERIC_TREECTRL || !defined(__WXMSW__) { wxGenericTreeCtrl* win = (wxGenericTreeCtrl*) this; win->Refresh(); } #endif } void wxRemotelyScrolledTreeCtrl::OnSize(wxSizeEvent& event) { HideVScrollbar(); AdjustRemoteScrollbars(); if (m_firstCompanionWindow) m_firstCompanionWindow->Refresh(TRUE); if (m_secondCompanionWindow) m_secondCompanionWindow->Refresh(TRUE); 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_secondCompanionWindow) m_secondCompanionWindow->GetEventHandler()->ProcessEvent(event); if (m_firstCompanionWindow) m_firstCompanionWindow->GetEventHandler()->ProcessEvent(event); } void wxRemotelyScrolledTreeCtrl::OnSelChanged(wxTreeEvent& event) { const wxTreeItemId &itemId = GetFirstVisibleItem(); if (m_lastTreeItemId != itemId) { AdjustRemoteScrollbars(); event.Skip(); Refresh(); // Pass on the event if (m_secondCompanionWindow) m_secondCompanionWindow->GetEventHandler()->ProcessEvent(event); if (m_firstCompanionWindow) m_firstCompanionWindow->GetEventHandler()->ProcessEvent(event); m_lastTreeItemId = itemId; } else event.Skip(); } 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; int cy = 0; wxTreeItemId h, lastH; for(h = GetFirstVisibleItem(); h && IsVisible(h); h = GetNextVisible(h)) { if (GetBoundingRect(h, itemRect)) { cy = itemRect.GetTop(); dc.DrawLine(0, cy, clientSize.x, cy); lastH = h; } } if (lastH.IsOk() && GetBoundingRect(lastH, itemRect)) { cy = itemRect.GetBottom(); dc.DrawLine(0, cy, clientSize.x, cy); } } // Adjust the containing wxScrolledWindow's scrollbars appropriately void 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)) // newer method //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 - 1, 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); } } } } void wxRemotelyScrolledTreeCtrl::DeleteAllItems() { wxTreeCtrl::DeleteAllItems(); if (m_firstCompanionWindow) m_firstCompanionWindow->Refresh(TRUE); if (m_secondCompanionWindow) m_secondCompanionWindow->Refresh(TRUE); } // Calculate the area that contains both rectangles static 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 void wxRemotelyScrolledTreeCtrl::CalcTreeSize(wxRect& rect) { 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 // or the top of the window? How would we convert? wxRect itemSize; if (GetBoundingRect(id, itemSize)) { rect = CombineRectangles(rect, itemSize); } wxTreeItemIdValue cookie; wxTreeItemId childId = GetFirstChild(id, cookie); while (childId != wxTreeItemId((long)0)) { CalcTreeSize(childId, rect); childId = GetNextChild(childId, cookie); } } // Find the scrolled window that contains this control wxScrolledWindow* wxRemotelyScrolledTreeCtrl::GetScrolledWindow() const { wxWindow* parent = wxWindow::GetParent(); while (parent) { if (parent->IsKindOf(CLASSINFO(wxScrolledWindow))) return (wxScrolledWindow*) parent; parent = parent->GetParent(); } return NULL; } void wxRemotelyScrolledTreeCtrl::OnScroll(wxScrollWinEvent& event) { 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); // Pass on the event if (m_secondCompanionWindow) m_secondCompanionWindow->GetEventHandler()->ProcessEvent(event); if (m_firstCompanionWindow) m_firstCompanionWindow->GetEventHandler()->ProcessEvent(event); } /* * wxTreeCompanionWindow * * A window displaying values associated with tree control items. */ IMPLEMENT_CLASS(wxTreeCompanionWindow, wxWindow) 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) EVT_TREE_SEL_CHANGED(-1, wxTreeCompanionWindow::OnSelChanged) END_EVENT_TABLE() wxTreeCompanionWindow::wxTreeCompanionWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& sz, long style): wxWindow(parent, id, pos, sz, style) { m_treeControl = NULL; } wxTreeCompanionWindow::~wxTreeCompanionWindow() { } void wxTreeCompanionWindow::DrawItem(wxDC& dc, wxTreeItemId id, const wxRect& rect) { if (m_treeControl) { wxString text = m_treeControl->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); } } void wxTreeCompanionWindow::OnPaint(wxPaintEvent& WXUNUSED(event)) { if (m_treeControl == NULL) return; wxMemoryDC tempDC; wxSize clientSize = GetClientSize(); wxBitmap tempBitmap(clientSize.x, clientSize.y); tempDC.SelectObject(tempBitmap); tempDC.Clear(); wxPen pen(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID); tempDC.SetPen(pen); tempDC.SetBrush(*wxTRANSPARENT_BRUSH); wxFont font(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); tempDC.SetFont(font); wxRect itemRect; int cy = 0; wxTreeItemId h, lastH; for(h = m_treeControl->GetFirstVisibleItem(); h && m_treeControl->IsVisible(h); h = m_treeControl->GetNextVisible(h)) { if (m_treeControl->GetBoundingRect(h, itemRect)) { cy = itemRect.GetTop(); wxRect drawItemRect(0, cy, clientSize.x, itemRect.GetHeight()); lastH = h; // Draw the actual item DrawItem(tempDC, h, drawItemRect); tempDC.DrawLine(0, cy, clientSize.x, cy); } } if (lastH.IsOk() && m_treeControl->GetBoundingRect(lastH, itemRect)) { cy = itemRect.GetBottom(); tempDC.DrawLine(0, cy, clientSize.x, cy); } wxPaintDC dc(this); dc.Blit(0, 0, clientSize.x, clientSize.y, &tempDC, 0, 0); tempDC.SelectObject(wxNullBitmap); } void wxTreeCompanionWindow::OnScroll(wxScrollWinEvent& event) { int orient = event.GetOrientation(); if (orient == wxHORIZONTAL) { event.Skip(); return; } if (!m_treeControl) return; // TODO: scroll the window physically instead of just refreshing. Refresh(TRUE); } void wxTreeCompanionWindow::OnExpand(wxTreeEvent& WXUNUSED(event)) { // TODO: something more optimized than simply refresh the whole // window when the tree is expanded/collapsed. Tricky. Refresh(); } void wxTreeCompanionWindow::OnSelChanged(wxTreeEvent& WXUNUSED(event)) { Refresh(); } /* * wxThinSplitterWindow */ IMPLEMENT_CLASS(wxThinSplitterWindow, wxSplitterWindow) BEGIN_EVENT_TABLE(wxThinSplitterWindow, wxSplitterWindow) EVT_SIZE(wxThinSplitterWindow::OnSize) END_EVENT_TABLE() wxThinSplitterWindow::wxThinSplitterWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& sz, long style): wxSplitterWindow(parent, id, pos, sz, style) { } void wxThinSplitterWindow::SizeWindows() { // The client size may have changed inbetween // the sizing of the first window and the sizing of // the second. So repeat SizeWindows. wxSplitterWindow::SizeWindows(); wxSplitterWindow::SizeWindows(); } // Tests for x, y over sash bool wxThinSplitterWindow::SashHitTest(int x, int y, int WXUNUSED(tolerance)) { return wxSplitterWindow::SashHitTest(x, y, 4); } void wxThinSplitterWindow::DrawSash(wxDC& dc) { if ( m_sashPosition == 0 || !m_windowTwo) return; if (GetWindowStyle() & wxSP_NOSASH) return; int w, h; GetClientSize(&w, &h); wxColour faceColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); wxPen facePen(faceColour, 1, wxSOLID); wxBrush faceBrush(faceColour, wxSOLID); if ( m_splitMode == wxSPLIT_VERTICAL ) { dc.SetPen(facePen); dc.SetBrush(faceBrush); int h1 = h-1; int y1 = 0; if ( (GetWindowStyleFlag() & wxSP_BORDER) != wxSP_BORDER && (GetWindowStyleFlag() & wxSP_3DBORDER) != wxSP_3DBORDER ) h1 += 1; // Not sure why this is necessary... if ( (GetWindowStyleFlag() & wxSP_3DBORDER) == wxSP_3DBORDER) { y1 = 2; h1 -= 3; } dc.DrawRectangle(m_sashPosition, y1, 3, h1); // 3 == m_sashSize now gone in wxWidgets >= 2.5 } else { dc.SetPen(facePen); dc.SetBrush(faceBrush); int w1 = w-1; int x1 = 0; if ( (GetWindowStyleFlag() & wxSP_BORDER) != wxSP_BORDER && (GetWindowStyleFlag() & wxSP_3DBORDER) != wxSP_3DBORDER ) w1 ++; if ( (GetWindowStyleFlag() & wxSP_3DBORDER) == wxSP_3DBORDER) { x1 = 2; w1 -= 3; } dc.DrawRectangle(x1, m_sashPosition, w1, 3); } dc.SetPen(wxNullPen); dc.SetBrush(wxNullBrush); } void wxThinSplitterWindow::OnSize(wxSizeEvent& event) { wxSplitterWindow::OnSize(event); } /* * wxSplitterScrolledWindow */ IMPLEMENT_CLASS(wxSplitterScrolledWindow, wxScrolledWindow) BEGIN_EVENT_TABLE(wxSplitterScrolledWindow, wxScrolledWindow) EVT_SCROLLWIN(wxSplitterScrolledWindow::OnScroll) EVT_SIZE(wxSplitterScrolledWindow::OnSize) END_EVENT_TABLE() wxSplitterScrolledWindow::wxSplitterScrolledWindow(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& sz, long style): wxScrolledWindow(parent, id, pos, sz, style) { } void wxSplitterScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event)) { wxSize sz = GetClientSize(); if (GetChildren().GetFirst()) { ((wxWindow*) GetChildren().GetFirst()->GetData())->SetSize(0, 0, sz.x, sz.y); } } void wxSplitterScrolledWindow::OnScroll(wxScrollWinEvent& event) { // Ensure that events being propagated back up the window hierarchy // 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); if (nScrollInc == 0) { inOnScroll = FALSE; return; } if (orient == wxHORIZONTAL) { inOnScroll = FALSE; event.Skip(); return; } else { int newPos = m_yScrollPosition + nScrollInc; SetScrollPos(wxVERTICAL, newPos, TRUE ); } if (orient == wxHORIZONTAL) { m_xScrollPosition += nScrollInc; } else { m_yScrollPosition += nScrollInc; } // Find targets in splitter window and send the event to them wxWindowListNode* node = GetChildren().GetFirst(); while (node) { wxWindow* child = (wxWindow*) node->GetData(); if (child->IsKindOf(CLASSINFO(wxSplitterWindow))) { wxSplitterWindow* splitter = (wxSplitterWindow*) child; if (splitter->GetWindow1()) splitter->GetWindow1()->ProcessEvent(event); if (splitter->GetWindow2()) splitter->GetWindow2()->ProcessEvent(event); break; } node = node->GetNext(); } #ifdef __WXMAC__ m_targetWindow->MacUpdateImmediately() ; #endif inOnScroll = FALSE; } --- NEW FILE: staktree.cpp --- ///////////////////////////////////////////////////////////////////////////// // Name: StackTree.cpp // Purpose: Display the lua stack in a dialog. // Author: J. Winwood // Created: February 2002 // Copyright: (c) 2002 Lomtick Software. All rights reserved. // Licence: wxWidgets licence ///////////////////////////////////////////////////////////////////////////// // ---------------------------------------------------------------------------- // headers // ---------------------------------------------------------------------------- #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "staktree.h" #endif #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "wx/imaglist.h" #include "wxlua/staktree.h" #include "wxlua/internal.h" #include "wxlua/wxlua.h" #include "wxlua/debugio.h" #include "wxlua/dserver.h" #include "wxlua/library.h" #if defined(__WXGTK__) || defined(__WXMAC__) || defined(__WXMOTIF__) #include "../wxLua.xpm" #endif #if !defined(__WXMSW__) || wxUSE_XPM_IN_MSW /* Closed folder */ static char * icon1_xpm[] = { /* width height ncolors chars_per_pixel */ "16 16 6 1", /* colors */ " s None c None", ". c #000000", "+ c #c0c0c0", "@ c #808080", "# c #ffff00", "$ c #ffffff", /* pixels */ " ", " @@@@@ ", " @#+#+#@ ", " @#+#+#+#@@@@@@ ", " @$$$$$$$$$$$$@.", " @$#+#+#+#+#+#@.", " @$+#+#+#+#+#+@.", " @$#+#+#+#+#+#@.", " @$+#+#+#+#+#+@.", " @$#+#+#+#+#+#@.", " @$+#+#+#+#+#+@.", " @$#+#+#+#+#+#@.", " @@@@@@@@@@@@@@.", " ..............", " ", " " }; /* File */ static char * icon2_xpm[] = { /* width height ncolors chars_per_pixel */ "16 16 3 1", /* colors */ " s None c None", ". c #000000", "+ c #ffffff", /* pixels */ " ", " ........ ", " .++++++.. ", " .+.+.++.+. ", " .++++++.... ", " .+.+.+++++. ", " .+++++++++. ", " .+.+.+.+.+. ", " .+++++++++. ", " .+.+.+.+.+. ", " .+++++++++. ", " .+.+.+.+.+. ", " .+++++++++. ", " ........... ", " ", " " }; #endif // ---------------------------------------------------------------------------- // wxLuaStackFrame // ---------------------------------------------------------------------------- wxLuaStackFrame::wxLuaStackFrame( wxWindow *parent, const wxString &title, const wxPoint &pos, const wxSize &size, wxLuaDebugServer *pServer) : wxDialog(parent, idSTACK_FRAME, title, pos, size, wxCAPTION | wxSYSTEM_MENU | wxDIALOG_MODAL | wxRESIZE_BORDER), m_luaInterface(NULL), m_pServer(pServer) { Construct(); } wxLuaStackFrame::wxLuaStackFrame( wxWindow *parent, const wxString &title, const wxPoint &pos, const wxSize &size, wxLuaInterface *luaInterface) : wxDialog(parent, idSTACK_FRAME, title, pos, size, wxCAPTION | wxSYSTEM_MENU | wxDIALOG_MODAL | wxRESIZE_BORDER), m_luaInterface(luaInterface), m_pServer(NULL) { Construct(); } wxLuaStackFrame::~wxLuaStackFrame() { if (m_pServer != NULL) m_pServer->CleanupDebugReferences(); if (m_pServer != NULL) wxGetLuaHandler().SetStackFrame(NULL); } void wxLuaStackFrame::Construct() { m_treeSplitter = NULL; m_valueSplitter = NULL; m_scrolledWindow = NULL; m_treeControl = NULL; m_firstValueWindow = NULL; m_secondValueWindow = NULL; if (m_pServer != NULL) wxGetLuaHandler().SetStackFrame(this); m_stackComboBox = new wxComboBox( this, idSTACK_COMBOBOX, wxEmptyString, wxPoint(0, 0), wxDefaultSize, 0, NULL, wxCB_DROPDOWN | wxCB_READONLY); m_scrolledWindow = new wxSplitterScrolledWindow(this, idSCROLLED_WINDOW, wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxCLIP_CHILDREN | wxVSCROLL); #if wxCHECK_VERSION(2, 3, 0) m_dismissButton = new wxButton(this, idDISMISS_BUTTON, _("Cancel"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); #else m_dismissButton = new wxButton(this, idDISMISS_BUTTON, _("Cancel"), wxDefaultPosition, wxDefaultSize); #endif m_dismissButton->SetDefault(); m_treeSplitter = new wxThinSplitterWindow(m_scrolledWindow, idSPLITTER_WINDOW, wxDefaultPosition, wxDefaultSize, wxSP_3DBORDER | wxCLIP_CHILDREN); m_treeSplitter->SetSashSize(2); /* Note the wxTR_ROW_LINES style: draws horizontal lines between items */ #if wxCHECK_VERSION(2, 3, 0) m_treeControl = new wxLuaStackTree(m_treeSplitter, idSTACKTREE_CTRL, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxTR_NO_LINES | wxNO_BORDER | wxTR_ROW_LINES ); #else m_treeControl = new wxLuaStackTree(m_treeSplitter, idSTACKTREE_CTRL, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxTR_NO_LINES | wxNO_BORDER); #endif m_valueSplitter = new wxThinSplitterWindow(m_treeSplitter, idVALUE_SPLITTER_WINDOW, wxDefaultPosition, wxDefaultSize, wxSP_NOBORDER | wxCLIP_CHILDREN); m_valueSplitter->SetSashSize(2); m_firstValueWindow = new wxLuaStackDataWindow(m_valueSplitter, idFIRST_VALUE_WINDOW, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); m_secondValueWindow = new wxLuaStackDataWindow(m_valueSplitter, idSECOND_VALUE_WINDOW, wxDefaultPosition, wxDefaultSize, wxNO_BORDER, false); m_treeSplitter->SetSashPosition(25); m_treeSplitter->SetMinimumPaneSize(10); m_treeSplitter->SplitVertically(m_treeControl, m_valueSplitter); m_valueSplitter->SetSashPosition(125); m_valueSplitter->SetMinimumPaneSize(10); m_valueSplitter->SplitVertically(m_firstValueWindow, m_secondValueWindow); m_scrolledWindow->SetTargetWindow(m_treeControl); m_scrolledWindow->EnableScrolling(FALSE, FALSE); // Let the two controls know about each other m_firstValueWindow->SetTreeCtrl(m_treeControl); m_secondValueWindow->SetTreeCtrl(m_treeControl); m_treeControl->SetCompanionWindows(m_firstValueWindow, m_secondValueWindow); // set the frame icon #if wxCHECK_VERSION(2, 3, 0) SetIcon(wxICON(LUA)); #endif int nWidth, nHeight; GetClientSize(&nWidth, &nHeight); SizeWindow(nWidth, nHeight); if (m_pServer != NULL) m_pServer->EnumerateStack(); else { wxLuaDebugData *pSortedList = m_luaInterface->BuildStack(); if (pSortedList != NULL) { FillStackCombobox(pSortedList); delete pSortedList; } } } void wxLuaStackFrame::FillStackCombobox(const wxLuaDebugData *pSortedList) { size_t idx; m_stackComboBox->Clear(); for (idx = 0; idx < pSortedList->Count(); ++idx) { const wxLuaDebugDataItem *item = pSortedList->Item(idx); #if defined(__WXMAC__) // Mac is dying on the two parameter version...don't know how to fix. m_stackComboBox->Append(item->GetName()); #else m_stackComboBox->Append(item->GetName(), (void *) item->GetReference()); #endif } if (pSortedList->Count() > 0) { m_stackComboBox->SetSelection(0); SelectStack(0); } } BEGIN_EVENT_TABLE(wxLuaStackFrame, wxDialog) EVT_SIZE(wxLuaStackFrame::OnSizeWindow) EVT_COMBOBOX(idSTACK_COMBOBOX, wxLuaStackFrame::OnSelectStack) EVT_TREE_ITEM_EXPANDING(idSTACKTREE_CTRL, wxLuaStackFrame::OnItemExpanding) EVT_BUTTON(idDISMISS_BUTTON, wxLuaStackFrame::OnCloseDialog) END_EVENT_TABLE() void wxLuaStackFrame::OnSizeWindow(wxSizeEvent &event) { wxSize size = GetClientSize(); //event.GetSize(); event size no good in > 2.5.3 at least SizeWindow(size.x, size.y); event.Skip(); } void wxLuaStackFrame::SizeWindow(int nWidth, int nHeight) { int nComboWidth, nComboHeight, nButtonWidth, nButtonHeight; m_stackComboBox->GetSize(&nComboWidth, &nComboHeight); m_dismissButton->GetSize(&nButtonWidth, &nButtonHeight); nComboHeight += 2; // makes it look a little better m_stackComboBox->SetSize(0, 0, nWidth, -1); m_scrolledWindow->SetSize(0, nComboHeight, nWidth, nHeight - 15 - nComboHeight - nButtonHeight); m_dismissButton->SetSize((nWidth / 2) - (nButtonWidth / 2), nHeight - 5 - nButtonHeight, nButtonWidth, nButtonHeight); } void wxLuaStackFrame::OnSelectStack(wxCommandEvent &event) { SelectStack(event.GetSelection()); } void wxLuaStackFrame::SelectStack(int nCurrentSel) { m_nCurrentSel = nCurrentSel; int nEntry = (int) m_stackComboBox->GetClientData(nCurrentSel); if (m_pServer != NULL) { m_pServer->EnumerateStackEntry(nEntry); } else { wxLuaDebugData *pSortedList = m_luaInterface->BuildStackList(nEntry); if (pSortedList != NULL) { FillStackEntry(nEntry, pSortedList); delete pSortedList; } } } void wxLuaStackFrame::FillStackEntry(int WXUNUSED(nEntry), const wxLuaDebugData *pSortedList) { m_treeControl->DeleteAllItems(); wxTreeItemId rootItem = m_treeControl->AddRoot(_("Locals"), -1, -1); m_treeControl->AdjustRemoteScrollbars(); size_t idx; for (idx = 0; idx < pSortedList->Count(); ++idx) { const wxLuaDebugDataItem *item = pSortedList->Item(idx); int nOffset = 1; if (item->GetReference() != LUA_NOREF) nOffset = 0; wxTreeItemId treeNode = m_treeControl->AppendItem(rootItem, item->GetName(), nOffset, nOffset, new wxLuaDebugDataItem(*item)); if (item->GetReference() != LUA_NOREF) m_treeControl->SetItemHasChildren(treeNode); } // If at global scope, process globals if (m_nCurrentSel == m_stackComboBox->GetCount() - 1) { if (m_pServer != NULL) m_pServer->EnumerateTable(-1, -1, rootItem); else { wxLuaDebugData *pSortedList = m_luaInterface->GetGlobalData(); const wxLuaDebugDataItem *item = pSortedList->Item(0); wxTreeItemId treeNode = m_treeControl->AppendItem( rootItem, item->GetName(), 0, 0, new wxLuaDebugDataItem(*item)); if (item->GetReference() != LUA_NOREF) m_treeControl->SetItemHasChildren(treeNode); GetDerivedAndTrackedItems(m_treeControl, rootItem); delete pSortedList; } } m_treeControl->Expand(rootItem); } void wxLuaStackFrame::GetDerivedAndTrackedItems(wxRemotelyScrolledTreeCtrl *treeControl, wxTreeItemId rootItem) { GET_LUASTATEVARS_RET(m_luaInterface->GetLuaState()) int derivedCount = 0, trackedCount = 0, appHandlerCount = 0, windowCount = 0; if (stateVars->m_pDerivedList) derivedCount = stateVars->m_pDerivedList->GetCount(); if (stateVars->m_pTrackedList) trackedCount = stateVars->m_pTrackedList->GetCount(); if (stateVars->m_pAppHandlerList) appHandlerCount = stateVars->m_pAppHandlerList->GetCount(); if (stateVars->m_pWindowList) windowCount = stateVars->m_pWindowList->GetCount(); treeControl->AppendItem (rootItem, wxT("Derived List"), 1, 1, new wxLuaDebugDataItem(_("Derived List"), wxT("wxLuaData"), wxT(""), wxString::Format(wxT("%d"), derivedCount), LUA_NOREF, 0)); treeControl->AppendItem (rootItem, wxT("Tracked List"), 1, 1, new wxLuaDebugDataItem(_("Tracked List"), wxT("wxLuaData"), wxT(""), wxString::Format(wxT("%d"), trackedCount), LUA_NOREF, 0)); treeControl->AppendItem (rootItem, wxT("AppHandler List"), 1, 1, new wxLuaDebugDataItem(_("AppHandler List"), wxT("wxLuaData"), wxT(""), wxString::Format(wxT("%d"), appHandlerCount), LUA_NOREF, 0)); treeControl->AppendItem (rootItem, wxT("wxWindow List"), 1, 1, new wxLuaDebugDataItem(_("wxWindow List"), wxT("wxLuaData"), wxT(""), wxString::Format(wxT("%d"), windowCount), LUA_NOREF, 0)); } void wxLuaStackFrame::OnItemExpanding(wxTreeEvent &event) { ItemExpanding(event.GetItem()); } void wxLuaStackFrame::ItemExpanding(const wxTreeItemId &itemNode) { if (itemNode) { wxLuaDebugDataItem *pDebugData = (wxLuaDebugDataItem *)m_treeControl->GetItemData(itemNode); if (pDebugData != NULL) { int nRef = pDebugData->GetReference(); if (nRef != LUA_NOREF) { int nIndex = pDebugData->GetIndex() + 1; if (!pDebugData->IsExpanded()) { pDebugData->SetExpanded(true); if (m_pServer != NULL) { m_pServer->EnumerateTable(nRef, nIndex, itemNode); } else { // insert items wxLuaDebugData *pSortedList = m_luaInterface->BuildTableList(nRef, nIndex); if (pSortedList != NULL) { FillTableEntry(itemNode, pSortedList); delete pSortedList; } } } } } } } void wxLuaStackFrame::FillTableEntry(wxTreeItemId itemNode, const wxLuaDebugData *pSortedList) { if (pSortedList->Count() == 0) m_treeControl->SetItemHasChildren(itemNode, false); else { size_t count; for (count = 0; count < pSortedList->Count(); ++count) { const wxLuaDebugDataItem *item = pSortedList->Item(count); int nOffset = 1; if (item->GetReference() != LUA_NOREF) nOffset = 0; wxTreeItemId treeNode = m_treeControl->AppendItem(itemNode, item->GetName(), nOffset, nOffset, new wxLuaDebugDataItem(*item)); if (item->GetReference() != LUA_NOREF) m_treeControl->SetItemHasChildren(treeNode); } } m_treeControl->Expand(itemNode); } void wxLuaStackFrame::OnCloseDialog(wxCommandEvent & WXUNUSED(event)) { EndModal(0); } // ---------------------------------------------------------------------------- // wxLuaStackTree // ---------------------------------------------------------------------------- wxLuaStackTree::wxLuaStackTree( wxWindow *parent, wxWindowID id, const wxPoint &pt, const wxSize &sz, long style) : wxRemotelyScrolledTreeCtrl(parent, id, pt, sz, style) { m_imageList = new wxImageList(16, 16, TRUE); #if !defined(__WXMSW__) // || wxUSE_XPM_IN_MSW m_imageList->Add(wxIcon(icon1_xpm)); m_imageList->Add(wxIcon(icon2_xpm)); #elif defined(__WXMSW__) m_imageList->Add(wxIcon(wxT("wxICON_SMALL_CLOSED_FOLDER"), wxBITMAP_TYPE_ICO_RESOURCE)); m_imageList->Add(wxIcon(wxT("wxICON_SMALL_FILE"), wxBITMAP_TYPE_ICO_RESOURCE)); #else #error "Sorry, we don't have icons available for this platforms." #endif SetImageList(m_imageList); } IMPLEMENT_CLASS(wxLuaStackTree, wxRemotelyScrolledTreeCtrl) BEGIN_EVENT_TABLE(wxLuaStackTree, wxRemotelyScrolledTreeCtrl) END_EVENT_TABLE() wxLuaStackTree::~wxLuaStackTree() { SetImageList(NULL); delete m_imageList; } // ---------------------------------------------------------------------------- // wxLuaStackDataWindow // ---------------------------------------------------------------------------- BEGIN_EVENT_TABLE(wxLuaStackDataWindow, wxTreeCompanionWindow) END_EVENT_TABLE() wxLuaStackDataWindow::wxLuaStackDataWindow(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &sz, long style, bool fFirst): wxTreeCompanionWindow(parent, id, pos, sz, style), m_fFirst(fFirst) { SetBackgroundColour(*wxWHITE); } void wxLuaStackDataWindow::DrawItem(wxDC &dc, wxTreeItemId id, const wxRect &rect) { if (m_treeControl) { wxLuaDebugDataItem *itemData = (wxLuaDebugDataItem *) m_treeControl->GetItemData(id); dc.SetTextForeground(*wxBLACK); dc.SetBackgroundMode(wxTRANSPARENT); int textWidth, textHeight = 0; if (itemData != NULL) { if (m_fFirst) dc.GetTextExtent(itemData->GetType(), &textWidth, &textHeight); else dc.GetTextExtent(itemData->GetValue(), &textWidth, &textHeight); } int x = 5; int y = rect.GetY() + wxMax(0, (rect.GetHeight() - textHeight) / 2); if (itemData != NULL) { if (m_fFirst) dc.DrawText(itemData->GetType(), x, y); else dc.DrawText(itemData->GetValue(), x, y); } } } --- NEW FILE: debug.cpp --- ///////////////////////////////////////////////////////////////////////////// // Name: wxLuaDebug.cpp // Purpose: Debugging I/O functions for wxLua // Author: J. Winwood // Created: May 2002 // Copyright: (c) 2002 Lomtick Software. All rights reserved. // Licence: wxWidgets licence ///////////////////////////////////////////////////////////////////////////// // Ray Gilbert #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "debug.h" #endif #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "wxlua/debug.h" #include "wxlua/internal.h" DEFINE_EVENT_TYPE(wxEVT_DEBUG_CLIENT_CONNECTED) DEFINE_EVENT_TYPE(wxEVT_DEBUG_BREAK) DEFINE_EVENT_TYPE(wxEVT_DEBUG_PRINT) DEFINE_EVENT_TYPE(wxEVT_DEBUG_ERROR) DEFINE_EVENT_TYPE(wxEVT_DEBUG_EXIT) DEFINE_EVENT_TYPE(wxEVT_DEBUG_STACK_ENUM) DEFINE_EVENT_TYPE(wxEVT_DEBUG_STACK_ENTRY_ENUM) DEFINE_EVENT_TYPE(wxEVT_DEBUG_TABLE_ENUM) DEFINE_EVENT_TYPE(wxEVT_DEBUG_EVALUATE_EXPR) DEFINE_EVENT_TYPE(wxEVT_DEBUG_STARTDEBUGGER) DEFINE_EVENT_TYPE(wxEVT_DEBUG_STOPDEBUGGER) DEFINE_EVENT_TYPE(wxEVT_DEBUG_BREAKPOINT_ADDED) DEFINE_EVENT_TYPE(wxEVT_DEBUG_BREAKPOINT_REMOVED) // ---------------------------------------------------------------------------- // wxLuaBuffer // ---------------------------------------------------------------------------- IMPLEMENT_CLASS(wxLuaBuffer, wxObject) wxLuaBuffer::wxLuaBuffer(const wxString &fileName, const wxString &buffer) : m_fileName(fileName), m_buffer(buffer) { } // ---------------------------------------------------------------------------- // wxLuaBuffer // ---------------------------------------------------------------------------- IMPLEMENT_CLASS(wxLuaDebuggerBase, wxEvtHandler) // ---------------------------------------------------------------------------- // wxLuaDebugEvent // ---------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS(wxLuaDebugEvent, wxEvent) wxLuaDebugEvent::wxLuaDebugEvent() { m_fHasMessage = false; m_pDebugData = NULL; m_nReference = -1; m_fEnabledFlag = false; } wxLuaDebugEvent::wxLuaDebugEvent(int eventType) { SetEventType(eventType); m_fHasMessage = false; m_pDebugData = NULL; m_nReference = -1; m_fEnabledFlag = false; } wxLuaDebugEvent::wxLuaDebugEvent(int eventType, int lineNumber, const wxString &file, bool enabledFlag) { SetEventType(eventType); m_lineNumber = lineNumber; m_fileName = file; m_fHasMessage = false; m_nReference = -1; m_pDebugData = NULL; m_fEnabledFlag = enabledFlag; } wxLuaDebugEvent::~wxLuaDebugEvent() { if (m_pDebugData != NULL) delete m_pDebugData; } void wxLuaDebugEvent::SetMessage(const wxString &pMessage) { m_strMessage = pMessage; m_fHasMessage = true; } void wxLuaDebugEvent::SetDebugData(int nReference, wxLuaDebugData *pData) { m_nReference = nReference; m_pDebugData = pData; } int wxLuaDebugEvent::GetLineNumber() const { return m_lineNumber; } wxString wxLuaDebugEvent::GetFileName() const { return m_fileName; } wxString wxLuaDebugEvent::GetMessage() const { return m_strMessage; } bool wxLuaDebugEvent::GetEnabledFlag() const { return m_fEnabledFlag; } const wxLuaDebugData *wxLuaDebugEvent::GetDebugData() const { return m_pDebugData; } int wxLuaDebugEvent::GetReference() const { return m_nReference; } wxEvent *wxLuaDebugEvent::Clone() const { wxLuaDebugEvent *pEvent = new wxLuaDebugEvent(GetEventType(), m_lineNumber, m_fileName); if (pEvent != NULL) { if (m_fHasMessage) pEvent->SetMessage(m_strMessage); if (m_pDebugData != NULL) pEvent->SetDebugData(m_nReference, m_pDebugData->Clone()); else pEvent->SetDebugData(m_nReference); } return pEvent; } // ---------------------------------------------------------------------------- // wxLuaDebugDataItem // ---------------------------------------------------------------------------- wxLuaDebugDataItem::wxLuaDebugDataItem(const wxString &itemName, const wxString &itemType, const wxString &itemValue, const wxString &itemSource, int nReference, int nIndex, bool fExpanded) { m_itemName = itemName; m_itemType = itemType; m_itemValue = itemValue; m_itemSource = itemSource; m_nReference = nReference; m_nIndex = nIndex; m_fExpanded = fExpanded; } wxLuaDebugDataItem::wxLuaDebugDataItem(const wxLuaDebugDataItem &treeItem) { m_itemName = treeItem.m_itemName; m_itemType = treeItem.m_itemType; m_itemValue = treeItem.m_itemValue; m_itemSource = treeItem.m_itemSource; m_nReference = treeItem.m_nReference; m_nIndex = treeItem.m_nIndex; m_fExpanded = treeItem.m_fExpanded; } // ---------------------------------------------------------------------------- // wxLuaDebugData - Debug Info sent via socket to debugger client // ---------------------------------------------------------------------------- wxLuaDebugData::wxLuaDebugData() : wxLuaDebugDataItemArray(SortFunction) { } wxLuaDebugData::~wxLuaDebugData() { size_t idx; for (idx = 0; idx < Count(); ++idx) { const wxLuaDebugDataItem *pData = Item(idx); delete pData; } } wxLuaDebugData *wxLuaDebugData::Clone() { wxLuaDebugData *pCloneData = new wxLuaDebugData; if (pCloneData != NULL) { size_t idx; for (idx = 0; idx < Count(); ++idx) { const wxLuaDebugDataItem *pOldData = Item(idx); if (pOldData != NULL) pCloneData->Add(new wxLuaDebugDataItem(*pOldData)); } } return pCloneData; } int wxLuaDebugData::SortFunction(wxLuaDebugDataItem *elem1, wxLuaDebugDataItem *elem2 ) { return wxStrcmp(elem1->GetName(), elem2->GetName()); } // ---------------------------------------------------------------------------- // wxLuaInterface (local) // ---------------------------------------------------------------------------- wxLuaInterface::wxLuaInterface(lua_State *luaState) : m_luaState(luaState) { } wxLuaInterface::~wxLuaInterface() { size_t idx, idxMax = m_references.GetCount(); for (idx = 0; idx < idxMax; ++idx) { int iItem = m_references.Item(idx); tremove(m_luaState, iItem); } } int wxLuaInterface::GetStack(int nIndex, lua_Debug *luaDebug) { return lua_getstack(m_luaState, nIndex, luaDebug); } bool wxLuaInterface::GetInfo(const wxString &what, lua_Debug *luaDebug) { return (lua_getinfo(m_luaState, wx2lua(what), luaDebug) != 0); } wxString wxLuaInterface::GetLocal(lua_Debug *luaDebug, int index) { return lua2wx(lua_getlocal(m_luaState, luaDebug, index)); } void wxLuaInterface::GetGlobals() { lua_pushvalue(m_luaState, LUA_GLOBALSINDEX); } int wxLuaInterface::GetTop() { return lua_gettop(m_luaState); } int wxLuaInterface::Type(int index) { return lua_type(m_luaState, index); } double wxLuaInterface::ToNumber(int index) { return lua_tonumber(m_luaState, index); } int wxLuaInterface::ToBoolean(int index) { return lua_toboolean(m_luaState, index); } wxString wxLuaInterface::ToString(int index) { return lua2wx(lua_tostring(m_luaState, index)); } const void *wxLuaInterface::ToPointer(int index) { return lua_topointer(m_luaState, index); } bool wxLuaInterface::IsCFunction(int index) { return lua_iscfunction(m_luaState, index) != 0; } const void *wxLuaInterface::ToCFunction(int index) { return (const void *) lua_tocfunction(m_luaState, index); } const void *wxLuaInterface::ToUserData(int index) { return lua_touserdata(m_luaState, index); } int wxLuaInterface::GetTag(int index) { return ttag(m_luaState, index); } int wxLuaInterface::GetN(int index) { return luaL_getn(m_luaState, index); } int wxLuaInterface::Ref() { int nReference = tinsert(m_luaState, -1); m_references.Add(nReference); return nReference; } int wxLuaInterface::GetRef(int ref) { return tget(m_luaState, ref); } void wxLuaInterface::Pop(int count) { lua_pop(m_luaState, count); } void wxLuaInterface::PushNil() { lua_pushnil(m_luaState); } void wxLuaInterface::PushValue(int index) { lua_pushvalue(m_luaState, index); } int wxLuaInterface::Next(int index) { return lua_next(m_luaState, index); } wxLuaDebugData *wxLuaInterface::BuildStack() { wxLuaDebugData *pSortedList = new wxLuaDebugData(); int nIndex = 0; lua_Debug luaDebug; bool fFirst = true; while (GetStack(nIndex, &luaDebug) != 0) { if (GetInfo(wxT("Sln"), &luaDebug)) { wxString itemName; wxString source = lua2wx(luaDebug.source); // skip stack frames that do not have line number int currentLine = luaDebug.currentline; if (!fFirst || (currentLine != -1)) { if (currentLine == -1) currentLine = 0; if (luaDebug.name != NULL) itemName.Printf(_("function %s line %u"), luaDebug.name, currentLine); else itemName.Printf(_("line %u"), currentLine); wxLuaDebugDataItem *item = new wxLuaDebugDataItem(itemName, wxT(""), wxT(""), source, nIndex, 0); pSortedList->Add(item); fFirst = false; } } ++nIndex; } return pSortedList; } wxLuaDebugData *wxLuaInterface::BuildStackList(int nEntry) { wxLuaDebugData *pSortedList = new wxLuaDebugData(); if (pSortedList != NULL) { lua_Debug luaDebug; if (GetStack(nEntry, &luaDebug) != 0) { int idx = 1; wxString name = GetLocal(&luaDebug, idx); while (!name.IsEmpty()) { bool fIsTable = false; wxString type; wxString value; wxString source = lua2wx(luaDebug.source); switch (Type(-1)) { case LUA_TNIL: type = wxT("Nil"); value = wxT("nil"); break; case LUA_TBOOLEAN: type = wxT("Boolean"); value = MakeBoolean(ToBoolean(-1)); break; case LUA_TNUMBER: type = wxT("Number"); value = MakeNumber(ToNumber(-1)); break; case LUA_TSTRING: type = wxT("String"); value = ToString(-1); break; case LUA_TTABLE: type = wxT("Table"); value = GetTableInfo(-1); fIsTable = true; break; case LUA_TFUNCTION: if (IsCFunction(-1)) { type = wxT("C Function"); value.Printf(wxT("%p"), ToCFunction(-1)); } else { type = wxT("Lua Function"); value.Printf(wxT("%p"), ToPointer(-1)); } break; case LUA_TUSERDATA: type = wxT("User Data"); value = GetUserDataInfo(-1); break; case LUA_TLIGHTUSERDATA: type = wxT("Light User Data"); value = GetUserDataInfo(-1, false); break; case LUA_TTHREAD: type = wxT("Thread"); value.Printf(wxT("%p"), ToPointer(-1)); break; } int nRef = LUA_NOREF; if (fIsTable) { nRef = Ref(); } else Pop(1); wxLuaDebugDataItem *item = new wxLuaDebugDataItem(name, type, value, source, nRef, 0); pSortedList->Add(item); name = GetLocal(&luaDebug, ++idx); } } } return pSortedList; } wxLuaDebugData *wxLuaInterface::BuildTableList(int nRef, int nIndex) { wxLuaDebugData *pSortedList = new wxLuaDebugData(); if (pSortedList != NULL && GetRef(nRef) != 0) { int nTop = GetTop(); // start iterating PushNil(); while (Next(nTop) != 0) { bool fIsTable = false; wxString type; wxString value; wxString name; wxString source; // get the index switch (Type(-2)) { case LUA_TNIL: name = wxT("Nil"); break; case LUA_TBOOLEAN: name = MakeBoolean(ToBoolean(-2)); break; case LUA_TNUMBER: name = MakeNumber(ToNumber(-2)); break; case LUA_TSTRING: name = ToString(-2); break; case LUA_TTABLE: name = GetTableInfo(-2); break; case LUA_TFUNCTION: if (IsCFunction(-2)) name.Printf(wxT("%p"), ToCFunction(-2)); else name.Printf(wxT("%p"), ToPointer(-2)); break; case LUA_TUSERDATA: name = GetUserDataInfo(-2); break; case LUA_TLIGHTUSERDATA: name = GetUserDataInfo(-2, false); break; } // get the value switch (Type(-1)) { case LUA_TNIL: type = wxT("Nil"); value = wxT("nil"); break; case LUA_TBOOLEAN: value = MakeBoolean(ToBoolean(-1)); type = wxT("Boolean"); break; case LUA_TNUMBER: value = MakeNumber(ToNumber(-1)); type = wxT("Number"); break; case LUA_TSTRING: type = wxT("String"); value = ToString(-1); break; case LUA_TTABLE: type = wxT("Table"); value = GetTableInfo(-1); fIsTable = true; break; case LUA_TFUNCTION: if (IsCFunction(-1)) { type = wxT("C Function"); value.Printf(wxT("%p"), ToCFunction(-1)); } else { type = wxT("Lua Function"); value.Printf(wxT("%p"), ToPointer(-1)); } break; case LUA_TUSERDATA: type = wxT("User Data"); value = GetUserDataInfo(-1); break; case LUA_TLIGHTUSERDATA: type = wxT("Light User Data"); value = GetUserDataInfo(-1, false); break; case LUA_TTHREAD: type = wxT("Thread"); value.Printf(wxT("%p"), ToPointer(-1)); break; } int nRef = LUA_NOREF; if (fIsTable) nRef = Ref(); else Pop(1); wxLuaDebugDataItem *item = new wxLuaDebugDataItem(name, type, value, source, nRef, nIndex); pSortedList->Add(item); } // remove reference Pop(1); } return pSortedList; } wxString wxLuaInterface::GetTableInfo(int index) { wxString tableInfo; int nItems = GetN(index); const void *pItem = ToPointer(index); if (nItems == 0) tableInfo.Printf(wxT("%p"), pItem); else tableInfo.Printf(wxT("%p approx %u items)"), pItem, nItems); return tableInfo; } wxString wxLuaInterface::GetUserDataInfo(int index, bool full) { wxString userdatainfo; if (full) { wxString pTagName; int nTag = GetTag(index); if (nTag != TLUA_NOTAG) pTagName = lua2wx(... [truncated message content] |