From 974a5cccc1328714f824b2ba4e499fc1ef50f2b5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Karsten=20Ball=C3=BCder?= Date: Tue, 18 May 1999 15:05:29 +0000 Subject: [PATCH] Merged in from Mahogany. A bit better and safer. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2497 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- user/wxLayout/TODO | 5 ++++- user/wxLayout/wxllist.cpp | 9 ++++++++- user/wxLayout/wxllist.h | 19 +++++++++++++------ user/wxLayout/wxlwindow.cpp | 33 ++++++++++++++++++++++++++++++--- user/wxLayout/wxlwindow.h | 20 +++++++++++++++++++- 5 files changed, 74 insertions(+), 12 deletions(-) diff --git a/user/wxLayout/TODO b/user/wxLayout/TODO index 932d6e93d4..6d3df47b67 100644 --- a/user/wxLayout/TODO +++ b/user/wxLayout/TODO @@ -18,10 +18,13 @@ TODO - UNDO!! - replacement of llist in window + - selection highlighting is a bit broken +Improve speed! (See layout problem below!) The following two probs can probably be fixed by adding the RecalculateLayout() method: - Funny re-layout shows again in sample text. +Funny re-layout shows again in sample text. +(Gone after calling layout for all objects before drawing one.) Printing works again, but layout at begin of new page is corrupted. diff --git a/user/wxLayout/wxllist.cpp b/user/wxLayout/wxllist.cpp index 9c687de6d9..548e6dc268 100644 --- a/user/wxLayout/wxllist.cpp +++ b/user/wxLayout/wxllist.cpp @@ -598,6 +598,11 @@ wxLayoutLine::RecalculatePosition(wxLayoutList *llist) void wxLayoutLine::RecalculatePositions(int recurse, wxLayoutList *llist) { + //FIXME: is this really needed? We run Layout() anyway. + // Recursing here, drives computation time up exponentially, as + // each line will cause all following lines to be recalculated. + return; + wxASSERT(recurse >= 0); wxPoint pos = m_Position; CoordType height = m_Height; @@ -1243,7 +1248,8 @@ wxLayoutLine::Copy(wxLayoutList *llist, CoordType firstOffset, lastOffset; if(to == -1) to = GetLength(); - + if(from == to) return; + wxLOiterator first = FindObject(from, &firstOffset); wxLOiterator last = FindObject(to, &lastOffset); @@ -1562,6 +1568,7 @@ bool wxLayoutList::Insert(wxLayoutObject *obj) { wxASSERT(m_CursorLine); + if(! m_CursorLine) m_CursorLine = GetFirstLine(); SetUpdateRect(m_CursorScreenPos); SetUpdateRect(m_CursorScreenPos+m_CursorSize); m_CursorLine->Insert(m_CursorPos.x, obj); diff --git a/user/wxLayout/wxllist.h b/user/wxLayout/wxllist.h index 7edbcbbdff..267447465a 100644 --- a/user/wxLayout/wxllist.h +++ b/user/wxLayout/wxllist.h @@ -99,10 +99,13 @@ public: struct UserData { UserData() { m_refcount = 1; } - void IncRef(void) { m_refcount++; } - void DecRef(void) { m_refcount--; if(m_refcount == 0) delete this;} + inline void IncRef(void) { m_refcount++; } + inline void DecRef(void) { m_refcount--; if(m_refcount == 0) delete this;} + inline void SetLabel(const wxString &l) { m_label = l; } + inline const wxString & GetLabel(void) const { return m_label; } private: int m_refcount; + wxString m_label; protected: virtual ~UserData() { wxASSERT(m_refcount == 0); } /// prevents gcc from generating stupid warnings @@ -161,6 +164,7 @@ public: /** Tells the object about some user data. This data is associated with the object and will be deleted at destruction time. + It is reference counted. */ void SetUserData(UserData *data) { @@ -171,8 +175,11 @@ public: m_UserData->IncRef(); } - /** Return the user data. */ - void * GetUserData(void) const { if(m_UserData) m_UserData->IncRef(); return m_UserData; } + /** Return the user data. + Increments the object's reference count. When no longer needed, + caller must call DecRef() on the pointer returned. + */ + UserData * GetUserData(void) const { if(m_UserData) m_UserData->IncRef(); return m_UserData; } /** Makes a copy of this object. */ @@ -745,8 +752,8 @@ public: { MoveCursorHorizontally(-m_CursorPos.x); } /// Returns current cursor position. - wxPoint GetCursorPos(wxDC &dc) const { return m_CursorPos; } - wxPoint GetCursorPos() const { return m_CursorPos; } + const wxPoint &GetCursorPos(wxDC &dc) const { return m_CursorPos; } + const wxPoint &GetCursorPos() const { return m_CursorPos; } //@} diff --git a/user/wxLayout/wxlwindow.cpp b/user/wxLayout/wxlwindow.cpp index cc63534cb7..80d47b9f80 100644 --- a/user/wxLayout/wxlwindow.cpp +++ b/user/wxLayout/wxlwindow.cpp @@ -75,6 +75,7 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent) wxHSCROLL | wxVSCROLL | wxBORDER) { + SetStatusBar(NULL); // don't use statusbar m_Editable = false; m_doSendEvents = false; m_ViewStartX = 0; m_ViewStartY = 0; @@ -160,23 +161,33 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event) bool found; wxLayoutObject *obj = m_llist->FindObjectScreen(dc, findPos, &cursorPos, &found); + wxLayoutObject::UserData *u = obj ? obj->GetUserData() : NULL; //has the mouse only been moved? if(eventId == WXLOWIN_MENU_MOUSEMOVE) { // found is only true if we are really over an object, not just // behind it - if(found && obj && obj->GetUserData() != NULL) + if(found && u) { if(!m_HandCursor) SetCursor(wxCURSOR_HAND); m_HandCursor = TRUE; + if(m_StatusBar && m_StatusFieldLabel != -1) + { + const wxString &label = u->GetLabel(); + if(label.Length()) + m_StatusBar->SetStatusText(label, + m_StatusFieldLabel); + } } else { if(m_HandCursor) SetCursor(wxCURSOR_IBEAM); m_HandCursor = FALSE; + if(m_StatusBar && m_StatusFieldLabel != -1) + m_StatusBar->SetStatusText("", m_StatusFieldLabel); } if(event.LeftIsDown()) { @@ -198,6 +209,7 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event) m_Selecting = false; DoPaint(FALSE); } + if(u) u->DecRef(); return; } @@ -210,18 +222,24 @@ wxLayoutWindow::OnMouse(int eventId, wxMouseEvent& event) ScrollToCursor(); DoPaint(FALSE); // DoPaint suppresses flicker under GTK } + if(!m_doSendEvents) // nothing to do + { + if(u) u->DecRef(); return; + } // only do the menu if activated, editable and not on a clickable object if(eventId == WXLOWIN_MENU_RCLICK && IsEditable() - && (! obj || (obj && obj->GetUserData() == NULL)) - ) + && (! obj || u == NULL)) { PopupMenu(m_PopupMenu, m_ClickPosition.x, m_ClickPosition.y); + if(u) u->DecRef(); return; } + + if(u) u->DecRef(); // find the object at this position if(obj) { @@ -412,7 +430,10 @@ void wxLayoutWindow::OnKeyUp(wxKeyEvent& event) { if(event.KeyCode() == WXK_SHIFT && m_llist->IsSelecting()) + { m_llist->EndSelection(); + m_Selecting = false; + } event.Skip(); } @@ -605,6 +626,12 @@ wxLayoutWindow::InternalPaint(const wxRect *updateRect) ResetDirty(); m_ScrollToCursor = false; + if(m_StatusBar && m_StatusFieldCursor != -1) + { + wxString label; + label.Printf(_("L:%d C:%d"), m_llist->GetCursorPos().x+1, m_llist->GetCursorPos().y+1); + m_StatusBar->SetStatusText(label, m_StatusFieldCursor); + } } // change the range and position of scrollbars diff --git a/user/wxLayout/wxlwindow.h b/user/wxLayout/wxlwindow.h index fd913824c8..ead3310cf7 100644 --- a/user/wxLayout/wxlwindow.h +++ b/user/wxLayout/wxlwindow.h @@ -163,7 +163,19 @@ public: bool IsModified(void) const { return m_Modified; } /// Mark list as modified or unchanged. void SetModified(bool modified = true) { m_Modified = modified; } - + /** Tell window to update a wxStatusBar with UserData labels and + cursor positions. + @param bar wxStatusBar pointer + @param labelfield field to use in statusbar for URLs/userdata labels, or -1 to disable + @param cursorfield field to use for cursor position, or -1 to disable + */ + inline SetStatusBar(class wxStatusBar *bar, + int labelfield = -1, + int cursorfield = -1) + { + m_StatusBar = bar; m_StatusFieldLabel = labelfield; + m_StatusFieldCursor = cursorfield; + } protected: /// generic function for mouse events processing void OnMouse(int eventId, wxMouseEvent& event); @@ -211,6 +223,12 @@ private: wxMemoryDC *m_memDC; wxBitmap *m_bitmap; wxPoint m_bitmapSize; + /// A frame's statusbar to update + class wxStatusBar *m_StatusBar; + /// statusbar field for labels + int m_StatusFieldLabel; + /// statusbar field for cursor positions + int m_StatusFieldCursor; /// a pointer to a bitmap for the background wxBitmap *m_BGbitmap; DECLARE_EVENT_TABLE() -- 2.45.2