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.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@157 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Karsten Ballüder 1998-06-29 12:44:36 +00:00
parent 8f79098a04
commit a5f81d8c07
13 changed files with 2800 additions and 0 deletions

26
user/wxLayout/Makefile.in Normal file
View File

@ -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

309
user/wxLayout/Micon.xpm Normal file
View File

@ -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........"
};

50
user/wxLayout/README Normal file
View File

@ -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

320
user/wxLayout/kbList.cpp Normal file
View File

@ -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

290
user/wxLayout/kbList.h Normal file
View File

@ -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

273
user/wxLayout/wxLayout.cpp Normal file
View File

@ -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;
};

57
user/wxLayout/wxLayout.h Normal file
View File

@ -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__

789
user/wxLayout/wxllist.cpp Normal file
View File

@ -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;
}

246
user/wxLayout/wxllist.h Normal file
View File

@ -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

186
user/wxLayout/wxlparser.cpp Normal file
View File

@ -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;
}

57
user/wxLayout/wxlparser.h Normal file
View File

@ -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

149
user/wxLayout/wxlwindow.cpp Normal file
View File

@ -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();
}
}

48
user/wxLayout/wxlwindow.h Normal file
View File

@ -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