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:
parent
8f79098a04
commit
a5f81d8c07
26
user/wxLayout/Makefile.in
Normal file
26
user/wxLayout/Makefile.in
Normal 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
309
user/wxLayout/Micon.xpm
Normal 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
50
user/wxLayout/README
Normal 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
320
user/wxLayout/kbList.cpp
Normal 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
290
user/wxLayout/kbList.h
Normal 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
273
user/wxLayout/wxLayout.cpp
Normal 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
57
user/wxLayout/wxLayout.h
Normal 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
789
user/wxLayout/wxllist.cpp
Normal 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
246
user/wxLayout/wxllist.h
Normal 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
186
user/wxLayout/wxlparser.cpp
Normal 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
57
user/wxLayout/wxlparser.h
Normal 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
149
user/wxLayout/wxlwindow.cpp
Normal 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
48
user/wxLayout/wxlwindow.h
Normal 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
|
Loading…
Reference in New Issue
Block a user