]> git.saurik.com Git - wxWidgets.git/commitdiff
Added my wxWindows based layout engine to the repository.
authorKarsten Ballüder <ballueder@usa.net>
Mon, 29 Jun 1998 12:44:36 +0000 (12:44 +0000)
committerKarsten Ballüder <ballueder@usa.net>
Mon, 29 Jun 1998 12:44:36 +0000 (12:44 +0000)
It arranges text and graphics for display on a wxDC.
This code is licensed under the LGPL.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@157 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

13 files changed:
user/wxLayout/Makefile.in [new file with mode: 0644]
user/wxLayout/Micon.xpm [new file with mode: 0644]
user/wxLayout/README [new file with mode: 0644]
user/wxLayout/kbList.cpp [new file with mode: 0644]
user/wxLayout/kbList.h [new file with mode: 0644]
user/wxLayout/wxLayout.cpp [new file with mode: 0644]
user/wxLayout/wxLayout.h [new file with mode: 0644]
user/wxLayout/wxllist.cpp [new file with mode: 0644]
user/wxLayout/wxllist.h [new file with mode: 0644]
user/wxLayout/wxlparser.cpp [new file with mode: 0644]
user/wxLayout/wxlparser.h [new file with mode: 0644]
user/wxLayout/wxlwindow.cpp [new file with mode: 0644]
user/wxLayout/wxlwindow.h [new file with mode: 0644]

diff --git a/user/wxLayout/Makefile.in b/user/wxLayout/Makefile.in
new file mode 100644 (file)
index 0000000..dbf3623
--- /dev/null
@@ -0,0 +1,26 @@
+# WXXT base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+# compile a library only
+RULE=bin
+
+# define library name
+BIN_TARGET=wxLayout
+# define library sources
+BIN_SRC=\
+wxLayout.cpp kbList.cpp wxlist.cpp wxlwindow.cpp wxlparser.cpp
+
+#define library objects
+BIN_OBJ=\
+wxLayout.o kbList.o wxllist.o wxlwindow.o wxlparser.o
+
+# additional things needed to link
+BIN_LINK=
+
+# additional things needed to compile
+ADD_COMPILE=
+
+# include the definitions now
+include ../../../template.mak
diff --git a/user/wxLayout/Micon.xpm b/user/wxLayout/Micon.xpm
new file mode 100644 (file)
index 0000000..153d3a4
--- /dev/null
@@ -0,0 +1,309 @@
+/* XPM */
+static char *Micon_xpm[] = {
+/* width height num_colors chars_per_pixel */
+"    64    48      254            2",
+/* colors */
+".. c #040207",
+".# c #6482b4",
+".a c #2a4471",
+".b c #9cc2d4",
+".c c #4c627f",
+".d c #94918e",
+".e c #0c243e",
+".f c #4c4a4a",
+".g c #3c63a8",
+".h c #7ca2ac",
+".i c #24447e",
+".j c #2c2c2c",
+".k c #5482cc",
+".l c #d4d0d0",
+".m c #99aab7",
+".n c #5c74b1",
+".o c #2c5287",
+".p c #1a2a4d",
+".q c #acdefc",
+".r c #646362",
+".s c #7491d0",
+".t c #bcc4bf",
+".u c #5273aa",
+".v c #b4b1aa",
+".w c #3d5583",
+".x c #828482",
+".y c #8c9490",
+".z c #6f7369",
+".A c #1c365c",
+".B c #041220",
+".C c #2c325c",
+".D c #94b6e4",
+".E c #3e4242",
+".F c #648edc",
+".G c #d4f2fc",
+".H c #cbd3d1",
+".I c #3c54a1",
+".J c #243244",
+".K c #4c69aa",
+".L c #7c8ba2",
+".M c #4c5d84",
+".N c #34497f",
+".O c #1c2228",
+".P c #6484c5",
+".Q c #6a7788",
+".R c #9ba09b",
+".S c #2c3634",
+".T c #acb6b4",
+".U c #141517",
+".V c #a0c4e8",
+".W c #515753",
+".X c #5c76cc",
+".Y c #1b2f51",
+".Z c #4472c4",
+".0 c #7c8a88",
+".1 c #5a6262",
+".2 c #a4aba6",
+".3 c #bcc8d5",
+".4 c #7494df",
+".5 c #84b2d4",
+".6 c #6784d9",
+".7 c #acd3e4",
+".8 c #304b72",
+".9 c #2c4c81",
+"#. c #3c5b93",
+"## c #5468bc",
+"#a c #b5bbb0",
+"#b c #1c3765",
+"#c c #444e44",
+"#d c #ecece8",
+"#e c #7ca3dc",
+"#f c #d4deda",
+"#g c #345495",
+"#h c #1c2641",
+"#i c #94a6cc",
+"#j c #243252",
+"#k c #a7acb5",
+"#l c #5c7ab3",
+"#m c #0a152d",
+"#n c #c4def0",
+"#o c #686e84",
+"#p c #a4a19e",
+"#q c #3e3c3a",
+"#r c #84aaee",
+"#s c #040a09",
+"#t c #3c6294",
+"#u c #7c929c",
+"#v c #3c5c9d",
+"#w c #4e6ead",
+"#x c #344458",
+"#y c #446bae",
+"#z c #696b6a",
+"#A c #547cbc",
+"#B c #789ae3",
+"#C c #112a44",
+"#D c #4f504b",
+"#E c #2c3140",
+"#F c #8c8688",
+"#G c #5e5c5c",
+"#H c #8c8c80",
+"#I c #cccccc",
+"#J c #4c6398",
+"#K c #c7cbc4",
+"#L c #5174b8",
+"#M c #3d558e",
+"#N c #2c3c5f",
+"#O c #acbad4",
+"#P c #3f495a",
+"#Q c #354e82",
+"#R c #6a8ac7",
+"#S c #767c84",
+"#T c #30374b",
+"#U c #b1c9e7",
+"#V c #1b315d",
+"#W c #537bcb",
+"#X c #c4bec0",
+"#Y c #243e6a",
+"#Z c #969892",
+"#0 c #7e858e",
+"#1 c #94b3f1",
+"#2 c #c2d4e8",
+"#3 c #141e35",
+"#4 c #acb2ac",
+"#5 c #c4ced0",
+"#6 c #2b4d8e",
+"#7 c #445ca2",
+"#8 c #2c3e6f",
+"#9 c #14243e",
+"a. c #f1fdfa",
+"a# c #8c9abc",
+"aa c #d7f9f9",
+"ab c #5a697e",
+"ac c #c7ebf7",
+"ad c #bceefc",
+"ae c #b4c2b4",
+"af c #889cf0",
+"ag c #d8d6c8",
+"ah c #748598",
+"ai c #b4d2fc",
+"aj c #4c5eb0",
+"ak c #3f4f64",
+"al c #8492bc",
+"am c #161d1e",
+"an c #5d7dcf",
+"ao c #5c86d6",
+"ap c #9cacc8",
+"aq c #6c92e6",
+"ar c #e4ecec",
+"as c #89b7ef",
+"at c #a6d0f8",
+"au c #e4e2e0",
+"av c #8c98a4",
+"aw c #ccdaec",
+"ax c #94bee4",
+"ay c #232b2b",
+"az c #1c2b43",
+"aA c #0c1c33",
+"aB c #99bcf7",
+"aC c #6c72bc",
+"aD c #7c766c",
+"aE c #a4a2b4",
+"aF c #6c7eac",
+"aG c #e4d6dc",
+"aH c #e4fefc",
+"aI c #84aeb4",
+"aJ c #b4b6bf",
+"aK c #345b9b",
+"aL c #bce2ef",
+"aM c #ccc6bc",
+"aN c #82a3ef",
+"aO c #7c7b77",
+"aP c #040c1e",
+"aQ c #6c7e94",
+"aR c #9ca69c",
+"aS c #acbebc",
+"aT c #a2cafa",
+"aU c #545e5f",
+"aV c #5c6a74",
+"aW c #cae6ee",
+"aX c #5c6e7c",
+"aY c #5474c6",
+"aZ c #fcfaf4",
+"a0 c #344672",
+"a1 c #446ec4",
+"a2 c #b4c4d4",
+"a3 c #313231",
+"a4 c #9cb2b4",
+"a5 c #345a8c",
+"a6 c #7496d4",
+"a7 c #0c1a24",
+"a8 c #444a47",
+"a9 c #343e3c",
+"b. c #dce6e4",
+"b# c #a9b2bc",
+"ba c #a6a6a3",
+"bb c #446a9c",
+"bc c #c4f2f8",
+"bd c #445667",
+"be c #727475",
+"bf c #6a7896",
+"bg c #9aa0a7",
+"bh c #9ec4fa",
+"bi c #545a61",
+"bj c #6474e0",
+"bk c #546674",
+"bl c #b8bcbd",
+"bm c #5d7cbf",
+"bn c #515255",
+"bo c #979a9f",
+"bp c #849cd0",
+"bq c #546a8f",
+"br c #d7d8d5",
+"bs c #688ada",
+"bt c #4f6ebe",
+"bu c #343e4c",
+"bv c #dafefc",
+"bw c #acd6fc",
+"bx c #b4b6b0",
+"by c #8c9a94",
+"bz c #203a44",
+"bA c #a4b6c8",
+"bB c #4c6a98",
+"bC c #040214",
+"bD c #5c74be",
+"bE c #4c5c98",
+"bF c #24325c",
+"bG c #8c8c8f",
+"bH c #4464a7",
+"bI c #2c457e",
+"bJ c #5c83c7",
+"bK c #34538a",
+"bL c #b4dff1",
+"bM c #7c92d4",
+"bN c #c4c4c0",
+"bO c #243759",
+"bP c #0c151e",
+"bQ c #9cb2d4",
+"bR c #6c8fd3",
+"bS c #546aab",
+"bT c #848c9f",
+"bU c #242420",
+"bV c #6c83c0",
+"bW c #343935",
+"bX c #848b89",
+"bY c #acaca6",
+"bZ c #c4cad0",
+"b0 c #445c90",
+"b1 c #243865",
+"b2 c #dce0dc",
+"b3 c #747b76",
+"b4 c #8cacee",
+"b5 c #0c0c08",
+"b6 c #446299",
+"b7 c #8493a4",
+/* pixels */
+"................................................................................................................................",
+"..................................bC....bC....bC..bC....bC..bCbCbCbC..bCbC..bC..bC..bC..bCbC..bC..bC....bC....bC................",
+"..#9#C#h#C.p.Y.Y.Y#j.Y.Y.Y#V#V#Vb1bFb1b1#8#Y.a.a#Q#Q.a.N#Q.abI.i.9bI#Q#MbK#M.wb0#M.9.N.N.N.9.abI.a#Y#Yb1b1#b#bb1b1b1#V#V#V#Vaz..",
+"..#h#C.p.p#9.Y.Y#j.AbObO.A.AbO.Ab1#Y#Y#8.a.aa0.N.8.w.w#QbK.w.ibI.9#6#Q#.#Mb0b0#J#MbK#M.NbK.N.9.NbI.N#YbIb1#Y#8#8bOb1bO#j#V#Caz..",
+"..#9.e#h#C.p.p.Y.YbO.A#b#N.a#8#Y#bb1#8#Y.Na0.9.8#Q.w.Mb0#Q#MbK.9bK#g#6.Kb6#J#J#wb0#M#MbKbK#Q#M.9bI.N.N.a.N.a.a.ab1b1#V.Y#V.Y.Y..",
+"..#9#C.p#h.p.p.p.Y#VbO#b.a.ia0.9#Q.N#YbI.a.N.N.N.w#Q.wb6b6b0b6#.#g#v#M.K#w#L.n.n#vbH#.bH.Ib6aK#MbK.9#Q#Q#Q#Q.a#Yb1.AbF#VbO.Y#j..",
+"..#h#h.p.p.p.Y.p#bbF#bb1#Y.a.8.N#Q#M#M#Q.N.9#QbK#M#Mb0b0.ubB.K.K#..K#v#w.nbmbV.nbHbS#w#7#w#vb0#.#M#Mb0#M#Q.9#Y#Yb1#Yb1b1.Y.Y.Y..",
+"..#h#9.p.p.p#V#V#b#b#Y#Y.a.ibI.N.w#Mb0b6#7#M#Q#QbK#.b6b6bq#l.n#LbHbH#y#L#R.s.4#AaY#w#w#L.K.KbH.g.KbH#v#M.9bI.i.8.a#Yb1.A.A.A#j..",
+"..#h#C.p.p.Y#V#V#bb1.abIbI#6.o.o#g.oaK#tbH.K.KbH#M.Iaj.K#w.n#R.P#Rbt#W#W.4bpb4aoanbsaobm#La1#L#A#L.ga5bK#g#g#Q.8#Y#bb1b1bOb1bO..",
+"...p.p.Y#V.Y#V.Ab1#YbI.9#Q#Q#M#M#7#7#M#v.M#J.K.K.nbS#MbH.nbm.#b4.s#Baq#Wb4aB#1aqaq#R.P.##l#RbmbD.K#7#J#J#.#Q.9.i.N.a#Y#Yb1.Aaz..",
+"..az#C#V#j#V.A#N#8.N.N.ibObz#T.J#E.J#T#Tbu.Y.8#..K.nbVbD#wbm.4a6aTb4aoaNaTaiasaNa6.n.m.3bZ#2bN.3aR#2#2.3#J#Q#MbK.8.a#8#b.AbO#j..",
+"..#h.p.p.Y.Yb1bO.ibI#g#Mbd#hambU.jbW.Sa3aybP.Y.9bHbH.ubm#BbM.P#rbhbc.qasbL.G.VbhaBbpbZaJbobxbl#I#a#abXbP#V.9#6.NbI#8#8#bbF#V#j..",
+"..az#C.Y.Y.Y#bb1.abI#Q.oaj#Pa3a3aya3a3bW.Eayb0.K.g#y.K#LanbRbhaTaxbLbvbLbvbvaLadaTai.mbobYba#Xbl.H#I#P#m#.#M#QbIbI#Y#Yb1#b#V#j..",
+"..az.p.p#VbObO#Y.a.N#g#g.I#xbW.j.ja3.E.Ebnbib0bmananbm#wanbs.4asacbLbvaHa.aHbvbc.7aIbY#p#pblbl#Kbe#F#k#9#..I#g#6.i#8#8b1b1.A#j..",
+"..#h#C.p.YbO#bb1a0bIbKbK#7#xaya3.jaya3#q.Wbn.J.wbD#Lbm.X#Bb4bhat.b#na.a.a.aZaHaHaW#k#a.vagbNaObl#I.vb3#3#w.K#7#v#M#QbIa0#Y#N#N..",
+"..#haz.p#V.YbO#Y#Y.N.9#g#7#P.EbUa8#q#D.f.f.fbi#hbB#LaY.n.P#R#e.5.7aLa.a.aZaZa.a.aS#5#p.d#p.t.l.HbYaObo.Y#w.Kb6#.#M.Na0.a#8#NbO..",
+"..#h#C.YbO#V#N#Y.8#Q#g#t##ak.j.W.f.Wbn#Gbe#zbnaU.M#Ra6#eaNb4bh.7bLaWa.aZaZaZa.br.H.2ba.H.T#fau.H.H#p.x#3#w.K#tb0#Q#Q.a#8#Nb1bO..",
+"..az#j#j.Ab1#N.a.8#Q#.bb##ak.Ebnbn.1.Ua8.zaO#z.xbubqbsbR.saqaN#1bw.7aaaHa.b.a.a4bZ#k#dbgbP.H#IbG#4bY#o#9#w.K#7b0#Q.8.a#8#NbObO..",
+"..az#j.Y.YbO#8.a.8#Q#7#t##bd.r#D#D.rbPaV#G#z.x.y#z.p.u#W.6#B#r#eaTaTaLaWaaaI#5#aau#XbraU#8.HbN.T.RbY#0#9#w.Kb6#M#Q#Qa0#Y#Y#N#N..",
+"..#h#j.YbOb1bO#Ya0.NbKa5aj.c.f#G#z.1#3.Mbe#zaO.x#pbT#.bmbsbs.F#1#easat.Gbc.hb.b2aragbgbPaC.3#k.v#4babe#9.KbH#7b0#Qak.a.i#N#Y#T..",
+"..az.Y#j.Y.Ab1#Y.8.N#gbK.IaX.r.raDaV.Bb0bfbeb3bab3#HazbBaYbsaqbRaf#1.DaB#na2#K#4b3.ybC.Yaf#k#Z.y.d#p#S#3#v#7#M#g.N.N.a#N#Y#NbO..",
+"..#h.p#C#jbFbO#8.a.NbK#.#7bk.z.zb3#H#9aKbm#J.y#Hbablb#.e.PaqbmbsaNaN#1aB#2bZ.x.2aub3.AbSbjapbobobo.rbn#9#v#gbK.9bI.a.a#Yb1bObO..",
+"..#haz.YbF#VbO#Y.abI#QaK.I.Q.z.WaO#za7b0an.ub#.R.y.R#XbXbEbtbJbR#Bbsb4.D.3.v#p#za3#s.ubJbj#u.WbWb3.Rbe#9#v#v#g.9bI#Yb1b1#b.A#j..",
+"..#h#C.p#C.Y#bbO#YbI.9.o.Iab#Zb3.x.da7bK#WbmalbTae.t#F#Gaz.nbsaqbJ.6#R#U#aaMbx#KbPbz#laoanb#ba.2.RbG#G#9#v#v#g.9bI.ab1#bbF#Vaz..",
+"..#haz.p.p#V#Vb1#Y.a#6bK#7bk.1#z#Z.y#m#.a1a1bq.LbX#HblbN.3#N.PaobJafbQ.3.tblbx.TazbB.X.kaYb7bG.d.x#ZaV#3bH#v#Q.NbI#8b1b1.A.Y.Y..",
+"..az#h#C.p#VbO#b#YbIbK#g#7aQ.d.y.RbX#mbK#y#ybt.#bZ#IaM.l.2bdbmanaobMap.t.2bY.2.ObO.s.X#W.6bX#F.yaOaD#G#9b6#7.I#Q.a.ab1#bbF.Y.Y..",
+"..#9#h.p.p#V#Vb1.a.NbK#..IaQ.xbob3aO#m.9#L.ZaY#w#iaJagaGbr#5.8aF.4a#blbN#Z#Z.WaP#l#l.6#WaY#0aO.y.xb3#PaA#7b6bK#QbI#8b1bO.A#V.Y..",
+"..#h.p#C#V.YbO#Y.abI.9aK.Ibf#D.1bYbY#mbK#ybt#ybHbSbT#aba.tbx#S.M#B.y#kbxbYbYaP.YbR#A.6bmbt.Lb3#z.W#Dbn#3bK#.#M#Q.N#Yb1b1#V.Yaz..",
+"..#h#C.p#V.p#b.A.a#Y#Q#..Ib7#kbe#4#pa7bK#ybH.g.gbHbfbZbN#4bNbgakah#Zbg#F.x.1#9bK.P#A.X.#btbTaO.W.r.ra8.e#Q.o#Q#Q.a.ab1bO.A.Yaz..",
+"..#h.p#h#C#VbOb1#YbI.9.o.I.L#H#Z.2.vaA#QbHaK.g.g#y#7#nbr#a.H.vaE.zaU#4blbebCbIaK#Lbm#LbJbtaXaO.z#z#G.EaA#g#Q.9bI.a.a#Nb1#jbO.Y..",
+"..#h#C#h#V.p#V.A.a#8.9.9.Iah#4bY#4bGbP#QaKaKaKaK#7#wbEbg.z.zay.E#a#K.2#ZbCbO#v#gbH.Xbb.ubDbk#z.r#c.f.E#9#Q#6bI.i#8b1#YbO.AbO.J..",
+"..#h.p#9.p.p#b.A#8#Y.9.9.I.0.R.2bN#XbP.NaK.IaK#v.IbS.KaQaR.Wbl#K.RbY.R.y#9#M#gaKbH.Kbb#yaCbk.r#Ga8#D#TaAbK#6.i.a#Y#bbObO.Y#jaz..",
+"..#9#9.p.p.Y#V.Ab1#YbI.9#7a#bn.Hb2#FaP.a.I#g#g#g#v#7bHb0.L.HbY.y.0#ZaObC.8b0#g#6aKbH#wbb#LaX#D#q.Ea3.UaAbK#QbI#Y#Y#bbO.AbO.Y.Y..",
+"..#9#h#h#C.p.Y#V#Y#Y#6.obEbk.H.2bUbe#m.a#g#g#Q#M#M#vaK#6bq#k.d.x.y#Z..az#M#v.o#6.o#v#L#tbSbda8bU.Ub5.O#3#6#6bI.ib1#bbF.Y#C.Yaz..",
+"..#9#9.p.p.p#Vb1#Y.N#6.o#Q#O.R.xaM.HaPa0bK#Q#Q#M#M#MbK#gb0akb3aO.xbX#9#x#v#g.N#6.9.wbH#yb0bn#D.f#q.j.U#3.N#6#8.i#b#b.Y.p.Y.paz..",
+"..#9#h#9.p.p#V#bb1#8bI#g.NbAb.br.t#H#m#Y#Q#g#Q.9.9.N#6.o#gb0avbG#Z...Y.w#g#6bIbIbIbK#v.K#Ma7#s#s....#haA#Q.NbI#Yb1#V#V#V.p.paz..",
+"..#9#9#9.p.p#VbO#Y#8#6.i#M.Q#z.H#f#K.B#Y#6.9.N.9bIbI.9.9#M#M#JbybP.B.Nb0.NbIbI#Y.ibI#vbH.wbubW.E.Sa3a7#m.o#Q#Y#Yb1#V#V#C.p.p.e..",
+"..#3#9#9#9.Y#V#VbF#Y#8#6ak#O#db2br.HaP#N.N#QbIbI.a#Y.i.8#M#Qa0.L.B.p#Q#Q.i.i.i#Y.ibI#Q#..c.E.ja3a3bWambP.N.9#Y#Y#b#b#V.p.p.p#9..",
+"..#3.e#9.p.p.Y.Yb1b1#Y#.#Ubgbl.T#S..aw#obI.a.a#8#Y#Y.a#YbI.Na0.8bO#8a0#Qa0#8b1#Y#Y#8#Q.ibO#Ta9a9bWa3ay#Eb1.a.ab1#V#V.Y.p.p.e#9..",
+"..#3#9.p#h#C.p.Y#Vb1#b#V.a.Y.Y.Y#CazbO.eb1#8#Y#b#bb1b1#8bI#Y.8.abIb1#Y.Nb1#Y#Y#Y#b#Y.9.8.8.C.JbO#j.Yaz#C.p.Y#bb1#V.p.p.p#C.e#9..",
+"..#9#9#9.p#9.p.Y.Y#V#b#bb1#8.i#8.a.a#Y#Y#Y#Yb1b1#b#bb1#N#Y#8b1#Y#Yb1#8#Yb1#b#b#b#bb1#Y.N.w.8.N.8#Q.8.i.a#b#Y#bbO#V.Y.p#C.p.p#9..",
+"..#3#9.e#9.p.p#9#C.Y#V#b#b#b#Y#Y#Y#Y#Y#Yb1b1bO#V.Y#j#Vb1b1bObObObO.Ab1#N.A.AbF#V#V#V#b#8.aa0.a.ibI.8#Y#Yb1#V#V#V#V.p.p#9.p.e#9..",
+"..#3#3#9.e.e.p.p.p.p#V.Y#b#b#Vb1#b#Yb1.A#V.Y.Y.Y.Y.Y.A#j.YbO#VbO.Y#jbO#b#j#j#V.Y#V#V#bb1#Y.a#Yb1.a#8b1b1#b.A#V#C.p.p.p.p.e.e#9..",
+"..#3aAaA#3#9.e.e#9#C#C.Y.p.Y#V#VbF#VbO.Y#j.p.p.Y#C#j.Y#j.Y#j.Y#j.Y.YbO.Y#j.Y.p.p.p.p.Y#VbOb1#NbObOb1b1.A#V.p.p.p#C.p#9#9#9.e#9..",
+"..#3#9.e#3aA#9.e#9.p.p.e.p.p.p#V#j.Y.Y.Y#9.p.p#9.Yaz.Yaz.paz.Y.paz.Y.Y#j#C.p#C.p#C#C.p#V#VbO#VbF#V#j#V#j.p.p.p#C.p#9#C#C#9.e#9..",
+"..#3aA#9aA#9aA.e#9.e#9#9.p.p.p.p#Caz.Y#C.p.p#9.p#C#Caz.p#Caz.Y#C.p#9#j.p#h.p#C#C#C.e.p#9.Y#j.Y.Y.p.p.p#C.p.p#9#9#9#9#9.e#9.e#3..",
+"..#3.e#3.e#3.e#9#9aA#9.e.e.e.p#C.p#h#Caz#9.p.p.p#h.Y#9.p.p#C.paz.p#h.Yaz#9.p#C.e.e.e.p.p#9.p.paz#C.paz.Y#9.p.e#9.e#9#9#9#9aA#9..",
+"......bC..bC..bCbCbCbCbCbCbC..bC....bC..bCbCbCbCbC..bC....bC......bC..bCbCbCbCbCbCbCbCbCbCbC....bC......bCbC..bC..bC..bC........"
+};
diff --git a/user/wxLayout/README b/user/wxLayout/README
new file mode 100644 (file)
index 0000000..bedb164
--- /dev/null
@@ -0,0 +1,50 @@
+
+README for wxLayout classes
+---------------------------
+
+All the source in this directory is copyrighted under the
+LGPL (GNU LIBRARY PUBLIC LICENSE), by Karsten Ballueder <ballueder@usa.net>.
+
+
+This is still work in progress, so if you want to make any significant
+changes, please get in touch with me before.
+
+There are three building blocks for richt text editing:
+
+wxllist :
+
+The wxLayoutList layout engine. It is a linked list of wxLayoutObjects
+which can arrange and display them on any wxDC. I am trying to keep
+this class as simple as possible, to be just the core layout
+engine. All "convenience" functions should be defined in classes built 
+on top of this.
+The wxLayoutList is derived from kbList, a double-linked list with an
+interface modelled after the STL list. As wxLayoutList depends on the
+way kbList treats iterators (i.e. the iterator value after an insert() 
+or erase() operation), I don't feel like rewriting it for wxList.
+
+wxlwindow :
+
+Contains a class wxLayoutWindow, derived from wxScrolledWindow which
+can directly be used as a rich-text display or editing window. The
+function responsible for keyboard handling is virtual and can be
+overloaded for different keybindings. wxLayoutWindow can sent fake
+menu-events to the application to react to the user clicking on
+objects.
+
+wxlparser:
+
+Contains several high level functions operating on
+wxLayoutList. Currently implemented is inserting of text (including
+linebreaks) and export of objects, text or html.
+Planned for the future is an html parser for importing html.
+
+
+
+wxLayout.cpp is a simple test program. It will export Text and HTML to
+stdout and demonstrate some of the features and bugs of wxLayoutList.
+
+There are still things to do and I'm working on them. :-)
+
+Karsten Ballueder <Ballueder@usa.ne>          29 June 1998
+
diff --git a/user/wxLayout/kbList.cpp b/user/wxLayout/kbList.cpp
new file mode 100644 (file)
index 0000000..7ff7409
--- /dev/null
@@ -0,0 +1,320 @@
+/*-*- c++ -*-********************************************************
+ * kbList.cc : a double linked list                                 *
+ *                                                                  *
+ * (C) 1998 by Karsten Ballüder (Ballueder@usa.net)                 *
+ *                                                                  *
+ * $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.1.1.1  1998/06/13 21:51:12  karsten
+ * initial code
+ *
+ * Revision 1.4  1998/05/24 14:48:00  KB
+ * lots of progress on Python, but cannot call functions yet
+ * kbList fixes again?
+ *
+ * Revision 1.3  1998/05/18 17:48:34  KB
+ * more list<>->kbList changes, fixes for wxXt, improved makefiles
+ *
+ * Revision 1.2  1998/05/14 16:39:31  VZ
+ *
+ * fixed SIGSEGV in ~kbList if the list is empty
+ *
+ * Revision 1.1  1998/05/13 19:02:11  KB
+ * added kbList, adapted MimeTypes for it, more python, new icons
+ *
+ *******************************************************************/
+
+#ifdef __GNUG__
+#   pragma implementation "kbList.h"
+#endif
+
+#include   "kbList.h"
+
+
+kbListNode::kbListNode( void *ielement,
+                        kbListNode *iprev,
+                        kbListNode *inext)
+{
+   next = inext;
+   prev = iprev;
+   if(prev)
+      prev->next = this;
+   if(next)
+      next->prev = this;
+   element = ielement;
+}
+
+kbListNode::~kbListNode()
+{
+   if(prev)
+      prev->next = next;
+   if(next)
+      next->prev = prev;
+}
+
+
+kbList::iterator::iterator(kbListNode *n)
+{
+   node = n;
+}
+
+void *
+kbList::iterator::operator*() 
+{
+   return node->element;
+}
+
+kbList::iterator &
+kbList::iterator::operator++()
+{
+   node  = node ? node->next : NULL;
+   return *this;
+}
+
+kbList::iterator &
+kbList::iterator::operator--()
+{
+   node = node ? node->prev : NULL; 
+   return *this;
+}
+kbList::iterator &
+kbList::iterator::operator++(int foo)
+{
+   return operator++();
+}
+
+kbList::iterator &
+kbList::iterator::operator--(int bar)
+{
+   return operator--();
+}
+
+
+bool
+kbList::iterator::operator !=(kbList::iterator const & i) const
+{
+   return node != i.node;
+}
+
+bool
+kbList::iterator::operator ==(kbList::iterator const & i) const
+{
+   return node == i.node;
+}
+
+kbList::kbList(bool ownsEntriesFlag)
+{
+   first = NULL;
+   last = NULL;
+   ownsEntries = ownsEntriesFlag;
+}
+
+void
+kbList::push_back(void *element)
+{
+   if(! first) // special case of empty list
+   {
+      first = new kbListNode(element);
+      last = first;
+      return;
+   }
+   else
+      last = new kbListNode(element, last);
+}
+
+void
+kbList::push_front(void *element)
+{
+   if(! first) // special case of empty list
+   {
+      push_back(element);
+      return;
+   }
+   else
+      first = new kbListNode(element, NULL, first);
+}
+
+void *
+kbList::pop_back(void)
+{
+   iterator i;
+   void *data;
+   bool ownsFlagBak = ownsEntries;
+   i = tail();
+   data = *i;
+   ownsEntries = false;
+   erase(i);
+   ownsEntries = ownsFlagBak;
+   return data;
+}
+
+void *
+kbList::pop_front(void)
+{
+   iterator i;
+   void *data;
+   bool ownsFlagBak = ownsEntries;
+   
+   i = begin();
+   data = *i;
+   ownsEntries = false;
+   erase(i);
+   ownsEntries = ownsFlagBak;
+   return data;
+   
+}
+
+void
+kbList::insert(kbList::iterator & i, void *element)
+{   
+   if(! i.Node())
+      return;
+   else if(i.Node() == first)
+   {
+      push_front(element);
+      return;
+   }
+   else if(i.Node() == last)
+   {
+      push_back(element);
+      return;
+   }
+   i = kbList::iterator(new kbListNode(element, i.Node()->prev, i.Node()));
+}
+
+void
+kbList::erase(kbList::iterator & i)
+{
+   kbListNode
+      *node = i.Node(),
+      *prev, *next;
+   
+   if(! node) // illegal iterator
+      return;
+
+   prev = node->prev;
+   next = node->next;
+   
+   // correct first/last:
+   if(node == first)
+      first = node->next;
+   if(node == last)  // don't put else here!
+      last = node->prev;
+
+   // build new links:
+   if(prev)
+      prev->next = next;
+   if(next)
+      next->prev = prev;
+
+   // delete this node and contents:
+   if(ownsEntries)
+      delete *i;
+   delete i.Node();
+
+   // change the iterator to next element:
+   i = kbList::iterator(next);
+}
+
+kbList::~kbList()
+{
+   kbListNode *next;
+
+   while ( first != NULL )
+   {
+      next = first->next;
+      if(ownsEntries)
+         delete first->element;
+      delete first;
+      first = next;
+   }
+}
+
+kbList::iterator
+kbList::begin(void) const
+{
+   return kbList::iterator(first);
+}
+
+kbList::iterator
+kbList::tail(void) const
+{
+   return kbList::iterator(last);
+}
+
+kbList::iterator
+kbList::end(void) const
+{
+   return kbList::iterator(NULL); // the one after the last
+}
+
+unsigned
+kbList::size(void) const // inefficient
+{
+   unsigned count = 0;
+   kbList::iterator i;
+   for(i = begin(); i != end(); i++, count++)
+      ;
+   return count;
+}
+
+
+
+
+
+
+
+#ifdef   KBLIST_TEST
+
+#include   <iostream.h>
+
+KBLIST_DEFINE(kbListInt,int);
+   
+int main(void)
+{
+   int
+      n, *ptr;
+   kbListInt
+      l;
+   kbListInt::iterator
+      i;
+   
+   for(n = 0; n < 10; n++)
+   {
+      ptr = new int;
+      *ptr = n*n;
+      l.push_back(ptr);
+   }
+
+   i = l.begin(); // first element
+   i++; // 2nd
+   i++; // 3rd
+   i++; // 4th, insert here:
+   ptr = new int;
+   *ptr = 4444;
+   l.insert(i,ptr);
+
+   // this cannot work, because l.end() returns NULL:
+   i = l.end(); // behind last
+   i--;  // still behind last
+   l.erase(i);  // doesn't do anything
+
+   // this works:
+   i = l.tail(); // last element
+   i--;
+   --i;
+   l.erase(i); // erase 3rd last element (49)
+   
+   for(i = l.begin(); i != l.end(); i++)
+      cout << *i << '\t' << *((int *)*i) << endl;
+
+   
+   return 0;
+}
+#endif
diff --git a/user/wxLayout/kbList.h b/user/wxLayout/kbList.h
new file mode 100644 (file)
index 0000000..2771578
--- /dev/null
@@ -0,0 +1,290 @@
+/*-*- c++ -*-********************************************************
+ * kbList.h : a double linked list                                  *
+ *                                                                  *
+ * (C) 1998 by Karsten Ballüder (Ballueder@usa.net)                 *
+ *                                                                  *
+ * $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.
+ *
+ *******************************************************************/
+
+#ifndef   KBLIST_H
+#   define   KBLIST_H
+
+#ifdef __GNUG__
+#   pragma interface "kbList.h"
+#endif
+
+#ifndef   NULL
+#   define   NULL   0
+#endif
+
+/**@name Double linked list implementation. */
+//@{
+
+/** kbListNode is a class used by kbList. It represents a single
+    element in the list. It is not intended for general use outside
+    kbList functions.
+*/
+struct kbListNode
+{
+   /// pointer to next node or NULL
+   struct kbListNode *next;
+   /// pointer to previous node or NULL
+   struct kbListNode *prev;
+   /// pointer to the actual data 
+   void *element;
+   /** Constructor - it automatically links the node into the list, if
+       the iprev, inext parameters are given.
+       @param ielement pointer to the data for this node (i.e. the data itself)
+       @param iprev if not NULL, use this as previous element in list
+       @param inext if not NULL, use this as next element in list
+   */
+   kbListNode( void *ielement,
+               kbListNode *iprev = NULL,
+               kbListNode *inext = NULL);
+   /// Destructor.
+   ~kbListNode();
+};
+
+/** The main list class, handling void pointers as data.
+  */
+
+class kbList
+{
+public:
+   /// An iterator class for kbList, just like for the STL classes.
+   class iterator
+   {
+   protected:
+      /// the node to which this iterator points
+      kbListNode *node;
+      friend class kbList;
+         public:
+      /** Constructor.
+          @param n if not NULL, the node to which to point
+      */
+      iterator(kbListNode *n = NULL);
+      /** Dereference operator.
+          @return the data pointer of the node belonging to this
+          iterator
+      */
+      void * operator*();
+
+      /** Increment operator - prefix, goes to next node in list.
+          @return itself
+      */
+      iterator & operator++();
+
+      /** Decrement operator - prefix, goes to previous node in list.
+          @return itself
+      */
+      iterator & operator--();
+
+      /** Increment operator - prefix, goes to next node in list.
+          @return itself
+      */
+      iterator & operator++(int); //postfix
+
+      /** Decrement operator - prefix, goes to previous node in list.
+          @return itself
+      */
+      iterator & operator--(int); //postfix
+
+      /** Comparison operator.
+          @return true if not equal.
+      */
+      bool operator !=(iterator const &) const; 
+
+      /* Comparison operator.
+         @return true if equal
+      */
+      bool operator ==(iterator const &) const; 
+
+      /** Returns a pointer to the node associated with this iterator.
+          This function is not for general use and should be
+          protected. However, if protected, it cannot be called from
+          derived classes' iterators. (Is this a bug in gcc/egcs?)
+          @return the node pointer
+      */
+      inline kbListNode * Node(void) const
+         { return node; }
+   };
+
+   /** Constructor.
+       @param ownsEntriesFlag if true, the list owns the entries and
+       will issue a delete on each of them when deleting them. If
+       false, the entries themselves will not get deleted. Do not use
+       this with array types!
+   */
+   kbList(bool ownsEntriesFlag = true);
+
+   /** Destructor.
+       If entries are owned, they will all get deleted from here.
+   */
+   ~kbList();
+
+   /** Tell list whether it owns objects. If owned, they can be
+       deleted by list. See the constructor for more details.
+       @param ownsflag if true, list will own entries
+   */
+   void ownsObjects(bool ownsflag = true)
+      { ownsEntries = ownsflag; }
+
+   /** Query whether list owns entries.
+       @return true if list owns entries
+   */
+   bool ownsObjects(void)
+      { return ownsEntries; }
+   
+   /** Add an entry at the end of the list.
+       @param element pointer to data
+   */
+   void push_back(void *element);
+
+   /** Add an entry at the head of the list.
+       @param element pointer to data
+   */
+   void push_front(void *element);
+
+   /** Get element from end of the list and delete it.
+       NOTE: In this case the element's data will not get deleted by
+       the list. It is the responsibility of the caller to free it.
+       @return the element data
+   */
+   void *pop_back(void);
+
+   /** Get element from head of the list and delete it.
+       NOTE: In this case the element's data will not get deleted by
+       the list. It is the responsibility of the caller to free it.
+       @return the element data
+   */
+   void *pop_front(void);
+
+   /** Insert an element into the list.
+       @param i an iterator pointing to the element, before which the new one should be inserted
+       @param element the element data
+   */
+   void insert(iterator & i, void *element);
+
+   /** Erase an element, move iterator to following element.
+       @param i iterator pointing to the element to be deleted
+   */
+   void erase(iterator & i);
+   
+   /* Get head of list.
+      @return iterator pointing to head of list
+   */
+   iterator begin(void) const;
+
+   /* Get end of list.
+   @return iterator pointing after the end of the list. This is an
+   invalid iterator which cannot be dereferenced or decremented. It is
+   only of use in comparisons. NOTE: this is different from STL!
+   @see tail
+   */
+   iterator end(void) const;
+
+   /* Get last element in list.
+      @return iterator pointing to the last element in the list.
+      @see end
+   */
+   iterator tail(void) const;
+
+   /* Get the number of elements in the list.
+      @return number of elements in the list
+   */
+   unsigned size(void) const;
+
+   /* Query whether list is empty.
+      @return true if list is empty
+   */
+   bool empty(void) const
+      { return first == NULL ; }
+
+private:
+   /// if true, list owns entries
+   bool        ownsEntries;
+   /// pointer to first element in list
+   kbListNode *first;
+   /// pointer to last element in list
+   kbListNode *last;
+
+   /// forbid copy construction
+   kbList(kbList const &foo);
+   /// forbid assignments
+   kbList& operator=(const kbList& foo);
+};
+
+/// just for backward compatibility, will be removed soon
+typedef kbList::iterator kbListIterator;
+/// cast an iterator to a pointer, compatibility only to be removed
+#define   kbListICast(type, iterator)   ((type *)*iterator)
+/// cast an iterator to a const pointer, compatibility only to be removed
+#define   kbListIcCast(type, iterator)   ((type const *)*iterator)
+
+/** Macro to define a kbList with a given name, having elements of
+    pointer to the given type. I.e. KBLIST_DEFINE(Int,int) would
+    create a kbListInt type holding int pointers.
+*/
+#define   KBLIST_DEFINE(name,type)   \
+class name : public kbList \
+{ \
+public: \
+   class iterator : public kbList::iterator \
+   { \
+   protected: \
+      inline iterator(kbList::iterator const & i) \
+         { node = i.Node(); } \
+      friend class name; \
+   public: \
+      inline iterator(kbListNode *n = NULL) \
+         : kbList::iterator(n) {} \
+      inline type * operator*() \
+         /* the cast is needed for MS VC++ 5.0 */ \
+         { return (type *)((kbList::iterator *)this)->operator*() ; } \
+   }; \
+   inline name(bool ownsEntriesFlag = true) \
+      : kbList(ownsEntriesFlag) {} \
+   \
+   inline void push_back(type *element) \
+      { kbList::push_back((void *)element); } \
+   \
+   inline void push_front(type *element) \
+      { kbList::push_front((void *)element); } \
+   \
+   inline type *pop_back(void) \
+      { return (type *) kbList::pop_back(); } \
+   \
+   inline type *pop_front(void) \
+      { return (type *) kbList::pop_front(); } \
+   \
+   inline void insert(iterator & i, type *element) \
+      { kbList::insert(i, (void *) element); } \
+   \
+   void erase(iterator & i) \
+      { kbList::erase(i); } \
+   \
+   inline iterator begin(void) const \
+      { return kbList::begin(); } \
+   \
+   inline iterator end(void) const \
+      { return kbList::end(); } \
+   \
+   inline iterator tail(void) const \
+      { return kbList::tail(); } \
+}
+
+#ifdef   MCONFIG_H
+/// define the most commonly used list type once:
+KBLIST_DEFINE(kbStringList, String);
+#endif
+
+#endif // KBLIST_H
diff --git a/user/wxLayout/wxLayout.cpp b/user/wxLayout/wxLayout.cpp
new file mode 100644 (file)
index 0000000..7aefb35
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * Program: wxLayout
+ * 
+ * Author: Karsten Ballüder
+ *
+ * Copyright: (C) 1998, Karsten Ballüder <Ballueder@usa.net>
+ *
+ */
+
+#ifdef __GNUG__
+#pragma implementation "wxLayout.h"
+#endif
+
+#include "wxLayout.h"
+#include "wx/textfile.h"
+
+
+#include   "Micon.xpm"
+
+// for testing only:
+#include   <stdio.h>
+
+//-----------------------------------------------------------------------------
+// main program
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_APP(MyApp)
+
+//-----------------------------------------------------------------------------
+// MyFrame
+//-----------------------------------------------------------------------------
+
+   enum ids{ ID_EDIT = 1, ID_ADD_SAMPLE, ID_CLEAR, ID_PRINT, ID_DPRINT,
+             ID_DEBUG, ID_QUIT, ID_CLICK, ID_HTML, ID_TEXT };
+
+
+IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
+
+   BEGIN_EVENT_TABLE(MyFrame,wxFrame)
+   EVT_MENU    (-1,       MyFrame::OnCommand)
+   EVT_COMMAND (-1,-1,    MyFrame::OnCommand)
+   EVT_CHAR    (wxLayoutWindow::OnChar)
+   END_EVENT_TABLE()
+
+   MyFrame::MyFrame(void) :
+      wxFrame( NULL, -1, "wxLayout", wxPoint(20,20), wxSize(600,360) )
+{
+   CreateStatusBar( 1 );
+  
+   SetStatusText( "wxLayout by Karsten Ballüder." );
+
+   wxMenu *file_menu = new wxMenu( "Menu 1" );
+   file_menu->Append( ID_CLEAR, "Clear");
+   file_menu->Append( ID_ADD_SAMPLE, "Example");
+   file_menu->Append( ID_EDIT, "Edit");
+   file_menu->Append( ID_DEBUG, "Debug");
+   file_menu->Append( ID_PRINT, "Print");
+   file_menu->Append( ID_DPRINT, "Direct Print");
+   file_menu->Append( ID_TEXT, "Export Text");
+   file_menu->Append( ID_HTML, "Export HTML");
+   file_menu->Append( ID_QUIT, "Exit");
+  
+   wxMenuBar *menu_bar = new wxMenuBar();
+   menu_bar->Append(file_menu, "File" );
+   menu_bar->Show( TRUE );
+  
+   SetMenuBar( menu_bar );
+
+   m_lwin = new wxLayoutWindow(this);
+   m_lwin->SetEventId(ID_CLICK);
+   m_lwin->GetLayoutList().SetEditable(true);
+   m_lwin->SetFocus();
+};
+
+void
+MyFrame::AddSampleText(wxLayoutList &llist)
+{
+
+   llist.SetFont(wxROMAN,24,wxNORMAL,wxNORMAL, false);
+
+   llist.Insert("The quick brown fox jumps over the lazy dog.");
+   llist.LineBreak();
+
+   llist.Insert("Hello ");
+   llist.Insert(new wxLayoutObjectIcon(new wxIcon(Micon_xpm,-1,-1)));
+   llist.Insert("World!");
+
+
+   llist.Insert("The quick brown fox jumps...");
+   llist.LineBreak();
+
+   llist.Insert("over the lazy dog.");
+   llist.SetFont(-1,-1,-1,-1,true);
+   llist.Insert("underlined");
+   llist.SetFont(-1,-1,-1,-1,false);
+   llist.SetFont(wxROMAN);
+   llist.Insert("This is ");
+   llist.SetFont(-1,-1,-1,wxBOLD);  llist.Insert("BOLD ");  llist.SetFont(-1,-1,-1,wxNORMAL);
+   llist.Insert("and ");
+   llist.SetFont(-1,-1,wxITALIC);
+   llist.Insert("italics ");
+   llist.SetFont(-1,-1,wxNORMAL);
+   llist.LineBreak();
+  
+   llist.Insert("and ");
+   llist.SetFont(-1,-1,wxSLANT);
+   llist.Insert("slanted");
+   llist.SetFont(-1,-1,wxNORMAL);
+   llist.Insert(" text.");
+   llist.LineBreak();
+
+   llist.Insert("and ");
+   llist.SetFont(-1,-1,-1,-1,-1,"blue");
+   llist.Insert("blue");
+   llist.SetFont(-1,-1,-1,-1,-1,"black");
+   llist.Insert("and ");
+   llist.SetFont(-1,-1,-1,-1,-1,"red","black");
+   llist.Insert("red on black");
+   llist.SetFont(-1,-1,-1,-1,-1,"black");
+   llist.Insert(" text.");
+   llist.LineBreak();
+
+   llist.SetFont(-1,-1,wxSLANT);
+   llist.Insert("Slanted");
+   llist.SetFont(-1,-1,wxNORMAL);
+   llist.Insert(" and normal text and ");
+   llist.SetFont(-1,-1,wxSLANT);
+   llist.Insert("slanted");
+   llist.SetFont(-1,-1,wxNORMAL);
+   llist.Insert(" again.");
+   llist.LineBreak();
+
+   // add some more text for testing:
+   llist.Insert("And here the source for the test program:");
+   llist.LineBreak();
+   llist.SetFont(wxTELETYPE,16);
+   char buffer[1024];
+   FILE *in = fopen("wxLayout.cpp","r");
+   if(in)
+   {
+      for(;;)
+      {
+         fgets(buffer,1024,in);
+         if(feof(in))
+            break;
+         llist.Insert(buffer);
+         llist.LineBreak();
+      }
+   }
+
+   m_lwin->Refresh();
+   m_lwin->UpdateScrollbars();
+}
+
+void
+MyFrame::Clear(void)
+{
+   m_lwin->Erase();
+   m_lwin->UpdateScrollbars();
+}
+
+/* test the editing */
+void MyFrame::Edit(void)
+{
+   wxLayoutList & llist = m_lwin->GetLayoutList();
+   m_lwin->SetEventId(ID_CLICK);
+  
+   llist.MoveCursor(0);
+   llist.MoveCursor(5);
+   llist.MoveCursor(0,2);
+   llist.Delete(2);
+   llist.MoveCursor(2);
+   llist.Insert("not all so ");
+   llist.LineBreak();
+   m_lwin->Refresh();
+}
+
+void MyFrame::OnCommand( wxCommandEvent &event )
+{
+   cerr << "id:" << event.GetId() << endl;
+   switch (event.GetId())
+   {
+   case ID_QUIT:
+      Close( TRUE );
+      break;
+   case ID_PRINT:
+      m_lwin->Print();
+      break;
+   case ID_DPRINT:
+   {
+      wxLayoutList llist;
+      AddSampleText(llist);
+      wxPostScriptDC   dc("layout.ps",true,this);
+      if (dc.Ok() && dc.StartDoc((char *)_("Printing message...")))
+      {
+         //dc.SetUserScale(1.0, 1.0);
+         llist.Draw(dc);
+         dc.EndDoc();
+      }
+   }
+   break;
+   case ID_EDIT:
+      Edit();
+      break;
+   case ID_ADD_SAMPLE:
+      AddSampleText(m_lwin->GetLayoutList());
+      break;
+   case ID_CLEAR:
+      Clear();
+      break;
+   case ID_DEBUG:
+      m_lwin->GetLayoutList().Debug();
+      break;
+   case ID_CLICK:
+      cerr << "Received click event." << endl;
+      break;
+   case ID_HTML:
+   {
+      wxLayoutExportObject *export;
+      wxLayoutList::iterator i = m_lwin->GetLayoutList().begin();
+
+      while((export = wxLayoutExport(m_lwin->GetLayoutList(),
+                                     i,WXLO_EXPORT_AS_HTML)) != NULL)
+      {
+         if(export->type == WXLO_EXPORT_HTML)
+            cout << *(export->content.text);
+         else
+            cout << "<!--UNKNOWN OBJECT>";
+         delete export;
+      }
+   }
+   break;
+   case ID_TEXT:
+   {
+      wxLayoutExportObject *export;
+      wxLayoutList::iterator i = m_lwin->GetLayoutList().begin();
+
+      while((export = wxLayoutExport(m_lwin->GetLayoutList(),
+                                     i,WXLO_EXPORT_AS_TEXT)) != NULL)
+      {
+         if(export->type == WXLO_EXPORT_TEXT)
+            cout << *(export->content.text);
+         else
+            cout << "<!--UNKNOWN OBJECT>";
+         delete export;
+      }
+   }
+   break;
+   }
+};
+
+
+//-----------------------------------------------------------------------------
+// MyApp
+//-----------------------------------------------------------------------------
+
+MyApp::MyApp(void) : 
+   wxApp( )
+{
+};
+
+bool MyApp::OnInit(void)
+{
+   wxFrame *frame = new MyFrame();
+   frame->Show( TRUE );
+   wxSetAFMPath("/usr/local/src/wxWindows/misc/afm/");
+   return TRUE;
+};
+
+
+
+
+
diff --git a/user/wxLayout/wxLayout.h b/user/wxLayout/wxLayout.h
new file mode 100644 (file)
index 0000000..251e382
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+
+#ifndef __WXLAYOUTH__
+#define __WXLAYOUTH__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/wx.h"
+
+#include "wxllist.h"
+#include "wxlwindow.h"
+#include "wxlparser.h"
+
+//-----------------------------------------------------------------------------
+// derived classes
+//-----------------------------------------------------------------------------
+
+class MyFrame;
+class MyApp;
+
+//-----------------------------------------------------------------------------
+// MyFrame
+//-----------------------------------------------------------------------------
+
+class MyFrame: public wxFrame
+{
+  DECLARE_DYNAMIC_CLASS(MyFrame)
+
+  public:
+  
+   MyFrame(void);
+   void Edit(void);
+   void AddSampleText(wxLayoutList &llist);
+   void Clear(void);
+   void OnCommand( wxCommandEvent &event );
+   DECLARE_EVENT_TABLE()
+
+private:
+   wxLayoutWindow  *m_lwin;
+   
+};
+
+//-----------------------------------------------------------------------------
+// MyApp
+//-----------------------------------------------------------------------------
+
+class MyApp: public wxApp
+{
+  public:
+  
+    MyApp(void);
+    virtual bool OnInit(void);
+};
+
+#endif // __WXCONVERTH__
diff --git a/user/wxLayout/wxllist.cpp b/user/wxLayout/wxllist.cpp
new file mode 100644 (file)
index 0000000..04da4bb
--- /dev/null
@@ -0,0 +1,789 @@
+/*-*- c++ -*-********************************************************
+ * wxFTCanvas: a canvas for editing formatted text                  *
+ *                                                                  *
+ * (C) 1998 by Karsten Ballüder (Ballueder@usa.net)                 *
+ *                                                                  *
+ * $Id$       *
+ *******************************************************************/
+
+/*
+  - each Object knows its size and how to draw itself
+  - the list is responsible for calculating positions
+  - the draw coordinates for each object are the top left corner
+  - coordinates only get calculated when things get redrawn
+  - during redraw each line gets iterated over twice, first just
+    calculating baselines and positions, second to actually draw it
+  - the cursor position is the position before an object, i.e. if the
+    buffer starts with a text-object, cursor 0,0 is just before the
+    first character
+*/
+
+#ifdef __GNUG__
+#pragma implementation "wxllist.h"
+#endif
+
+#include   "wxllist.h"
+#include   "iostream"
+
+#define   VAR(x)   cerr << #x"=" << x << endl;
+#define   DBG_POINT(p)   cerr << #p << ": " << p.x << ',' << p.y << endl
+#define   TRACE(f)   cerr << #f":" << endl;
+
+#ifdef DEBUG
+static const char *_t[] = { "invalid", "text", "cmd", "icon",
+                             "linebreak"};
+
+void
+wxLayoutObjectBase::Debug(void)
+{
+   CoordType bl = 0;
+   cerr << _t[GetType()] << ": size=" << GetSize(&bl).x << ","
+        << GetSize(&bl).y << " bl=" << bl; 
+}
+#endif
+
+//-------------------------- wxLayoutObjectText
+
+wxLayoutObjectText::wxLayoutObjectText(const wxString &txt)
+{
+   m_Text = txt;
+   m_Width = 0;
+   m_Height = 0;
+}
+
+
+wxPoint
+wxLayoutObjectText::GetSize(CoordType *baseLine) const
+{
+   if(baseLine) *baseLine = m_BaseLine;
+   return wxPoint(m_Width, m_Height);
+}
+
+void
+wxLayoutObjectText::Draw(wxDC &dc, wxPoint position, CoordType baseLine,
+                    bool draw)
+{
+   long descent = 0l;
+   dc.GetTextExtent(m_Text,&m_Width, &m_Height, &descent);
+   //FIXME: wxGTK does not set descent to a descent value yet.
+   if(descent == 0)
+      descent = (2*m_Height)/10;  // crude fix
+   m_BaseLine = m_Height - descent;
+   position.y += baseLine-m_BaseLine;
+   if(draw)
+      dc.DrawText(m_Text,position.x,position.y);
+#   ifdef   DEBUG
+//   dc.DrawRectangle(position.x, position.y, m_Width, m_Height);
+#   endif
+}
+
+#ifdef DEBUG
+void
+wxLayoutObjectText::Debug(void)
+{
+   wxLayoutObjectBase::Debug();
+   cerr << " `" << m_Text << '\'';
+}
+#endif
+
+//-------------------------- wxLayoutObjectIcon
+
+wxLayoutObjectIcon::wxLayoutObjectIcon(wxIcon *icon)
+{
+   m_Icon = icon;
+}
+
+void
+wxLayoutObjectIcon::Draw(wxDC &dc, wxPoint position, CoordType baseLine,
+                    bool draw)
+{
+   position.y += baseLine - m_Icon->GetHeight();
+   if(draw)
+      dc.DrawIcon(m_Icon,position.x,position.y);
+}
+
+wxPoint
+wxLayoutObjectIcon::GetSize(CoordType *baseLine) const
+{
+   wxASSERT(baseLine);
+   *baseLine = m_Icon->GetHeight();
+   return wxPoint(m_Icon->GetWidth(), m_Icon->GetHeight());
+}
+
+//-------------------------- wxLayoutObjectCmd
+
+
+wxLayoutObjectCmd::wxLayoutObjectCmd(int size, int family, int style, int
+                           weight, bool underline,
+                           wxColour const *fg, wxColour const *bg)
+   
+{
+   m_font = new wxFont(size,family,style,weight,underline);
+   m_ColourFG = fg;
+   m_ColourBG = bg;
+}
+
+wxLayoutObjectCmd::~wxLayoutObjectCmd()
+{
+   delete m_font;
+}
+
+wxLayoutStyleInfo *
+wxLayoutObjectCmd::GetStyle(void) const
+{
+   wxLayoutStyleInfo *si = new wxLayoutStyleInfo();
+
+
+   si->size = m_font->GetPointSize();
+   si->family = m_font->GetFamily();
+   si->style = m_font->GetStyle();
+   si->underline = m_font->GetUnderlined();
+   si->weight = m_font->GetWeight();
+
+   si->fg_red = m_ColourFG->Red();
+   si->fg_green = m_ColourFG->Green();
+   si->fg_blue = m_ColourFG->Blue();
+   si->bg_red = m_ColourBG->Red();
+   si->bg_green = m_ColourBG->Green();
+   si->bg_blue = m_ColourBG->Blue();
+
+   return si;
+}
+
+void
+wxLayoutObjectCmd::Draw(wxDC &dc, wxPoint position, CoordType lineHeight,
+                   bool draw)
+{
+   wxASSERT(m_font);
+   // this get called even when draw==false, so that recalculation
+   // uses right font sizes
+   dc.SetFont(m_font);
+   if(m_ColourFG)
+      dc.SetTextForeground(*m_ColourFG);
+   if(m_ColourBG)
+      dc.SetTextBackground(*m_ColourBG);
+}
+
+//-------------------------- wxwxLayoutList
+
+wxLayoutList::wxLayoutList()
+{
+   Clear();
+}
+
+wxLayoutList::~wxLayoutList()
+{
+}
+
+
+void
+wxLayoutList::LineBreak(void)
+{
+   Insert(new wxLayoutObjectLineBreak);
+   m_CursorPosition.x = 0; m_CursorPosition.y++;
+}
+
+void
+wxLayoutList::SetFont(int family, int size, int style, int weight,
+                      int underline, wxColour const *fg,
+                      wxColour const *bg)
+{
+   if(family != -1)    m_FontFamily = family;
+   if(size != -1)      m_FontPtSize = size;
+   if(style != -1)     m_FontStyle = style;
+   if(weight != -1)    m_FontWeight = weight;
+   if(underline != -1) m_FontUnderline = underline;
+
+   if(fg != NULL)     m_ColourFG = fg;
+   if(bg != NULL)     m_ColourBG = bg;
+   
+   Insert(
+      new wxLayoutObjectCmd(m_FontPtSize,m_FontFamily,m_FontStyle,m_FontWeight,m_FontUnderline,
+                       m_ColourFG, m_ColourBG));
+}
+
+void
+wxLayoutList::SetFont(int family, int size, int style, int weight,
+                      int underline, char const *fg, char const *bg)
+{
+   wxColour const
+      * cfg = NULL,
+      * cbg = NULL;
+
+   if( fg )
+      cfg = wxTheColourDatabase->FindColour(fg);
+   if( bg )
+      cbg = wxTheColourDatabase->FindColour(bg);
+   
+   SetFont(family,size,style,weight,underline,cfg,cbg);
+}
+
+
+/// for access by wxLayoutWindow:
+void
+wxLayoutList::GetSize(CoordType *max_x, CoordType *max_y,
+                      CoordType *lineHeight)
+{
+   wxASSERT(max_x); wxASSERT(max_y); wxASSERT(lineHeight);
+   *max_x = m_MaxX;
+   *max_y = m_MaxY;
+   *lineHeight = m_LineHeight;
+}
+
+wxLayoutObjectBase *
+wxLayoutList::Draw(wxDC &dc, bool findObject, wxPoint const &findCoords)
+{
+   wxLayoutObjectList::iterator i;
+
+   // in case we need to look for an object
+   wxLayoutObjectBase *foundObject = NULL;
+   
+   // first object in current line
+   wxLayoutObjectList::iterator headOfLine;
+
+   // do we need to recalculate current line?
+   bool recalculate = false;
+
+   // do we calculate or draw? Either true or false.
+   bool draw = false;
+   // drawing parameters:
+   wxPoint position = wxPoint(0,0);
+   wxPoint position_HeadOfLine;
+   CoordType baseLine = m_FontPtSize;
+   CoordType baseLineSkip = (12 * baseLine)/10;
+
+   // we trace the objects' cursor positions so we can draw the cursor
+   wxPoint cursor = wxPoint(0,0);
+   // the cursor position inside the object
+   CoordType cursorOffset = 0;
+   // object under cursor
+   wxLayoutObjectList::iterator cursorObject = FindCurrentObject(&cursorOffset);
+   
+   // queried from each object:
+   wxPoint       size = wxPoint(0,0);
+   CoordType     objBaseLine = baseLine;
+   wxLayoutObjectType type;
+
+   VAR(findObject); VAR(findCoords.x); VAR(findCoords.y);
+   // if the cursorobject is a cmd, we need to find the first
+   // printable object:
+   while(cursorObject != end()
+         && (*cursorObject)->GetType() == WXLO_TYPE_CMD)
+      cursorObject++;
+
+   headOfLine = begin();
+   position_HeadOfLine = position;
+
+   // setting up the default:
+   dc.SetTextForeground( *wxBLACK );
+   dc.SetFont( *wxNORMAL_FONT );
+
+   // we calculate everything for drawing a line, then rewind to the
+   // begin of line and actually draw it
+   i = begin();
+   for(;;)
+   {
+      recalculate = false;
+
+      if(i == end())
+         break;
+      type = (*i)->GetType();
+
+      // to initialise sizes of objects, we need to call Draw
+      (*i)->Draw(dc, position, baseLine, draw);
+
+      // update coordinates for next object:
+      size = (*i)->GetSize(&objBaseLine);
+      if(findObject && draw)  // we need to look for an object
+      {
+         if(findCoords.y >= position.y
+            && findCoords.y <= position.y+size.y
+            && findCoords.x >= position.x
+            && findCoords.x <= position.x+size.x)
+         {
+            foundObject = *i;
+            findObject = false; // speeds things up
+         }
+      }
+      // draw the cursor
+      if(m_Editable && draw && i == cursorObject)
+      {
+         if(type == WXLO_TYPE_TEXT) // special treatment
+         {
+            long descent = 0l; long width, height;
+            wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
+            wxString  str = tobj->GetText();
+            VAR(m_CursorPosition.x); VAR(cursor.x);
+            str = str.substr(0, cursorOffset);
+            VAR(str);
+            dc.GetTextExtent(str, &width,&height, &descent);
+            VAR(height);
+            VAR(width); VAR(descent);
+            dc.DrawLine(position.x+width,
+                        position.y+(baseLineSkip-height),
+                        position.x+width, position.y+baseLineSkip);
+         }
+         else
+         {
+            if(type == WXLO_TYPE_LINEBREAK)
+                dc.DrawLine(0, position.y+baseLineSkip, 0, position.y+2*baseLineSkip);
+            else
+            {
+               if(size.x == 0)
+               {
+                  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
+                  dc.DrawRectangle(position.x, position.y, size.x, size.y);
+            }
+         }
+      }
+
+      // calculate next object's position:
+      position.x += size.x;
+      
+      // do we need to increase the line's height?
+      if(size.y > baseLineSkip)
+      {
+         baseLineSkip = size.y;
+         recalculate = true;
+      }
+      if(objBaseLine > baseLine)
+      {
+         baseLine = objBaseLine;
+         recalculate = true;
+      }
+
+      // now check whether we have finished handling this line:
+      if(type == WXLO_TYPE_LINEBREAK || i == tail())
+      {
+         if(recalculate)  // do this line again
+         {
+            position.x = position_HeadOfLine.x;
+            i = headOfLine;
+            continue;
+         }
+
+         if(! draw) // finished calculating sizes
+         {  // do this line again, this time drawing it
+            position = position_HeadOfLine;
+            draw = true;
+            i = headOfLine;
+            continue;
+         }
+         else // we have drawn a line, so continue calculating next one
+            draw = false;
+      }
+
+      if(position.x+size.x > m_MaxX)
+         m_MaxX = position.x+size.x;
+      // is it a linebreak?
+      if(type == WXLO_TYPE_LINEBREAK || i == tail())
+      {
+         position.x = 0;
+         position.y += baseLineSkip;
+         baseLine = m_FontPtSize;
+         baseLineSkip = (12 * baseLine)/10;
+         headOfLine = i;
+         headOfLine++;
+         position_HeadOfLine = position;
+      }
+      i++;
+   }
+   m_MaxY = position.y;
+   return foundObject;
+}
+
+#ifdef DEBUG
+void
+wxLayoutList::Debug(void)
+{
+   CoordType               offs;
+   wxLayoutObjectList::iterator i;
+
+   cerr <<
+      "------------------------debug start-------------------------" << endl;
+   for(i = begin(); i != end(); i++)
+   {
+      (*i)->Debug();
+      cerr << endl;
+   }
+   cerr <<
+      "-----------------------debug end----------------------------"
+        << endl;
+   // show current object:
+   cerr << "Cursor: "
+        << m_CursorPosition.x << ','
+        << m_CursorPosition.y;
+   
+   i = FindCurrentObject(&offs);
+   cerr << " line length: " << GetLineLength(i) << "  ";
+   if(i == end())
+   {
+      cerr << "<<no object found>>" << endl;
+      return;  // FIXME we should set cursor position to maximum allowed
+      // value then
+   }
+   if((*i)->GetType() == WXLO_TYPE_TEXT)
+   {
+      cerr << " \"" << ((wxLayoutObjectText *)(*i))->GetText() << "\", offs: "
+           << offs << endl;
+   }
+   else
+      cerr << ' ' << _t[(*i)->GetType()] << endl;
+
+}
+#endif
+
+/******************** editing stuff ********************/
+
+wxLayoutObjectList::iterator 
+wxLayoutList::FindObjectCursor(wxPoint const &cpos, CoordType *offset)
+{
+   wxPoint cursor = wxPoint(0,0);  // runs along the objects
+   CoordType width;
+   wxLayoutObjectList::iterator i;
+
+#ifdef DEBUG
+   cerr << "Looking for object at " << cpos.x << ',' << cpos.y <<
+      endl;
+#endif
+   for(i = begin(); i != end() && cursor.y <= cpos.y; i++)
+   {
+      width = 0;
+      if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
+      {
+         if(cpos.y == cursor.y)
+         {
+            --i;
+            if(offset)
+               *offset = (*i)->CountPositions();
+            return i;
+         }
+         cursor.x = 0; cursor.y ++;
+      }
+      else
+         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)
+            *offset = cpos.x-(cursor.x-width);  // 0==cursor before
+         // the object
+#ifdef DEBUG
+         cerr << "   found object at " << cursor.x-width << ',' <<
+            cursor.y << ", type:" << _t[(*i)->GetType()] <<endl;
+#endif   
+         return i;
+      }
+   }
+#ifdef DEBUG
+   cerr << "   not found" << endl;
+#endif
+   return end(); // not found
+}
+
+wxLayoutObjectList::iterator 
+wxLayoutList::FindCurrentObject(CoordType *offset)
+{
+   wxLayoutObjectList::iterator obj = end();
+
+   obj = FindObjectCursor(m_CursorPosition, offset);
+   if(obj == end())  // not ideal yet
+   {
+      obj = tail();
+      if(obj != end()) // tail really exists
+         *offset = (*obj)->CountPositions(); // at the end of it
+   }
+   return obj;
+}
+
+void
+wxLayoutList::MoveCursor(int dx, int dy)
+{
+   CoordType offs, lineLength;
+   wxLayoutObjectList::iterator i;
+
+
+   if(dy > 0 && m_CursorPosition.y < m_MaxLine)
+      m_CursorPosition.y += dy;
+   else if(dy < 0 && m_CursorPosition.y > 0)
+      m_CursorPosition.y += dy; // dy is negative
+   if(m_CursorPosition.y < 0)
+      m_CursorPosition.y = 0;
+   else if (m_CursorPosition.y > m_MaxLine)
+      m_CursorPosition.y = m_MaxLine;
+   
+   while(dx > 0)
+   {
+      i = FindCurrentObject(&offs);
+      lineLength = GetLineLength(i);
+      if(m_CursorPosition.x < lineLength)
+      {
+         m_CursorPosition.x ++;
+         dx--;
+         continue;
+      }
+      else
+      {
+         if(m_CursorPosition.y < m_MaxLine)
+         {
+            m_CursorPosition.y++;
+            m_CursorPosition.x = 0;
+            dx--;
+         }
+         else
+            break; // cannot move there
+      }
+   }
+   while(dx < 0)
+   {
+      if(m_CursorPosition.x > 0)
+      {
+         m_CursorPosition.x --;
+         dx++;
+      }
+      else
+      {
+         if(m_CursorPosition.y > 0)
+         {
+            m_CursorPosition.y --;
+            m_CursorPosition.x = 0;
+            i = FindCurrentObject(&offs);
+            lineLength = GetLineLength(i);
+            m_CursorPosition.x = lineLength;
+            dx++;
+            continue;
+         }
+         else
+            break; // cannot move left any more
+      }
+   }
+   // final adjustment:
+   i = FindCurrentObject(&offs);
+   lineLength = GetLineLength(i);
+   if(m_CursorPosition.x > lineLength)
+      m_CursorPosition.x = lineLength;
+      
+#ifdef   DEBUG
+   i = FindCurrentObject(&offs);
+   cerr << "Cursor: "
+        << m_CursorPosition.x << ','
+        << m_CursorPosition.y;
+
+   if(i == end())
+   {
+      cerr << "<<no object found>>" << endl;
+      return;  // FIXME we should set cursor position to maximum allowed
+      // value then
+   }
+   if((*i)->GetType() == WXLO_TYPE_TEXT)
+   {
+      cerr << " \"" << ((wxLayoutObjectText *)(*i))->GetText() << "\", offs: "
+           << offs << endl;
+   }
+   else
+      cerr << ' ' << _t[(*i)->GetType()] << endl;
+#endif
+}
+
+void
+wxLayoutList::Delete(CoordType count)
+{
+   TRACE(Delete);
+
+   if(!m_Editable)
+      return;
+
+   VAR(count);
+
+   CoordType offs, len;
+   wxLayoutObjectList::iterator i;
+      
+   do
+   {
+      i  = FindCurrentObject(&offs);
+      if(i == end())
+         return;
+#ifdef DEBUG
+      cerr << "trying to delete: " << _t[(*i)->GetType()] << endl;
+#endif
+      if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
+         m_MaxLine--;
+      if((*i)->GetType() == WXLO_TYPE_TEXT)
+      {
+         wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
+         len = tobj->CountPositions();
+         // If we find the end of a text object, this means that we
+         // have to delete from the object following it.
+         if(offs == len)
+         {
+            i++;
+            if((*i)->GetType() == WXLO_TYPE_TEXT)
+            {
+               offs = 0;  // delete from begin of next string
+               tobj = (wxLayoutObjectText *)*i;
+               len = tobj->CountPositions();
+            }
+            else
+            {
+               erase(i);
+               return;
+            }
+         }
+         if(len <= count) // delete this object
+         {
+            count -= len;
+            erase(i);
+         }
+         else
+         {
+            len = count;
+            VAR(offs); VAR(len);
+            tobj->GetText().erase(offs,len);
+            return; // we are done
+         }
+      }
+      else // delete the object
+      {
+         len = (*i)->CountPositions();
+         erase(i); // after this, i is the iterator for the following object
+         if(count > len)
+            count -= len;
+         else
+            count = 0;
+      }
+   }
+   while(count && i != end());      
+}
+
+void
+wxLayoutList::Insert(wxLayoutObjectBase *obj)
+{
+   wxASSERT(obj);
+   CoordType offs;
+   wxLayoutObjectList::iterator i = FindCurrentObject(&offs);
+
+   TRACE(Insert(obj));
+
+   if(i == end())
+      push_back(obj);
+   else
+   {      
+      // do we have to split a text object?
+      if((*i)->GetType() == WXLO_TYPE_TEXT && offs != 0 && offs != (*i)->CountPositions())
+      {
+         wxLayoutObjectText *tobj = (wxLayoutObjectText *) *i;
+#ifdef DEBUG
+         cerr << "text: '" << tobj->GetText() << "'" << endl;
+         VAR(offs);
+#endif
+         wxString left = tobj->GetText().substr(0,offs); // get part before cursor
+         VAR(left);
+         tobj->GetText() = tobj->GetText().substr(offs,(*i)->CountPositions()-offs); // keeps the right half
+         VAR(tobj->GetText());
+         insert(i,obj);
+         insert(i,new wxLayoutObjectText(left)); // inserts before
+      }
+      else
+      {
+         wxLayoutObjectList::iterator j = i; // we want to apend after this object
+         j++;
+         if(j != end())
+            insert(j, obj);
+         else
+            push_back(obj);
+      }  
+   }
+   m_CursorPosition.x += obj->CountPositions();
+   if(obj->GetType() == WXLO_TYPE_LINEBREAK)
+      m_MaxLine++;
+}
+
+void
+wxLayoutList::Insert(wxString const &text)
+{
+   TRACE(Insert(text));
+
+   if(! m_Editable)
+      return;
+
+   CoordType offs;
+   wxLayoutObjectList::iterator i = FindCurrentObject(&offs);
+
+   if(i != end() && (*i)->GetType() == WXLO_TYPE_TEXT)
+   {  // insert into an existing text object:
+      TRACE(inserting into existing object);
+      wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
+      tobj->GetText().insert(offs,text);
+   }
+   else
+   {
+      // check whether the previous object is text:
+      wxLayoutObjectList::iterator j = i;
+      j--;
+      TRACE(checking previous object);
+      if(0 && j != end() && (*j)->GetType() == WXLO_TYPE_TEXT)
+      {
+         wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
+         tobj->GetText()+=text;
+      }
+      else  // insert a new text object
+      {
+         TRACE(creating new object);
+         Insert(new wxLayoutObjectText(text));  //FIXME not too optimal, slow
+         return;  // position gets incremented in Insert(obj)
+      }
+   }
+   m_CursorPosition.x += strlen(text.c_str());
+}
+
+CoordType
+wxLayoutList::GetLineLength(wxLayoutObjectList::iterator i)
+{
+   if(i == end())
+      return 0;
+
+   CoordType len = 0;
+
+   // search backwards for beginning of line:
+   while(i != begin() && (*i)->GetType() != WXLO_TYPE_LINEBREAK)
+      i--;
+   if((*i)->GetType() == WXLO_TYPE_LINEBREAK)
+      i++;
+   // now we can start counting:
+   while(i != end() && (*i)->GetType() != WXLO_TYPE_LINEBREAK)
+   {
+      len += (*i)->CountPositions();
+      i++;
+   }
+   return len;
+}
+
+void
+wxLayoutList::Clear(void)
+{
+   wxLayoutObjectList::iterator i = begin();
+
+   while(i != end()) // == while valid
+      erase(i);
+
+   // set defaults
+   m_FontPtSize = 12;
+   m_FontUnderline = false;
+   m_FontFamily = wxDEFAULT;
+   m_FontStyle = wxNORMAL;
+   m_FontWeight = wxNORMAL;
+   m_ColourFG = wxTheColourDatabase->FindColour("BLACK");
+   m_ColourBG = wxTheColourDatabase->FindColour("WHITE");
+
+   m_Position = wxPoint(0,0);
+   m_CursorPosition = wxPoint(0,0);
+   m_MaxLine = 0;
+   m_LineHeight = (12*m_FontPtSize)/10;
+   m_MaxX = 0; m_MaxY = 0;
+}
diff --git a/user/wxLayout/wxllist.h b/user/wxLayout/wxllist.h
new file mode 100644 (file)
index 0000000..e9c5c0f
--- /dev/null
@@ -0,0 +1,246 @@
+/*-*- c++ -*-********************************************************
+ * wxLayoutList.h - a formatted text rendering engine for wxWindows *
+ *                                                                  *
+ * (C) 1998 by Karsten Ballüder (Ballueder@usa.net)                 *
+ *                                                                  *
+ * $Id$
+ *******************************************************************/
+#ifndef WXLLIST_H
+#define WXLLIST_H
+
+#ifdef __GNUG__
+#   pragma interface "wxllist.h"
+#endif
+
+#include   "kbList.h"
+
+#include   <wx/wx.h>
+
+#ifndef   DEBUG
+#   define DEBUG
+#endif
+
+
+enum wxLayoutObjectType { WXLO_TYPE_INVALID, WXLO_TYPE_TEXT, WXLO_TYPE_CMD, WXLO_TYPE_ICON, WXLO_TYPE_LINEBREAK };
+
+typedef long CoordType;
+
+class wxLayoutList;
+class wxLayoutObjectBase;
+
+KBLIST_DEFINE(wxLayoutObjectList, wxLayoutObjectBase);
+KBLIST_DEFINE(wxLayoutOLinesList, wxLayoutObjectList::iterator);
+
+
+class wxLayoutObjectBase
+{
+public:
+   virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_INVALID; } ;
+   /** Draws an object.
+       @param dc the wxDC to draw on
+       @param position where to draw the top left corner
+       @param baseLine the baseline for alignment, from top of box
+       @draw if set to false, do not draw but just calculate sizes
+   */
+   virtual void Draw(wxDC &dc, wxPoint position, CoordType baseLine,
+                     bool draw = true) {};
+
+   virtual wxPoint GetSize(CoordType *baseLine) const { return
+                                                           wxPoint(0,0); };
+   /// returns the number of cursor positions occupied by this object
+   virtual CoordType CountPositions(void) const { return 1; }
+
+   wxLayoutObjectBase() { m_UserData = NULL; }
+   virtual ~wxLayoutObjectBase() {}
+#ifdef DEBUG
+   virtual void Debug(void);
+#endif
+
+   void   SetUserData(void *data) { m_UserData = data; }
+   void * GetUserData(void) const { return m_UserData; }
+private:
+   /// optional data for application's use
+   void * m_UserData;
+};
+
+/// object for text block
+class wxLayoutObjectText : public wxLayoutObjectBase
+{
+public:
+   virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_TEXT; }
+   virtual void Draw(wxDC &dc, wxPoint position, CoordType baseLine,
+                     bool draw = true);
+   /** This returns the height and in baseLine the position of the
+       text's baseline within it's box. This is needed to properly
+       align text objects.
+   */
+   virtual wxPoint GetSize(CoordType *baseLine) const;
+#ifdef DEBUG
+   virtual void Debug(void);
+#endif
+
+   wxLayoutObjectText(const wxString &txt);
+   virtual CoordType CountPositions(void) const { return strlen(m_Text.c_str()); }
+
+   // for editing:
+   wxString & GetText(void) { return m_Text; }
+   void SetText(wxString const &text) { m_Text = text; }
+private:
+   wxString m_Text;
+   /// size of the box containing text
+   long   m_Width, m_Height;
+   /// the position of the baseline counted from the top of the box
+   long   m_BaseLine;
+};
+
+/// icon/pictures:
+class wxLayoutObjectIcon : public wxLayoutObjectBase
+{
+public:
+   virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_ICON; }
+   virtual void Draw(wxDC &dc, wxPoint position, CoordType baseLine,
+                     bool draw = true);
+   virtual wxPoint GetSize(CoordType *baseLine) const;
+   wxLayoutObjectIcon(wxIcon *icon);
+private:
+   wxIcon * m_Icon;
+};
+
+/// for export to html:
+struct wxLayoutStyleInfo
+{
+   int  size, family, style, weight;
+   bool underline;
+   unsigned fg_red, fg_green, fg_blue;
+   unsigned bg_red, bg_green, bg_blue;
+};
+
+/// pseudo-object executing a formatting command in Draw()
+class wxLayoutObjectCmd : public wxLayoutObjectBase
+{
+public:
+   virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_CMD; }
+   virtual void Draw(wxDC &dc, wxPoint position, CoordType baseLine,
+                     bool draw = true);
+   wxLayoutObjectCmd(int size, int family, int style, int weight,
+                bool underline,
+                wxColour const *fg, wxColour const *bg);
+   ~wxLayoutObjectCmd();
+   // caller must free pointer:
+   wxLayoutStyleInfo *GetStyle(void) const ;
+private:
+   /// the font to use
+   wxFont *m_font;
+   /// foreground colour
+   wxColour const *m_ColourFG;
+   /// background colour
+   wxColour const *m_ColourBG;
+};
+
+/// this object doesn't do anything at all
+class wxLayoutObjectLineBreak : public wxLayoutObjectBase
+{
+public:
+   virtual wxLayoutObjectType GetType(void) const { return WXLO_TYPE_LINEBREAK; }
+};
+
+
+/**
+   This class provides a high level abstraction to the wxFText
+   classes.
+   It handles most of the character events with its own callback
+   functions, providing an editing ability. All events which cannot be
+   handled get passed to the parent window's handlers.
+*/
+class wxLayoutList : public wxLayoutObjectList
+{
+public:
+   wxLayoutList();
+   
+   /// Destructor.
+   ~wxLayoutList();
+
+   /// adds an object:
+   void AddObject(wxLayoutObjectBase *obj);
+   void AddText(wxString const &txt);
+
+   void LineBreak(void);
+   void SetFont(int family, int size, int style,
+                int weight, int underline,
+                wxColour const *fg,
+                wxColour const *bg);
+   void SetFont(int family=-1, int size = -1, int style=-1,
+                int weight=-1, int underline = -1,
+                char const *fg = NULL,
+                char const *bg = NULL);
+   /** Draw the list on a given DC.
+       @param findObject if true, return the object occupying the
+       position specified by coords
+       @param coords position where to find the object
+       @return if findObject == true, the object or NULL
+   */
+   wxLayoutObjectBase *Draw(wxDC &dc, bool findObject = false,
+                       wxPoint const &coords = wxPoint(0,0));
+
+#ifdef DEBUG
+   void Debug(void);
+#endif
+
+   
+   /// for access by wxLayoutWindow:
+   void GetSize(CoordType *max_x, CoordType *max_y,
+                CoordType *lineHeight);
+
+   /**@name Functionality for editing */
+   //@{
+   /// set list editable or read only
+   void SetEditable(bool editable = true) { m_Editable = true; }
+   /// move cursor
+   void MoveCursor(int dx = 0, int dy = 0);
+   void SetCursor(wxPoint const &p) { m_CursorPosition = p; }
+   /// delete one or more cursor positions
+   void Delete(CoordType count = 1);
+   void Insert(wxString const &text);
+   void Insert(wxLayoutObjectBase *obj);
+   void Clear(void);
+
+   //@}
+protected:
+   /// font parameters:
+   int m_FontFamily, m_FontStyle, m_FontWeight;
+   int m_FontPtSize;
+   bool m_FontUnderline;
+   /// colours:
+   wxColour const * m_ColourFG;
+   wxColour const * m_ColourBG;
+   
+   /// needs recalculation?
+   bool m_dirty;
+
+   // the currently updated line:
+   /// where do we draw next:
+   wxPoint   m_Position;
+   /// the height of the current line:
+   CoordType m_LineHeight;
+   /// maximum drawn x position so far
+   CoordType m_MaxX;
+   /// maximum drawn y position:
+   CoordType m_MaxY;
+
+   //---- this is needed for editing:
+   /// where is the text cursor:
+   wxPoint   m_CursorPosition;
+   /// which is the last line
+   CoordType m_MaxLine;
+   /// can we edit it?
+   bool      m_Editable;
+   /// find the object to the cursor position and returns the offset
+   /// in there
+   wxLayoutObjectList::iterator FindObjectCursor(wxPoint const &cpos, CoordType *offset = NULL);
+   wxLayoutObjectList::iterator FindCurrentObject(CoordType *offset = NULL);
+   // get the length of the line with the object pointed to by i
+   CoordType GetLineLength(wxLayoutObjectList::iterator i);
+   
+};
+
+#endif // WXLLIST_H
diff --git a/user/wxLayout/wxlparser.cpp b/user/wxLayout/wxlparser.cpp
new file mode 100644 (file)
index 0000000..90d92e9
--- /dev/null
@@ -0,0 +1,186 @@
+/*-*- c++ -*-********************************************************
+ * wxlparser.h : parsers,  import/export for wxLayoutList           *
+ *                                                                  *
+ * (C) 1998 by Karsten Ballüder (Ballueder@usa.net)                 *
+ *                                                                  *
+ * $Id$
+ *******************************************************************/
+
+#ifdef __GNUG__
+#   pragma implementation "wxlparser.h"
+#endif
+
+#include   "wxllist.h"
+#include   "wxlparser.h"
+
+#define   BASE_SIZE 12
+
+void wxLayoutImportText(wxLayoutList &list, wxString const &str)
+{
+   char * cptr = (char *)str.c_str(); // string gets changed only temporarily
+   const char * begin = cptr;
+   char  backup;
+   
+   for(;;)
+   {
+      begin = cptr++;
+      while(*cptr && *cptr != '\n')
+         cptr++;
+      backup = *cptr;
+      *cptr = '\0';
+      list.Insert(begin);
+      *cptr = backup;
+      if(backup == '\n')
+         list.LineBreak();
+      else if(backup == '\0') // reached end of string
+         break;
+      cptr++;
+   }
+}
+
+static
+wxString wxLayoutExportCmdAsHTML(wxLayoutObjectCmd const & cmd,
+                                 wxLayoutStyleInfo **lastStylePtr)
+{
+   static char buffer[20];
+   wxString html;
+   
+   wxLayoutStyleInfo *si = cmd.GetStyle();
+   wxLayoutStyleInfo *last_si = NULL;
+
+   int size, sizecount;
+   
+   if(lastStylePtr != NULL)
+      last_si = *lastStylePtr;
+   
+   html += "<font ";
+
+   html +="color=";
+   sprintf(buffer,"\"#%02X%02X%02X\"", si->fg_red,si->fg_green,si->fg_blue);
+   html += buffer;
+
+
+   html += " bgcolor=";
+   sprintf(buffer,"\"#%02X%02X%02X\"", si->bg_red,si->bg_green,si->bg_blue);
+   html += buffer;
+
+   switch(si->family)
+   {
+   case wxSWISS:
+   case wxMODERN:
+      html += " face=\"Arial,Helvetica\""; break;
+   case wxROMAN:
+      html += " face=\"Times New Roman, Times\""; break;
+   case wxTELETYPE:
+      html += " face=\"Courier New, Courier\""; break;
+   default:
+      ;
+   }
+
+   size = BASE_SIZE; sizecount = 0;
+   while(size < si->size && sizecount < 5)
+   {
+      sizecount ++;
+      size = (size*12)/10;
+   }
+   while(size > si->size && sizecount > -5)
+   {
+      sizecount --;
+      size = (size*10)/12;
+   }
+   html += "size=";
+   sprintf(buffer,"%+1d", sizecount);
+   html += buffer;
+
+   html +=">";
+
+   if(last_si != NULL)
+      html ="</font>"+html; // terminate any previous font command
+
+   if((si->weight == wxBOLD) && ( (!last_si) || (last_si->weight != wxBOLD)))
+      html += "<b>";
+   else
+      if(si->weight != wxBOLD && ( last_si && (last_si->weight == wxBOLD)))
+         html += "</b>";
+
+   if(si->style == wxSLANT)
+      si->style = wxITALIC; // the same for html
+   
+   if((si->style == wxITALIC) && ( (!last_si) || (last_si->style != wxITALIC)))
+      html += "<i>";
+   else
+      if(si->style != wxITALIC && ( last_si && (last_si->style == wxITALIC)))
+         html += "</i>";
+
+   if(si->underline && ( (!last_si) || ! last_si->underline))
+      html += "<u>";
+   else if(si->underline == false && ( last_si && last_si->underline))
+      html += "</u>";
+   
+   if(last_si)
+      delete last_si;
+   *lastStylePtr = si;
+   return html;
+}
+
+
+
+#define   WXLO_IS_TEXT(type) \
+( (type == WXLO_TYPE_TEXT || type == WXLO_TYPE_LINEBREAK) \
+  || (type == WXLO_TYPE_CMD \
+      && mode == WXLO_EXPORT_AS_HTML))
+
+
+  
+   wxLayoutExportObject *wxLayoutExport(wxLayoutList &list,
+                                        wxLayoutList::iterator &from,
+                                        wxLayoutExportMode mode)
+{
+   if(from == list.end())
+      return NULL;
+   
+   wxLayoutObjectType   type = (*from)->GetType();
+   wxLayoutExportObject     * export = new wxLayoutExportObject();
+
+   static wxLayoutStyleInfo *s_si = NULL;
+   
+   if( mode == WXLO_EXPORT_AS_OBJECTS || ! WXLO_IS_TEXT(type)) // simple case
+   {
+      export->type = WXLO_EXPORT_OBJECT;
+      export->content.object = *from;
+      from++;
+      return export;
+   }
+
+   wxString *str = new wxString();
+   
+   // text must be concatenated
+   while(from != list.end() && WXLO_IS_TEXT(type))
+   {
+      switch(type)
+      {
+      case WXLO_TYPE_TEXT:
+         *str += ((wxLayoutObjectText *)*from)->GetText();
+         break;
+      case WXLO_TYPE_LINEBREAK:
+         if(mode == WXLO_EXPORT_AS_HTML)
+            *str += "<br>";
+         *str += '\n';
+         break;
+      case WXLO_TYPE_CMD:
+         //wxASSERT(mode == WXLO_EXPORT_AS_HTML,"reached cmd object in text mode")
+         assert(mode == WXLO_EXPORT_AS_HTML);
+         *str += wxLayoutExportCmdAsHTML(*(wxLayoutObjectCmd const
+                                           *)*from, &s_si);
+         break;
+      default:  // ignore icons
+         ;
+      }
+      from++;
+      if(from != list.end())
+         type = (*from)->GetType();
+   }
+   export->type = (mode == WXLO_EXPORT_AS_HTML) ?  WXLO_EXPORT_HTML : WXLO_EXPORT_TEXT;
+   export->content.text = str;
+   return export;
+}
diff --git a/user/wxLayout/wxlparser.h b/user/wxLayout/wxlparser.h
new file mode 100644 (file)
index 0000000..c59b7dc
--- /dev/null
@@ -0,0 +1,57 @@
+/*-*- c++ -*-********************************************************
+ * wxlparser.h : parsers,  import/export for wxLayoutList           *
+ *                                                                  *
+ * (C) 1998 by Karsten Ballüder (Ballueder@usa.net)                 *
+ *                                                                  *
+ * $Id$
+ *******************************************************************/
+#ifndef WXLPARSER_H
+#   define   WXLPARSER_H
+
+#ifdef __GNUG__
+#   pragma interface "wxlparser.h"
+#endif
+
+#ifndef   NULL
+#   define   NULL 0
+#endif
+
+enum wxLayoutExportType
+{
+   WXLO_EXPORT_TEXT,        
+   WXLO_EXPORT_HTML,        
+   WXLO_EXPORT_OBJECT
+};
+
+enum wxLayoutExportMode
+{
+   WXLO_EXPORT_AS_TEXT,
+   WXLO_EXPORT_AS_TEXT_AND_COMMANDS,
+   WXLO_EXPORT_AS_HTML,
+   WXLO_EXPORT_AS_OBJECTS
+};
+
+struct wxLayoutExportObject
+{
+   wxLayoutExportType type;
+   union
+   {
+      wxString           *text;
+      wxLayoutObjectBase *object;
+   }content;
+   ~wxLayoutExportObject()
+      {
+         if(type == WXLO_EXPORT_TEXT || type == WXLO_EXPORT_HTML)
+            delete content.text;
+      }
+};
+
+/// import text into a wxLayoutList (including linefeeds):
+void wxLayoutImportText(wxLayoutList &list, wxString const &str);
+
+
+wxLayoutExportObject *wxLayoutExport(wxLayoutList &list,
+                               wxLayoutList::iterator &from,
+                               wxLayoutExportMode WXLO_EXPORT_AS_TEXT);
+
+#endif //WXLPARSER_H
diff --git a/user/wxLayout/wxlwindow.cpp b/user/wxLayout/wxlwindow.cpp
new file mode 100644 (file)
index 0000000..fd77b00
--- /dev/null
@@ -0,0 +1,149 @@
+/*-*- c++ -*-********************************************************
+ * wxLwindow.h : a scrolled Window for displaying/entering rich text*
+ *                                                                  *
+ * (C) 1998 by Karsten Ballüder (Ballueder@usa.net)                 *
+ *                                                                  *
+ * $Id$
+ *******************************************************************/
+
+#ifdef __GNUG__
+#   pragma implementation "wxlwindow.h"
+#endif
+
+#include   "wxlwindow.h"
+
+#define   VAR(x)   cout << #x"=" << x << endl;
+
+BEGIN_EVENT_TABLE(wxLayoutWindow,wxScrolledWindow)
+   EVT_PAINT  (wxLayoutWindow::OnPaint)
+   EVT_CHAR   (wxLayoutWindow::OnChar)
+   EVT_LEFT_DOWN(wxLayoutWindow::OnMouse)
+END_EVENT_TABLE()
+
+wxLayoutWindow::wxLayoutWindow(wxWindow *parent)
+   : wxScrolledWindow(parent)
+{
+   m_ScrollbarsSet = false;
+   m_EventId = 0;
+}
+
+void
+wxLayoutWindow::OnMouse(wxMouseEvent& event)
+{
+   if(m_EventId == 0) // nothing to do
+      return;
+   
+   m_FindPos.x = event.GetX();
+   m_FindPos.y = event.GetY();
+   m_FoundObject = NULL;
+
+#ifdef   DEBUG
+   cerr << "OnMouse: " << m_FindPos.x << ',' << m_FindPos.y << endl;
+#endif
+   Refresh();
+   if(m_FoundObject)
+   {
+      if(m_EventId)
+      {
+         wxCommandEvent commandEvent(wxEVENT_TYPE_MENU_COMMAND, m_EventId);
+         commandEvent.SetEventObject( this );
+         GetEventHandler()->ProcessEvent(commandEvent);
+      }
+   }
+}
+
+/*
+ * some simple keyboard handling
+ */
+void
+wxLayoutWindow::OnChar(wxKeyEvent& event)
+{
+   long keyCode = event.KeyCode();
+
+   switch(event.KeyCode())
+   {
+      case WXK_RIGHT:
+      m_llist.MoveCursor(1);
+      break;
+   case WXK_LEFT:
+      m_llist.MoveCursor(-1);
+      break;
+   case WXK_UP:
+      m_llist.MoveCursor(0,-1);
+      break;
+   case WXK_DOWN:
+      m_llist.MoveCursor(0,1);
+      break;
+   case WXK_PRIOR:
+      m_llist.MoveCursor(0,-20);
+      break;
+   case WXK_NEXT:
+      m_llist.MoveCursor(0,20);
+      break;
+   case WXK_DELETE :
+      m_llist.Delete(1);
+      break;
+   case WXK_BACK: // backspace
+      m_llist.MoveCursor(-1);
+      m_llist.Delete(1);
+      break;
+   case WXK_RETURN:
+      m_llist.LineBreak();
+      break;
+#ifdef DEBUG   
+   case WXK_F1:
+      m_llist.Debug();
+      break;
+#endif 
+   default:
+      if(keyCode < 256 && keyCode >= 32)
+      {
+         wxString tmp;
+         tmp += keyCode;
+         m_llist.Insert(tmp);
+      }
+      break;
+   }
+   Refresh();
+   UpdateScrollbars();
+}
+
+void
+wxLayoutWindow::OnPaint( wxPaintEvent &WXUNUSED(event)w)  // or: OnDraw(wxDC& dc)
+{
+   wxPaintDC dc( this );  // only when used as OnPaint for OnDraw we
+   PrepareDC( dc );       // can skip the first two lines
+
+   if(m_EventId) // look for keyclicks
+      m_FoundObject = m_llist.Draw(dc,true,m_FindPos);
+   else
+      m_llist.Draw(dc);
+   if(! m_ScrollbarsSet)
+   {
+      m_ScrollbarsSet = true; // avoid recursion
+      UpdateScrollbars();
+   }
+}
+
+void
+wxLayoutWindow::UpdateScrollbars(void)
+{
+   CoordType
+      max_x, max_y, lineHeight;
+   
+   m_llist.GetSize(&max_x, &max_y, &lineHeight);
+   SetScrollbars(10, lineHeight, max_x/10+1, max_y/lineHeight+1);
+   EnableScrolling(true,true);
+}
+
+void
+wxLayoutWindow::Print(void)
+{
+   wxPostScriptDC   dc("layout.ps",true,this);
+   if (dc.Ok() && dc.StartDoc((char *)_("Printing message...")))
+   {
+      //dc.SetUserScale(1.0, 1.0);
+      m_llist.Draw(dc);
+      dc.EndDoc();
+   }
+}
diff --git a/user/wxLayout/wxlwindow.h b/user/wxLayout/wxlwindow.h
new file mode 100644 (file)
index 0000000..31e98e4
--- /dev/null
@@ -0,0 +1,48 @@
+/*-*- c++ -*-********************************************************
+ * wxLwindow.h : a scrolled Window for displaying/entering rich text*
+ *                                                                  *
+ * (C) 1998 by Karsten Ballüder (Ballueder@usa.net)                 *
+ *                                                                  *
+ * $Id$
+ *******************************************************************/
+#ifndef WXLWINDOW_H
+#define WXLWINDOW_H
+
+#ifdef __GNUG__
+#   pragma interface "wxlwindow.h"
+#endif
+
+#include   <wx/wx.h>
+
+#include   "wxllist.h"
+
+class wxLayoutWindow : public wxScrolledWindow
+{
+public:
+   wxLayoutWindow(wxWindow *parent);
+
+   wxLayoutList & GetLayoutList(void) { return m_llist; }
+
+   //virtual void OnDraw(wxDC &dc);
+   void OnPaint(wxPaintEvent &WXUNUSED(event));
+   virtual void OnMouse(wxMouseEvent& event);
+   virtual void OnChar(wxKeyEvent& event);
+   void UpdateScrollbars(void);
+   void Print(void);
+   void Erase(void)
+      { m_llist.Clear(); Clear(); }
+   void SetEventId(int id) { m_EventId = id; }
+private:
+   int m_EventId;
+   /// the layout list to be displayed
+   wxLayoutList m_llist;
+   /// have we already set the scrollbars?
+   bool m_ScrollbarsSet;
+   /// if we want to find an object:
+   wxPoint m_FindPos;
+   wxLayoutObjectBase *m_FoundObject;
+
+   DECLARE_EVENT_TABLE()
+};
+
+#endif