Cursor and insert/delete work much better now, code streamlined, still

a minor problem left.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@507 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Karsten Ballüder
1998-08-12 08:33:34 +00:00
parent 3b9261289f
commit 3908d01eab
7 changed files with 249 additions and 176 deletions

View File

@@ -6,10 +6,16 @@
* $Id$ * * $Id$ *
* * * *
* $Log$ * $Log$
* Revision 1.1 1998/06/29 12:44:36 KB * Revision 1.2 1998/08/12 08:33:23 KB
* Added my wxWindows based layout engine to the repository. * Cursor and insert/delete work much better now, code streamlined, still
* It arranges text and graphics for display on a wxDC. * a minor problem left.
* This code is licensed under the LGPL. *
* Revision 1.6 1998/07/08 11:56:56 KB
* M compiles and runs on Solaris 2.5/gcc 2.8/c-client gso
*
* Revision 1.5 1998/06/27 20:07:18 KB
* several bug fixes for kbList
* started adding my layout stuff
* *
* Revision 1.1.1.1 1998/06/13 21:51:12 karsten * Revision 1.1.1.1 1998/06/13 21:51:12 karsten
* initial code * initial code
@@ -34,8 +40,11 @@
# pragma implementation "kbList.h" # pragma implementation "kbList.h"
#endif #endif
#include "kbList.h" #ifdef M_BASEDIR
# include "Mconfig.h"
#endif
#include "kbList.h"
kbListNode::kbListNode( void *ielement, kbListNode::kbListNode( void *ielement,
kbListNode *iprev, kbListNode *iprev,
@@ -178,11 +187,7 @@ kbList::insert(kbList::iterator & i, void *element)
else if(i.Node() == first) else if(i.Node() == first)
{ {
push_front(element); push_front(element);
return; i = first;
}
else if(i.Node() == last)
{
push_back(element);
return; return;
} }
i = kbList::iterator(new kbListNode(element, i.Node()->prev, i.Node())); i = kbList::iterator(new kbListNode(element, i.Node()->prev, i.Node()));

View File

@@ -4,14 +4,6 @@
* (C) 1998 by Karsten Ball<6C>der (Ballueder@usa.net) * * (C) 1998 by Karsten Ball<6C>der (Ballueder@usa.net) *
* * * *
* $Id$ * $Id$
* $Log$
* Revision 1.1 1998/06/29 12:44:36 KB
* Added my wxWindows based layout engine to the repository.
* It arranges text and graphics for display on a wxDC.
* This code is licensed under the LGPL.
*
* Revision 1.6 1998/06/27 20:06:10 KB
* Added my layout code.
* *
*******************************************************************/ *******************************************************************/
@@ -209,7 +201,7 @@ public:
bool empty(void) const bool empty(void) const
{ return first == NULL ; } { return first == NULL ; }
private: protected:
/// if true, list owns entries /// if true, list owns entries
bool ownsEntries; bool ownsEntries;
/// pointer to first element in list /// pointer to first element in list
@@ -217,6 +209,7 @@ private:
/// pointer to last element in list /// pointer to last element in list
kbListNode *last; kbListNode *last;
private:
/// forbid copy construction /// forbid copy construction
kbList(kbList const &foo); kbList(kbList const &foo);
/// forbid assignments /// forbid assignments
@@ -251,7 +244,7 @@ public: \
/* the cast is needed for MS VC++ 5.0 */ \ /* the cast is needed for MS VC++ 5.0 */ \
{ return (type *)((kbList::iterator *)this)->operator*() ; } \ { return (type *)((kbList::iterator *)this)->operator*() ; } \
}; \ }; \
inline name(bool ownsEntriesFlag = true) \ inline name(bool ownsEntriesFlag = FALSE) \
: kbList(ownsEntriesFlag) {} \ : kbList(ownsEntriesFlag) {} \
\ \
inline void push_back(type *element) \ inline void push_back(type *element) \
@@ -269,7 +262,7 @@ public: \
inline void insert(iterator & i, type *element) \ inline void insert(iterator & i, type *element) \
{ kbList::insert(i, (void *) element); } \ { kbList::insert(i, (void *) element); } \
\ \
void erase(iterator & i) \ inline void erase(iterator & i) \
{ kbList::erase(i); } \ { kbList::erase(i); } \
\ \
inline iterator begin(void) const \ inline iterator begin(void) const \
@@ -280,7 +273,22 @@ public: \
\ \
inline iterator tail(void) const \ inline iterator tail(void) const \
{ return kbList::tail(); } \ { return kbList::tail(); } \
} ~name() \
{ \
kbListNode *next; \
while ( first != NULL ) \
{ \
next = first->next; \
if(ownsEntries) \
delete typecast(first->element); \
delete first; \
first = next; \
} \
} \
private: \
inline type * typecast(void *ptr) \
{ return (type *) ptr; } \
}
#ifdef MCONFIG_H #ifdef MCONFIG_H
/// define the most commonly used list type once: /// define the most commonly used list type once:

View File

@@ -31,7 +31,7 @@ IMPLEMENT_APP(MyApp)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
enum ids{ ID_EDIT = 1, ID_ADD_SAMPLE, ID_CLEAR, ID_PRINT, ID_DPRINT, enum ids{ ID_EDIT = 1, ID_ADD_SAMPLE, ID_CLEAR, ID_PRINT, ID_DPRINT,
ID_WXLAYOUT_DEBUG, ID_QUIT, ID_CLICK, ID_HTML, ID_TEXT }; ID_WXLAYOUT_DEBUG, ID_QUIT, ID_CLICK, ID_HTML, ID_TEXT, ID_TEST };
IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame ) IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
@@ -58,6 +58,7 @@ IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
file_menu->Append( ID_DPRINT, "Direct Print"); file_menu->Append( ID_DPRINT, "Direct Print");
file_menu->Append( ID_TEXT, "Export Text"); file_menu->Append( ID_TEXT, "Export Text");
file_menu->Append( ID_HTML, "Export HTML"); file_menu->Append( ID_HTML, "Export HTML");
file_menu->Append( ID_TEST, "Test");
file_menu->Append( ID_QUIT, "Exit"); file_menu->Append( ID_QUIT, "Exit");
wxMenuBar *menu_bar = new wxMenuBar(); wxMenuBar *menu_bar = new wxMenuBar();
@@ -217,6 +218,15 @@ void MyFrame::OnCommand( wxCommandEvent &event )
case ID_CLICK: case ID_CLICK:
cerr << "Received click event." << endl; cerr << "Received click event." << endl;
break; break;
case ID_TEST:
{
Clear();
m_lwin->GetLayoutList().LineBreak();
m_lwin->GetLayoutList().Insert("abc");
m_lwin->GetLayoutList().LineBreak();
m_lwin->GetLayoutList().Insert("def");
break;
}
case ID_HTML: case ID_HTML:
{ {
wxLayoutExportObject *export; wxLayoutExportObject *export;

View File

@@ -22,12 +22,19 @@
#pragma implementation "wxllist.h" #pragma implementation "wxllist.h"
#endif #endif
#include "wxllist.h" // these two lines are for use in M:
#include "iostream.h" //#include "Mpch.h"
//#include "gui/wxllist.h"
#include <wx/dc.h> #include "wxllist.h"
#include <wx/postscrp.h>
#include <wx/print.h> #ifndef USE_PCH
# include "iostream.h"
# include <wx/dc.h>
# include <wx/postscrp.h>
# include <wx/print.h>
#endif
#define BASELINESTRETCH 12 #define BASELINESTRETCH 12
@@ -43,13 +50,13 @@ wxLayoutObjectBase::Debug(void)
<< GetSize(&bl).y << " bl=" << bl; << GetSize(&bl).y << " bl=" << bl;
} }
# define VAR(x) cerr << #x"=" << x << endl; # define WXL_VAR(x) cerr << #x"=" << x << endl;
# define DBG_POINT(p) cerr << #p << ": " << p.x << ',' << p.y << endl # define WXL_DBG_POINT(p) cerr << #p << ": " << p.x << ',' << p.y << endl
# define TRACE(f) cerr << #f":" << endl; # define WXL_TRACE(f) cerr << #f":" << endl;
#else #else
# define VAR(x) # define WXL_VAR(x)
# define DBG_POINT(p) # define WXL_DBG_POINT(p)
# define TRACE(f) # define WXL_TRACE(f)
#endif #endif
//-------------------------- wxLayoutObjectText //-------------------------- wxLayoutObjectText
@@ -99,8 +106,8 @@ wxLayoutObjectText::Debug(void)
//-------------------------- wxLayoutObjectIcon //-------------------------- wxLayoutObjectIcon
wxLayoutObjectIcon::wxLayoutObjectIcon(wxIcon *icon) wxLayoutObjectIcon::wxLayoutObjectIcon(wxIcon *icon)
: m_Icon(icon)
{ {
m_Icon = icon;
} }
void void
@@ -205,7 +212,7 @@ wxLayoutList::SetFont(int family, int size, int style, int weight,
if(size != -1) m_FontPtSize = size; if(size != -1) m_FontPtSize = size;
if(style != -1) m_FontStyle = style; if(style != -1) m_FontStyle = style;
if(weight != -1) m_FontWeight = weight; if(weight != -1) m_FontWeight = weight;
if(underline != -1) m_FontUnderline = underline; if(underline != -1) m_FontUnderline = underline != 0;
if(fg != NULL) m_ColourFG = fg; if(fg != NULL) m_ColourFG = fg;
if(bg != NULL) m_ColourBG = bg; if(bg != NULL) m_ColourBG = bg;
@@ -265,6 +272,9 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
CoordType baseLine = m_FontPtSize; CoordType baseLine = m_FontPtSize;
CoordType baseLineSkip = (BASELINESTRETCH * baseLine)/10; CoordType baseLineSkip = (BASELINESTRETCH * baseLine)/10;
// where to draw the cursor
wxPoint cursorPosition, cursorSize;
// we trace the objects' cursor positions so we can draw the cursor // we trace the objects' cursor positions so we can draw the cursor
wxPoint cursor = wxPoint(0,0); wxPoint cursor = wxPoint(0,0);
// the cursor position inside the object // the cursor position inside the object
@@ -295,7 +305,7 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
#endif #endif
dc.IsKindOf(CLASSINFO(wxPostScriptDC))) dc.IsKindOf(CLASSINFO(wxPostScriptDC)))
{ {
VAR(wxThePrintSetupData); WXL_VAR(wxThePrintSetupData);
dc.GetSize(&pageWidth, &pageHeight); dc.GetSize(&pageWidth, &pageHeight);
dc.StartDoc(_("Printing...")); dc.StartDoc(_("Printing..."));
@@ -314,7 +324,7 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
position.y = margins.right; position.y = margins.right;
position.x = margins.left; position.x = margins.left;
VAR(findObject); VAR(findCoords.x); VAR(findCoords.y); WXL_VAR(findObject); WXL_VAR(findCoords.x); WXL_VAR(findCoords.y);
// if the cursorobject is a cmd, we need to find the first // if the cursorobject is a cmd, we need to find the first
// printable object: // printable object:
while(cursorObject != end() while(cursorObject != end()
@@ -370,32 +380,32 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
long descent = 0l; long width, height; long descent = 0l; long width, height;
tobj = (wxLayoutObjectText *)*i; tobj = (wxLayoutObjectText *)*i;
String str = tobj->GetText(); String str = tobj->GetText();
VAR(m_CursorPosition.x); VAR(cursor.x); WXL_VAR(m_CursorPosition.x); WXL_VAR(cursor.x);
str = str.substr(0, cursorOffset); str = str.substr(0, cursorOffset);
VAR(str); WXL_VAR(str);
dc.GetTextExtent(Str(str), &width,&height, &descent); dc.GetTextExtent(Str(str), &width,&height, &descent);
VAR(height); WXL_VAR(height);
VAR(width); VAR(descent); WXL_VAR(width);
if(width < 1) width = 1; WXL_VAR(descent);
dc.DrawLine(position.x+width, cursorPosition = wxPoint(position.x+width,
position.y+(baseLineSkip-height), position.y+(baseLineSkip-height));
position.x+width, position.y+baseLineSkip); cursorSize = wxPoint(1, height);
//dc.DrawLine(position.x+width,
// position.y+(baseLineSkip-height),
// position.x+width, position.y+baseLineSkip);
} }
else else
{ {
if(type == WXLO_TYPE_LINEBREAK) if(type == WXLO_TYPE_LINEBREAK)
dc.DrawLine(0, position.y+baseLineSkip, 0, position.y+2*baseLineSkip); //dc.DrawLine(0, position.y+baseLineSkip, 0, position.y+2*baseLineSkip);
else
{ {
if(size.x == 0) cursorPosition = wxPoint(0, position.y);
{ cursorSize = wxPoint(1,baseLineSkip);
if(size.y == 0)
dc.DrawLine(position.x, position.y, position.x, position.y+baseLineSkip);
else
dc.DrawLine(position.x, position.y, position.x, position.y+size.y);
} }
else else
dc.DrawRectangle(position.x, position.y, size.x, size.y); {
cursorPosition = wxPoint(position.x, position.y);
cursorSize = wxPoint(size.x > 0 ? size.x : 1,size.y > 0 ? size.y : baseLineSkip);
} }
} }
} }
@@ -462,6 +472,12 @@ wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
i++; i++;
} }
dc.EndDoc(); dc.EndDoc();
// draw the cursor
if(m_Editable)
{
dc.DrawRectangle(cursorPosition.x, cursorPosition.y,
cursorSize.x, cursorSize.y);
}
m_MaxY = position.y; m_MaxY = position.y;
return foundObject; return foundObject;
} }
@@ -512,50 +528,80 @@ wxLayoutList::Debug(void)
// don't change this, I know how to optimise this and will do it real // don't change this, I know how to optimise this and will do it real
// soon (KB) // soon (KB)
/*
* FindObjectCursor:
* Finds the object belonging to a given cursor position cpos and
* returns an iterator to that object and stores the relative cursor
* position in offset.
*
* For linebreaks, the offset can be 0=before or 1=after.
*
* If the cpos coordinates don't exist, they are modified.
*/
wxLayoutObjectList::iterator wxLayoutObjectList::iterator
wxLayoutList::FindObjectCursor(wxPoint const &cpos, CoordType *offset) wxLayoutList::FindObjectCursor(wxPoint *cpos, CoordType *offset)
{ {
wxPoint cursor = wxPoint(0,0); // runs along the objects wxPoint object = wxPoint(0,0); // runs along the objects
CoordType width; CoordType width;
wxLayoutObjectList::iterator i; wxLayoutObjectList::iterator i;
#ifdef WXLAYOUT_DEBUG #ifdef WXLAYOUT_DEBUG
cerr << "Looking for object at " << cpos.x << ',' << cpos.y << cerr << "Looking for object at " << cpos->x << ',' << cpos->y <<
endl; endl;
#endif #endif
for(i = begin(); i != end() && cursor.y <= cpos.y; i++) for(i = begin(); i != end() && object.y <= cpos->y; i++)
{ {
width = 0; width = (**i).CountPositions();
if((*i)->GetType() == WXLO_TYPE_LINEBREAK) if(cpos->y == object.y) // a possible candidate
{ {
if(cpos.y == cursor.y && i != begin()) if((**i).GetType() ==WXLO_TYPE_LINEBREAK)
{ {
--i; if(cpos->x == object.x)
if(offset) *offset = i != end() ? (*i)->CountPositions() : 0; {
*offset = 0;
return i; return i;
} }
cursor.x = 0; cursor.y ++; *offset=1;
cpos->x = object.x;
return i;
} }
else if(cpos->x >= object.x && cpos->x <= object.x+width) // overlap
cursor.x += (width = (*i)->CountPositions());
if(cursor.y == cpos.y && (cursor.x > cpos.x ||
((*i)->GetType() != WXLO_TYPE_CMD && cursor.x == cpos.x))
) // found it ?
{ {
if(offset) if(offset) *offset = cpos->x-object.x;
*offset = cpos.x-(cursor.x-width); // 0==cursor before
// the object
#ifdef WXLAYOUT_DEBUG #ifdef WXLAYOUT_DEBUG
cerr << " found object at " << cursor.x-width << ',' << cerr << " found object at " << object.x << ',' <<
cursor.y << ", type:" << _t[(*i)->GetType()] <<endl; object.y << ", type:" << _t[(*i)->GetType()] <<endl;
#endif #endif
return i; return i;
} }
} }
// no overlap, increment coordinates
object.x += width;
if((**i).GetType() == WXLO_TYPE_LINEBREAK)
{
object.x = 0;
object.y++;
}
}
#ifdef WXLAYOUT_DEBUG #ifdef WXLAYOUT_DEBUG
cerr << " not found" << endl; cerr << " not found" << endl;
#endif #endif
return end(); // not found // return last object, coordinates of that one:
i = tail();
if(i == end())
return i;
if((**i).GetType()==WXLO_TYPE_LINEBREAK)
{
if(offset)
*offset = (cpos.x > object.x) : 1 : 0;
return i;
}
cpos->x = object.x; // would be the coordinate of next object
cpos->y = object.y;
cpos->x += width; // last object's width
if(*offset) *offset = cpos->x-object.x
return i; // not found
} }
wxLayoutObjectList::iterator wxLayoutObjectList::iterator
@@ -563,7 +609,7 @@ wxLayoutList::FindCurrentObject(CoordType *offset)
{ {
wxLayoutObjectList::iterator obj = end(); wxLayoutObjectList::iterator obj = end();
obj = FindObjectCursor(m_CursorPosition, offset); obj = FindObjectCursor(&m_CursorPosition, offset);
if(obj == end()) // not ideal yet if(obj == end()) // not ideal yet
{ {
obj = tail(); obj = tail();
@@ -665,68 +711,71 @@ wxLayoutList::MoveCursor(int dx, int dy)
void void
wxLayoutList::Delete(CoordType count) wxLayoutList::Delete(CoordType count)
{ {
TRACE(Delete); WXL_TRACE(Delete);
if(!m_Editable) if(!m_Editable)
return; return;
VAR(count); WXL_VAR(count);
CoordType offs, len; CoordType offs;
wxLayoutObjectList::iterator i; wxLayoutObjectList::iterator i;
do do
{ {
i = FindCurrentObject(&offs); i = FindCurrentObject(&offs);
startover: // ugly, but easiest way to do it
if(i == end()) if(i == end())
return; return; // we cannot delete anything more
#ifdef WXLAYOUT_DEBUG
cerr << "trying to delete: " << _t[(*i)->GetType()] << endl; /* Here we need to treat linebreaks differently.
#endif If offs==0 we are before the linebreak, otherwise behind. */
if((*i)->GetType() == WXLO_TYPE_LINEBREAK) if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
{
if(offs == 0)
{
m_MaxLine--; m_MaxLine--;
if((*i)->GetType() == WXLO_TYPE_TEXT) erase(i);
count--;
continue; // we're done
}
else // delete the object behind the linebreak
{
i++; // we increment and continue as normal
offs=0;
goto startover;
}
}
else if((*i)->GetType() == WXLO_TYPE_TEXT)
{ {
wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i; wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
len = tobj->CountPositions(); CoordType len = tobj->CountPositions();
// If we find the end of a text object, this means that we // If we find the end of a text object, this means that we
// have to delete from the object following it. // have to delete from the object following it.
if(offs == len) if(len == offs)
{ {
i++; i++;
if(i != end() && (*i)->GetType() == WXLO_TYPE_TEXT) offs = 0;
{ goto startover;
offs = 0; // delete from begin of next string
tobj = (wxLayoutObjectText *)*i;
len = tobj->CountPositions();
} }
else else if(len <= count) // delete this object
{
erase(i);
return;
}
}
if(len <= count) // delete this object
{ {
count -= len; count -= len;
erase(i); erase(i);
continue;
} }
else else
{ {
len = count; len = count;
VAR(offs); VAR(len);
tobj->GetText().erase(offs,len); tobj->GetText().erase(offs,len);
return; // we are done return; // we are done
} }
} }
else // delete the object else // all other objects: delete the object
{ {
len = (*i)->CountPositions(); CoordType len = (*i)->CountPositions();
erase(i); // after this, i is the iterator for the following object erase(i); // after this, i is the iterator for the following object
if(count > len) count = count > len ? count -= len : 0;
count -= len;
else
count = 0;
} }
} }
while(count && i != end()); while(count && i != end());
@@ -739,29 +788,30 @@ wxLayoutList::Insert(wxLayoutObjectBase *obj)
CoordType offs; CoordType offs;
wxLayoutObjectList::iterator i = FindCurrentObject(&offs); wxLayoutObjectList::iterator i = FindCurrentObject(&offs);
TRACE(Insert(obj)); WXL_TRACE(Insert(obj));
if(i == end()) if(i == end())
push_back(obj); push_back(obj);
else else if(offs == 0)
{ insert(i,obj);
// do we have to split a text object? // do we have to split a text object?
if((*i)->GetType() == WXLO_TYPE_TEXT && offs != 0 && offs != (*i)->CountPositions()) else if((*i)->GetType() == WXLO_TYPE_TEXT && offs != (*i)->CountPositions())
{ {
wxLayoutObjectText *tobj = (wxLayoutObjectText *) *i; wxLayoutObjectText *tobj = (wxLayoutObjectText *) *i;
#ifdef WXLAYOUT_DEBUG #ifdef WXLAYOUT_DEBUG
cerr << "text: '" << tobj->GetText() << "'" << endl; cerr << "text: '" << tobj->GetText() << "'" << endl;
VAR(offs); WXL_VAR(offs);
#endif #endif
String left = tobj->GetText().substr(0,offs); // get part before cursor String left = tobj->GetText().substr(0,offs); // get part before cursor
VAR(left); WXL_VAR(left);
tobj->GetText() = tobj->GetText().substr(offs,(*i)->CountPositions()-offs); // keeps the right half tobj->GetText() = tobj->GetText().substr(offs,(*i)->CountPositions()-offs); // keeps the right half
VAR(tobj->GetText()); WXL_VAR(tobj->GetText());
insert(i,obj); insert(i,obj);
insert(i,new wxLayoutObjectText(left)); // inserts before insert(i,new wxLayoutObjectText(left)); // inserts before
} }
else else
{ {
// all other cases, append after object:
wxLayoutObjectList::iterator j = i; // we want to apend after this object wxLayoutObjectList::iterator j = i; // we want to apend after this object
j++; j++;
if(j != end()) if(j != end())
@@ -769,7 +819,7 @@ wxLayoutList::Insert(wxLayoutObjectBase *obj)
else else
push_back(obj); push_back(obj);
} }
}
m_CursorPosition.x += obj->CountPositions(); m_CursorPosition.x += obj->CountPositions();
if(obj->GetType() == WXLO_TYPE_LINEBREAK) if(obj->GetType() == WXLO_TYPE_LINEBREAK)
m_MaxLine++; m_MaxLine++;
@@ -779,7 +829,7 @@ void
wxLayoutList::Insert(String const &text) wxLayoutList::Insert(String const &text)
{ {
wxLayoutObjectText *tobj = NULL; wxLayoutObjectText *tobj = NULL;
TRACE(Insert(text)); WXL_TRACE(Insert(text));
if(! m_Editable) if(! m_Editable)
return; return;
@@ -789,7 +839,7 @@ wxLayoutList::Insert(String const &text)
if(i != end() && (*i)->GetType() == WXLO_TYPE_TEXT) if(i != end() && (*i)->GetType() == WXLO_TYPE_TEXT)
{ // insert into an existing text object: { // insert into an existing text object:
TRACE(inserting into existing object); WXL_TRACE(inserting into existing object);
tobj = (wxLayoutObjectText *)*i ; tobj = (wxLayoutObjectText *)*i ;
wxASSERT(tobj); wxASSERT(tobj);
tobj->GetText().insert(offs,text); tobj->GetText().insert(offs,text);
@@ -798,7 +848,7 @@ wxLayoutList::Insert(String const &text)
{ {
wxLayoutObjectList::iterator j = i; wxLayoutObjectList::iterator j = i;
j--; j--;
TRACE(checking previous object); WXL_TRACE(checking previous object);
if(0 && j != end() && (*j)->GetType() == WXLO_TYPE_TEXT) if(0 && j != end() && (*j)->GetType() == WXLO_TYPE_TEXT)
{ {
tobj = (wxLayoutObjectText *)*i; tobj = (wxLayoutObjectText *)*i;
@@ -807,7 +857,7 @@ wxLayoutList::Insert(String const &text)
} }
else // insert a new text object else // insert a new text object
{ {
TRACE(creating new object); WXL_TRACE(creating new object);
Insert(new wxLayoutObjectText(text)); //FIXME not too optimal, slow Insert(new wxLayoutObjectText(text)); //FIXME not too optimal, slow
return; // position gets incremented in Insert(obj) return; // position gets incremented in Insert(obj)
} }

View File

@@ -14,7 +14,7 @@
#include "kbList.h" #include "kbList.h"
#include <wx/wx.h> #include "wx/wx.h"
// skip the following defines if embedded in M application // skip the following defines if embedded in M application
#ifdef M_BASEDIR #ifdef M_BASEDIR
@@ -47,8 +47,9 @@ typedef long CoordType;
class wxLayoutList; class wxLayoutList;
class wxLayoutObjectBase; class wxLayoutObjectBase;
/// Define a list type of wxLayoutObjectBase pointers. class wxDC;
KBLIST_DEFINE(wxLayoutObjectList, wxLayoutObjectBase); class wxColour;
class wxFont;
/** The base class defining the interface to each object which can be /** The base class defining the interface to each object which can be
part of the layout. Each object needs to draw itself and calculate part of the layout. Each object needs to draw itself and calculate
@@ -99,6 +100,10 @@ private:
void * m_UserData; void * m_UserData;
}; };
/// Define a list type of wxLayoutObjectBase pointers.
KBLIST_DEFINE(wxLayoutObjectList, wxLayoutObjectBase);
/// object for text block /// object for text block
class wxLayoutObjectText : public wxLayoutObjectBase class wxLayoutObjectText : public wxLayoutObjectBase
{ {
@@ -138,8 +143,9 @@ public:
bool draw = true); bool draw = true);
virtual wxPoint GetSize(CoordType *baseLine) const; virtual wxPoint GetSize(CoordType *baseLine) const;
wxLayoutObjectIcon(wxIcon *icon); wxLayoutObjectIcon(wxIcon *icon);
private: private:
wxIcon * m_Icon; wxIcon *m_Icon;
}; };
/// for export to html: /// for export to html:
@@ -294,7 +300,7 @@ protected:
bool m_Editable; bool m_Editable;
/// find the object to the cursor position and returns the offset /// find the object to the cursor position and returns the offset
/// in there /// in there
wxLayoutObjectList::iterator FindObjectCursor(wxPoint const &cpos, CoordType *offset = NULL); wxLayoutObjectList::iterator FindObjectCursor(wxPoint *cpos, CoordType *offset = NULL);
}; };

View File

@@ -24,22 +24,17 @@ wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
: wxScrolledWindow(parent) : wxScrolledWindow(parent)
{ {
m_ScrollbarsSet = false; m_ScrollbarsSet = false;
m_EventId = 0; m_EventId = -1;
} }
void void
wxLayoutWindow::OnMouse(wxMouseEvent& event) wxLayoutWindow::OnMouse(wxMouseEvent& event)
{ {
if(m_EventId == 0) // nothing to do if(m_EventId == -1) // nothing to do
return; return;
// this is unintuitive m_FindPos.x = event.GetX();
wxClientDC dc(this); m_FindPos.y = event.GetY();
PrepareDC( dc );
m_FindPos.x = dc.DeviceToLogicalX( event.GetX() );
m_FindPos.y = dc.DeviceToLogicalY( event.GetY() );
m_FoundObject = NULL; m_FoundObject = NULL;
#ifdef WXLAYOUT_DEBUG #ifdef WXLAYOUT_DEBUG
@@ -48,7 +43,7 @@ wxLayoutWindow::OnMouse(wxMouseEvent& event)
Refresh(); Refresh();
if(m_FoundObject) if(m_FoundObject)
{ {
if(m_EventId) if(m_EventId != -1)
{ {
wxCommandEvent commandEvent(wxEVENT_TYPE_MENU_COMMAND, m_EventId); wxCommandEvent commandEvent(wxEVENT_TYPE_MENU_COMMAND, m_EventId);
commandEvent.SetEventObject( this ); commandEvent.SetEventObject( this );
@@ -138,7 +133,7 @@ wxLayoutWindow::OnPaint( wxPaintEvent &WXUNUSED(event)w) // or: OnDraw(wxDC& dc
wxPaintDC dc( this ); // only when used as OnPaint for OnDraw we wxPaintDC dc( this ); // only when used as OnPaint for OnDraw we
PrepareDC( dc ); // can skip the first two lines PrepareDC( dc ); // can skip the first two lines
if(m_EventId) // look for keyclicks if(m_EventId != -1) // look for keyclicks
m_FoundObject = m_llist.Draw(dc,true,m_FindPos); m_FoundObject = m_llist.Draw(dc,true,m_FindPos);
else else
m_llist.Draw(dc); m_llist.Draw(dc);

View File

@@ -12,16 +12,12 @@
# pragma interface "wxlwindow.h" # pragma interface "wxlwindow.h"
#endif #endif
#include <wx/wx.h> #ifndef USE_PCH
# include <wx/wx.h>
#endif
#include "wxllist.h" #include "wxllist.h"
#define BROKEN_COMPILER
#ifdef BROKEN_COMPILER
# define virtual
#endif
class wxLayoutWindow : public wxScrolledWindow class wxLayoutWindow : public wxScrolledWindow
{ {
public: public:
@@ -38,18 +34,24 @@ public:
SetBackgroundColour( *GetLayoutList().GetDefaults()->GetBGColour()); SetBackgroundColour( *GetLayoutList().GetDefaults()->GetBGColour());
} }
//virtual void OnDraw(wxDC &dc); // callbacks
// NB: these functions are used as event handlers and must not be virtual
//void OnDraw(wxDC &dc);
void OnPaint(wxPaintEvent &WXUNUSED(event)); void OnPaint(wxPaintEvent &WXUNUSED(event));
virtual void OnMouse(wxMouseEvent& event); void OnMouse(wxMouseEvent& event);
virtual void OnChar(wxKeyEvent& event); void OnChar(wxKeyEvent& event);
#ifdef __WXMSW__
virtual long MSWGetDlgCode();
#endif //MSW
void UpdateScrollbars(void); void UpdateScrollbars(void);
void Print(void); void Print(void);
void Erase(void) void Erase(void) { m_llist.Clear(); Clear(); }
{ m_llist.Clear(); Clear(); }
void SetEventId(int id) { m_EventId = id; } void SetEventId(int id) { m_EventId = id; }
wxPoint const &GetClickPosition(void) const { return wxPoint const &GetClickPosition(void) const { return m_ClickPosition; }
m_ClickPosition; } virtual ~wxLayoutWindow() {}
virtual ~wxLayoutWindow() {} ;
private: private:
/// for sending events /// for sending events
wxWindow *m_Parent; wxWindow *m_Parent;
@@ -62,11 +64,8 @@ private:
wxPoint m_FindPos; wxPoint m_FindPos;
wxLayoutObjectBase *m_FoundObject; wxLayoutObjectBase *m_FoundObject;
wxPoint m_ClickPosition; wxPoint m_ClickPosition;
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
#ifdef BROKEN_COMPILER
#undef virtual
#endif
#endif #endif