UIMLView.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092
  1. #include "UIMLView.h"
  2. #include "Bild.h"
  3. #include "Bildschirm.h"
  4. #include "Fenster.h"
  5. #include "Knopf.h"
  6. #include "Rahmen.h"
  7. #include "Schrift.h"
  8. #include "Scroll.h"
  9. #include "Tabelle.h"
  10. #include "TextFeld.h"
  11. #include "XML.h"
  12. using namespace Framework;
  13. UIMLElement::UIMLElement()
  14. : ReferenceCounter()
  15. {}
  16. UIMLElement::~UIMLElement() {}
  17. //! wendet die layout parameter zu einer Zeichnung an
  18. void UIMLElement::layout(XML::Element& element,
  19. Zeichnung& z,
  20. int pWidth,
  21. int pHeight,
  22. UIMLContainer& generalLayouter)
  23. {
  24. int width = z.getBreite();
  25. int height = z.getHeight();
  26. if (element.hasAttribute("width"))
  27. {
  28. Text w = element.getAttributeValue("width");
  29. if (!w.istGleich("auto"))
  30. {
  31. width = (int)w;
  32. if (w.getText()[w.getLength() - 1] == '%')
  33. width = (int)((pWidth / 100.0) * width);
  34. }
  35. }
  36. if (element.hasAttribute("height"))
  37. {
  38. Text h = element.getAttributeValue("height");
  39. if (!h.istGleich("auto"))
  40. {
  41. height = (int)h;
  42. if (h.getText()[h.getLength() - 1] == '%')
  43. height = (int)((pHeight / 100.0) * height);
  44. }
  45. }
  46. z.setSize(width, height);
  47. if (element.hasAttribute("align-left"))
  48. {
  49. Text la = element.getAttributeValue("align-left");
  50. int x = 0;
  51. if (la.istGleich("start"))
  52. x = 0;
  53. else if (la.istGleich("end"))
  54. x = pWidth;
  55. else if (la.istGleich("center"))
  56. x = pWidth / 2 - width / 2;
  57. else
  58. {
  59. XML::Editor ed
  60. = element.zParent()->selectChildsByAttribute("id", la);
  61. generalLayouter.layout(*ed.begin().val(),
  62. *generalLayouter.zZeichnungById(la),
  63. pWidth,
  64. pHeight,
  65. generalLayouter);
  66. Zeichnung* laz = generalLayouter.zZeichnungById(la);
  67. if (laz) x = laz->getX() + laz->getBreite();
  68. }
  69. if (element.hasAttribute("margin-left"))
  70. {
  71. Text mt = element.getAttributeValue("margin-left");
  72. int m = (int)mt;
  73. if (mt.getText()[mt.getLength() - 1] == '%')
  74. m = (int)((pWidth / 100.0) * m);
  75. x += m;
  76. }
  77. z.setX(x);
  78. }
  79. else if (element.hasAttribute("align-right"))
  80. {
  81. Text ra = element.getAttributeValue("align-right");
  82. int x = 0;
  83. if (ra.istGleich("start"))
  84. x = -z.getBreite();
  85. else if (ra.istGleich("end"))
  86. x = pWidth - z.getBreite();
  87. else if (ra.istGleich("center"))
  88. x = pWidth / 2 - width / 2;
  89. else
  90. {
  91. XML::Editor ed
  92. = element.zParent()->selectChildsByAttribute("id", ra);
  93. generalLayouter.layout(*ed.begin().val(),
  94. *generalLayouter.zZeichnungById(ra),
  95. pWidth,
  96. pHeight,
  97. generalLayouter);
  98. Zeichnung* raz = generalLayouter.zZeichnungById(ra);
  99. if (raz) x = raz->getX() - z.getBreite();
  100. }
  101. if (element.hasAttribute("margin-right"))
  102. {
  103. Text mt = element.getAttributeValue("margin-right");
  104. int m = (int)mt;
  105. if (mt.getText()[mt.getLength() - 1] == '%')
  106. m = (int)((pWidth / 100.0) * m);
  107. x -= m;
  108. }
  109. z.setX(x);
  110. }
  111. if (element.hasAttribute("align-top"))
  112. {
  113. Text ta = element.getAttributeValue("align-top");
  114. int y = 0;
  115. if (ta.istGleich("start"))
  116. y = 0;
  117. else if (ta.istGleich("end"))
  118. y = pHeight;
  119. else if (ta.istGleich("center"))
  120. y = pHeight / 2 - height / 2;
  121. else
  122. {
  123. XML::Editor ed
  124. = element.zParent()->selectChildsByAttribute("id", ta);
  125. generalLayouter.layout(*ed.begin().val(),
  126. *generalLayouter.zZeichnungById(ta),
  127. pWidth,
  128. pHeight,
  129. generalLayouter);
  130. Zeichnung* taz = generalLayouter.zZeichnungById(ta);
  131. if (taz) y = taz->getY() + taz->getHeight();
  132. }
  133. if (element.hasAttribute("margin-top"))
  134. {
  135. Text mt = element.getAttributeValue("margin-top");
  136. int m = (int)mt;
  137. if (mt.getText()[mt.getLength() - 1] == '%')
  138. m = (int)((pHeight / 100.0) * m);
  139. y += m;
  140. }
  141. z.setY(y);
  142. }
  143. else if (element.hasAttribute("align-bottom"))
  144. {
  145. Text ba = element.getAttributeValue("align-bottom");
  146. int y = 0;
  147. if (ba.istGleich("start"))
  148. y = -z.getHeight();
  149. else if (ba.istGleich("end"))
  150. y = pHeight - z.getHeight();
  151. else if (ba.istGleich("center"))
  152. y = pHeight / 2 - height / 2;
  153. else
  154. {
  155. XML::Editor ed
  156. = element.zParent()->selectChildsByAttribute("id", ba);
  157. generalLayouter.layout(*ed.begin().val(),
  158. *generalLayouter.zZeichnungById(ba),
  159. pWidth,
  160. pHeight,
  161. generalLayouter);
  162. Zeichnung* baz = generalLayouter.zZeichnungById(ba);
  163. if (baz) y = baz->getY() - z.getHeight();
  164. }
  165. if (element.hasAttribute("margin-bottom"))
  166. {
  167. Text mt = element.getAttributeValue("margin-bottom");
  168. int m = (int)mt;
  169. if (mt.getText()[mt.getLength() - 1] == '%')
  170. m = (int)((pHeight / 100.0) * m);
  171. y -= m;
  172. }
  173. z.setY(y);
  174. }
  175. int x = z.getX();
  176. int y = z.getY();
  177. if (element.hasAttribute("x"))
  178. {
  179. Text xt = element.getAttributeValue("x");
  180. x = (int)xt;
  181. if (xt.getText()[xt.getLength() - 1] == '%')
  182. x = (int)((pWidth / 100.0) * x);
  183. }
  184. if (element.hasAttribute("y"))
  185. {
  186. Text yt = element.getAttributeValue("y");
  187. y = (int)yt;
  188. if (yt.getText()[yt.getLength() - 1] == '%')
  189. y = (int)((pHeight / 100.0) * y);
  190. }
  191. z.setPosition(x, y);
  192. pWidth = z.getInnenBreite();
  193. pHeight = z.getInnenHeight();
  194. // recursive layout
  195. for (auto i = element.getChilds(); i; i++)
  196. {
  197. Zeichnung* z = 0;
  198. if (i->hasAttribute("id"))
  199. {
  200. z = generalLayouter.zZeichnungById(i->getAttributeValue("id"));
  201. }
  202. if (z)
  203. {
  204. generalLayouter.layout(
  205. *i.val(), *z, pWidth, pHeight, generalLayouter);
  206. }
  207. }
  208. }
  209. UIMLContainer::UIMLContainer()
  210. : UIMLElement()
  211. {}
  212. UIMLContainer::~UIMLContainer() {}
  213. UIMLTextField::UIMLTextField()
  214. : UIMLElement()
  215. {}
  216. bool UIMLTextField::isApplicableFor(XML::Element& element)
  217. {
  218. return element.getName().istGleich("textfield");
  219. }
  220. Zeichnung* UIMLTextField::parseElement(
  221. XML::Element& element, UIMLContainer& generalFactory)
  222. {
  223. TextFeld* t = generalFactory.getFactory().createTextFeld(
  224. generalFactory.getFactory().initParam);
  225. if (element.hasAttribute("style"))
  226. {
  227. Text style = element.getAttributeValue("style");
  228. if (!style.hatAt(0, "0x"))
  229. {
  230. style.insert(0, "0x");
  231. }
  232. t->setStyle((int)style);
  233. }
  234. else
  235. {
  236. t->addStyle(TextFeld::Style::TextFeld);
  237. }
  238. return t;
  239. }
  240. void UIMLTextField::layout(XML::Element& element,
  241. Zeichnung& z,
  242. int pWidth,
  243. int pHeight,
  244. UIMLContainer& generalLayouter)
  245. {
  246. if (element.hasAttribute("text-align-horizontal"))
  247. z.setStyle(TextFeld::Style::HCenter,
  248. element.getAttributeValue("text-align-horizontal")
  249. .istGleich("center"));
  250. if (element.hasAttribute("text-align-vertical"))
  251. z.setStyle(TextFeld::Style::VCenter,
  252. element.getAttributeValue("text-align-vertical")
  253. .istGleich("center"));
  254. if (element.hasAttribute("font-size"))
  255. ((TextFeld*)&z)
  256. ->setSchriftSize(
  257. (unsigned char)(int)element.getAttributeValue("font-size"));
  258. if (element.hasAttribute("disabled"))
  259. z.removeStyle(TextFeld::Style::Editierbar);
  260. ((TextFeld*)&z)->setText(element.getText());
  261. if (element.hasAttribute("width"))
  262. {
  263. Text w = element.getAttributeValue("width");
  264. if (w.istGleich("auto"))
  265. {
  266. z.setWidth(((TextFeld*)&z)->getNeededWidth());
  267. }
  268. }
  269. if (element.hasAttribute("height"))
  270. {
  271. Text h = element.getAttributeValue("height");
  272. if (h.istGleich("auto"))
  273. {
  274. z.setHeight(((TextFeld*)&z)->getNeededHeight());
  275. }
  276. }
  277. UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter);
  278. }
  279. UIMLButton::UIMLButton()
  280. : UIMLElement()
  281. {}
  282. bool UIMLButton::isApplicableFor(XML::Element& element)
  283. {
  284. return element.getName().istGleich("button");
  285. }
  286. Zeichnung* UIMLButton::parseElement(
  287. XML::Element& element, UIMLContainer& generalFactory)
  288. {
  289. Knopf* k = generalFactory.getFactory().createKnopf(
  290. generalFactory.getFactory().initParam);
  291. if (element.hasAttribute("style"))
  292. {
  293. Text style = element.getAttributeValue("style");
  294. if (!style.hatAt(0, "0x"))
  295. {
  296. style.insert(0, "0x");
  297. }
  298. k->setStyle((int)style);
  299. }
  300. return k;
  301. }
  302. void UIMLButton::layout(XML::Element& element,
  303. Zeichnung& z,
  304. int pWidth,
  305. int pHeight,
  306. UIMLContainer& generalLayouter)
  307. {
  308. if (element.hasAttribute("font-size"))
  309. ((Knopf*)&z)
  310. ->setSchriftSize(
  311. (unsigned char)(int)element.getAttributeValue("font-size"));
  312. ((Knopf*)&z)->setText(element.getText());
  313. UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter);
  314. }
  315. UIMLCheck::UIMLCheck()
  316. : UIMLElement()
  317. {}
  318. bool UIMLCheck::isApplicableFor(XML::Element& element)
  319. {
  320. return element.getName().istGleich("check");
  321. }
  322. Zeichnung* UIMLCheck::parseElement(
  323. XML::Element& element, UIMLContainer& generalFactory)
  324. {
  325. KontrollKnopf* k = generalFactory.getFactory().createKontrollKnopf(
  326. generalFactory.getFactory().initParam);
  327. if (element.hasAttribute("style"))
  328. {
  329. Text style = element.getAttributeValue("style");
  330. if (!style.hatAt(0, "0x"))
  331. {
  332. style.insert(0, "0x");
  333. }
  334. k->setStyle((int)style);
  335. }
  336. return k;
  337. }
  338. void UIMLCheck::layout(XML::Element& element,
  339. Zeichnung& z,
  340. int pWidth,
  341. int pHeight,
  342. UIMLContainer& generalLayouter)
  343. {
  344. ((KontrollKnopf*)&z)->setText(element.getText());
  345. ((KontrollKnopf*)&z)->setSText(element.getText());
  346. z.setStyle(
  347. KontrollKnopf::Style::Selected, element.hasAttribute("selected"));
  348. if (element.hasAttribute("font-size"))
  349. ((KontrollKnopf*)&z)
  350. ->setSSize(
  351. (unsigned char)(int)element.getAttributeValue("font-size"));
  352. UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter);
  353. }
  354. UIMLText::UIMLText()
  355. : UIMLElement()
  356. {}
  357. bool UIMLText::isApplicableFor(XML::Element& element)
  358. {
  359. return element.getName().istGleich("text");
  360. }
  361. Zeichnung* UIMLText::parseElement(
  362. XML::Element& element, UIMLContainer& generalFactory)
  363. {
  364. TextFeld* t = generalFactory.getFactory().createTextFeld(
  365. generalFactory.getFactory().initParam);
  366. if (element.hasAttribute("style"))
  367. {
  368. Text style = element.getAttributeValue("style");
  369. if (!style.hatAt(0, "0x"))
  370. {
  371. style.insert(0, "0x");
  372. }
  373. t->setStyle((int)style);
  374. }
  375. else
  376. {
  377. t->addStyle(TextFeld::Style::Text);
  378. }
  379. return t;
  380. }
  381. void UIMLText::layout(XML::Element& element,
  382. Zeichnung& z,
  383. int pWidth,
  384. int pHeight,
  385. UIMLContainer& generalLayouter)
  386. {
  387. if (element.hasAttribute("text-align-horizontal"))
  388. z.setStyle(TextFeld::Style::HCenter,
  389. element.getAttributeValue("text-align-horizontal")
  390. .istGleich("center"));
  391. if (element.hasAttribute("text-align-vertical"))
  392. z.setStyle(TextFeld::Style::VCenter,
  393. element.getAttributeValue("text-align-vertical")
  394. .istGleich("center"));
  395. if (element.hasAttribute("font-size"))
  396. ((TextFeld*)&z)
  397. ->setSchriftSize(
  398. (unsigned char)(int)element.getAttributeValue("font-size"));
  399. if (element.hasAttribute("disabled"))
  400. z.removeStyle(TextFeld::Style::Editierbar);
  401. ((TextFeld*)&z)->setText(element.getText());
  402. if (element.hasAttribute("width"))
  403. {
  404. Text w = element.getAttributeValue("width");
  405. if (w.istGleich("auto"))
  406. {
  407. z.setWidth(((TextFeld*)&z)->getNeededWidth());
  408. }
  409. }
  410. if (element.hasAttribute("height"))
  411. {
  412. Text h = element.getAttributeValue("height");
  413. if (h.istGleich("auto"))
  414. {
  415. z.setHeight(((TextFeld*)&z)->getNeededHeight());
  416. }
  417. }
  418. UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter);
  419. }
  420. UIMLTextArea::UIMLTextArea()
  421. : UIMLElement()
  422. {}
  423. bool UIMLTextArea::isApplicableFor(XML::Element& element)
  424. {
  425. return element.getName().istGleich("textarea");
  426. }
  427. Zeichnung* UIMLTextArea::parseElement(
  428. XML::Element& element, UIMLContainer& generalFactory)
  429. {
  430. TextFeld* t = generalFactory.getFactory().createTextFeld(
  431. generalFactory.getFactory().initParam);
  432. if (element.hasAttribute("style"))
  433. {
  434. Text style = element.getAttributeValue("style");
  435. if (!style.hatAt(0, "0x"))
  436. {
  437. style.insert(0, "0x");
  438. }
  439. t->setStyle((int)style);
  440. }
  441. else
  442. {
  443. t->addStyle(TextFeld::Style::TextGebiet);
  444. }
  445. return t;
  446. }
  447. void UIMLTextArea::layout(XML::Element& element,
  448. Zeichnung& z,
  449. int pWidth,
  450. int pHeight,
  451. UIMLContainer& generalLayouter)
  452. {
  453. if (element.hasAttribute("text-align-horizontal"))
  454. z.setStyle(TextFeld::Style::HCenter,
  455. element.getAttributeValue("text-align-horizontal")
  456. .istGleich("center"));
  457. if (element.hasAttribute("text-align-vertical"))
  458. z.setStyle(TextFeld::Style::VCenter,
  459. element.getAttributeValue("text-align-vertical")
  460. .istGleich("center"));
  461. if (element.hasAttribute("font-size"))
  462. ((TextFeld*)&z)
  463. ->setSchriftSize(
  464. (unsigned char)(int)element.getAttributeValue("font-size"));
  465. if (element.hasAttribute("disabled"))
  466. z.removeStyle(TextFeld::Style::Editierbar);
  467. ((TextFeld*)&z)->setText(element.getText());
  468. ((TextFeld*)&z)
  469. ->zTextRenderer()
  470. ->textFormatieren(((TextFeld*)&z)->zText(), z.getInnenBreite());
  471. if (element.hasAttribute("width"))
  472. {
  473. Text w = element.getAttributeValue("width");
  474. if (w.istGleich("auto"))
  475. {
  476. z.setWidth(((TextFeld*)&z)->getNeededWidth());
  477. }
  478. }
  479. if (element.hasAttribute("height"))
  480. {
  481. Text h = element.getAttributeValue("height");
  482. if (h.istGleich("auto"))
  483. {
  484. z.setHeight(((TextFeld*)&z)->getNeededHeight());
  485. }
  486. }
  487. UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter);
  488. }
  489. UIMLTable::UIMLTable()
  490. : UIMLElement()
  491. {}
  492. bool UIMLTable::isApplicableFor(XML::Element& element)
  493. {
  494. return element.getName().istGleich("table");
  495. }
  496. Zeichnung* UIMLTable::parseElement(
  497. XML::Element& element, UIMLContainer& generalFactory)
  498. {
  499. ObjTabelle* t = generalFactory.getFactory().createObjTabelle(
  500. generalFactory.getFactory().initParam);
  501. int index = 0;
  502. for (auto i = element.getChilds(); i; i++)
  503. {
  504. Text id;
  505. if (i->hasAttribute("id"))
  506. id = i->getAttributeValue("id");
  507. else
  508. {
  509. id = Text("_") += index++;
  510. i->setAttribute("id", id);
  511. }
  512. if (i->getName().istGleich("tr"))
  513. {
  514. t->addZeile(id);
  515. Text line = id;
  516. int c = 1;
  517. for (auto j = i->getChilds(); j; j++)
  518. {
  519. Zeichnung* z
  520. = generalFactory.parseElement(*i.val(), generalFactory);
  521. if (t->getSpaltenAnzahl() < c) t->addSpalte(Text(c - 1));
  522. if (z) t->setZeichnungZ(Text(c - 1), line, z);
  523. c++;
  524. }
  525. }
  526. }
  527. if (element.hasAttribute("style"))
  528. {
  529. Text style = element.getAttributeValue("style");
  530. if (!style.hatAt(0, "0x"))
  531. {
  532. style.insert(0, "0x");
  533. }
  534. t->setStyle((int)style);
  535. }
  536. return t;
  537. }
  538. void UIMLTable::layout(XML::Element& element,
  539. Zeichnung& z,
  540. int pWidth,
  541. int pHeight,
  542. UIMLContainer& generalLayouter)
  543. {
  544. if (element.hasAttribute("scroll"))
  545. {
  546. z.setStyle(ObjTabelle::Style::HScroll,
  547. element.getAttributeValue("scroll").istGleich("horizontal"));
  548. z.setStyle(ObjTabelle::Style::VScroll,
  549. element.getAttributeValue("scroll").istGleich("vertical"));
  550. z.setStyle(ObjTabelle::Style::scroll,
  551. element.getAttributeValue("scroll").istGleich("both"));
  552. }
  553. UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter);
  554. ObjTabelle* objT = (ObjTabelle*)&z;
  555. if (objT->getZeilenAnzahl() > 0)
  556. {
  557. if (element.hasAttribute("line-height"))
  558. {
  559. int height = (int)element.getAttributeValue("line-height");
  560. for (int i = 0; i < objT->getZeilenAnzahl(); i++)
  561. objT->setZeilenHeight(i, height);
  562. }
  563. for (int i = 0; i < objT->getSpaltenAnzahl(); i++)
  564. {
  565. if (objT->zZeichnung(i, 0))
  566. objT->setSpaltenBreite(i, objT->zZeichnung(i, 0)->getBreite());
  567. }
  568. }
  569. }
  570. UIMLFrame::UIMLFrame()
  571. : UIMLElement()
  572. {}
  573. bool UIMLFrame::isApplicableFor(XML::Element& element)
  574. {
  575. return element.getName().istGleich("frame");
  576. }
  577. Zeichnung* UIMLFrame::parseElement(
  578. XML::Element& element, UIMLContainer& generalFactory)
  579. {
  580. Fenster* f = generalFactory.getFactory().createFenster(
  581. generalFactory.getFactory().initParam);
  582. if (element.hasAttribute("style"))
  583. {
  584. Text style = element.getAttributeValue("style");
  585. if (!style.hatAt(0, "0x"))
  586. {
  587. style.insert(0, "0x");
  588. }
  589. f->setStyle((int)style);
  590. }
  591. for (auto i = element.getChilds(); i; i++)
  592. {
  593. Zeichnung* z = generalFactory.parseElement(*i.val(), generalFactory);
  594. if (z) f->addMember(z);
  595. }
  596. return f;
  597. }
  598. void UIMLFrame::layout(XML::Element& element,
  599. Zeichnung& z,
  600. int pWidth,
  601. int pHeight,
  602. UIMLContainer& generalLayouter)
  603. {
  604. if (element.hasAttribute("title"))
  605. ((Fenster*)&z)->setTitel(element.getAttributeValue("title"));
  606. if (element.hasAttribute("title-height"))
  607. ((Fenster*)&z)
  608. ->zTTextFeld()
  609. ->setSize(((Fenster*)&z)->zTTextFeld()->getBreite(),
  610. (int)element.getAttributeValue("title-height"));
  611. UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter);
  612. }
  613. // Erstellt eine UIML View
  614. UIMLView::UIMLView()
  615. : ZeichnungHintergrund()
  616. {
  617. style = Style::MEIgnoreInside | Style::MEIgnoreParentInside
  618. | Style::MEIgnoreSichtbar | Style::MEIgnoreVerarbeitet;
  619. members = new Trie<Zeichnung>();
  620. dom = 0;
  621. nextId = 0;
  622. memset(&init, 0, sizeof(UIInit));
  623. addKnownElement(new UIMLTextField());
  624. addKnownElement(new UIMLButton());
  625. addKnownElement(new UIMLCheck());
  626. addKnownElement(new UIMLText());
  627. addKnownElement(new UIMLTextArea());
  628. addKnownElement(new UIMLTable());
  629. addKnownElement(new UIMLFrame());
  630. }
  631. // Erstellt eine UIML View zu einem UIML Text
  632. // uiml: Ein xml element gemät des ksg uiml standarts
  633. UIMLView::UIMLView(XML::Element* uiml, UIInit& init)
  634. : UIMLView()
  635. {
  636. this->init = init;
  637. setUIML(uiml);
  638. }
  639. // Erstellt eine UIML View zu einem UIML Text
  640. // uiml: Ein xml text gemät des ksg uiml standarts
  641. UIMLView::UIMLView(Text uiml, UIInit& init)
  642. : UIMLView()
  643. {
  644. this->init = init;
  645. setUIML(uiml);
  646. }
  647. UIMLView::~UIMLView()
  648. {
  649. if (dom) dom->release();
  650. members->release();
  651. }
  652. // Verarbeitet ein Maus Ereignis. Wird vom Framework automatisch aufgerufen.
  653. // me: Das Ereignis
  654. void UIMLView::doMausEreignis(MausEreignis& me, bool userRet)
  655. {
  656. if (dom)
  657. {
  658. bool verarbeitet = me.verarbeitet;
  659. me.verarbeitet |= hatStyleNicht(Style::Sichtbar);
  660. bool insideParent = me.insideParent;
  661. if (!hatStyle(Style::Sichtbar) || !me.insideParent || me.verarbeitet
  662. || me.mx < 0 || me.my < 0 || me.mx >= gr.x || me.my >= gr.y
  663. || !userRet)
  664. me.insideParent = 0;
  665. int rbr = 0;
  666. if (hatStyle(Style::Rahmen) && rahmen) rbr = rahmen->getRBreite();
  667. me.mx -= rbr;
  668. me.my -= rbr;
  669. if (hatStyle(Style::VScroll) && vertikalScrollBar)
  670. me.my += vertikalScrollBar->getScroll();
  671. if (hatStyle(Style::HScroll) && horizontalScrollBar)
  672. me.mx += horizontalScrollBar->getScroll();
  673. if (dom)
  674. {
  675. for (auto i = dom->getChilds(); i; i++)
  676. { // TODO render elements backwards
  677. Zeichnung* z = members->z(i->getAttributeValue("id"),
  678. i->getAttributeValue("id").getLength());
  679. if (z) z->doPublicMausEreignis(me);
  680. }
  681. }
  682. me.mx += rbr;
  683. me.my += rbr;
  684. if (hatStyle(Style::VScroll) && vertikalScrollBar)
  685. me.my -= vertikalScrollBar->getScroll();
  686. if (hatStyle(Style::HScroll) && horizontalScrollBar)
  687. me.mx -= horizontalScrollBar->getScroll();
  688. if (!hatStyle(Style::Sichtbar) || !me.insideParent || me.verarbeitet
  689. || me.mx < 0 || me.my < 0 || me.mx >= gr.x || me.my >= gr.y
  690. || !userRet)
  691. me.insideParent = insideParent;
  692. else
  693. me.verarbeitet = 1;
  694. if (hatStyleNicht(Style::Sichtbar)) me.verarbeitet = verarbeitet;
  695. }
  696. }
  697. //! entfernt alle bekannten elemente, die im uiml verwendet werden können
  698. void UIMLView::removeAllKnownElements()
  699. {
  700. knownElements.leeren();
  701. }
  702. //! fügt ein neues bekanntes element hinzu, dass danach im uiml verwendet werden
  703. //! kann.
  704. void UIMLView::addKnownElement(UIMLElement* element)
  705. {
  706. knownElements.add(element);
  707. }
  708. //! prüft, ob ein xml Element ein bekanntes uiml Element ist;
  709. bool UIMLView::isKnownElement(XML::Element* zElement)
  710. {
  711. for (UIMLElement* element : knownElements)
  712. {
  713. if (element->isApplicableFor(*zElement)) return 1;
  714. }
  715. return 0;
  716. }
  717. // setzt den inhalt der view
  718. // uiml: Ein xml element gemät des ksg uiml standarts
  719. void UIMLView::setUIML(XML::Element* uiml)
  720. {
  721. if (dom) dom->release();
  722. dom = uiml;
  723. members->leeren();
  724. nextId = 0;
  725. if (dom)
  726. {
  727. for (auto i = dom->getChilds(); i; i++)
  728. {
  729. Zeichnung* z = parseElement(*i.val(), *this);
  730. if (z) z->release();
  731. }
  732. }
  733. }
  734. // setzt den inhalt der view
  735. // uiml: Ein xml text gemät des ksg uiml standarts
  736. void UIMLView::setUIML(Text uiml)
  737. {
  738. setUIML(new XML::Element(uiml));
  739. }
  740. // Gibt eine zeichnung zurück, welche in uiml eine bestimmte id hat
  741. // id: die id der Zeichnung
  742. Zeichnung* UIMLView::zZeichnungById(const char* id)
  743. {
  744. return members->z(id, textLength(id));
  745. }
  746. // Gibt eine zeichnung zurück, welche in uiml eine bestimmte id hat
  747. // id: die id der Zeichnung
  748. Zeichnung* UIMLView::getZeichnungById(const char* id)
  749. {
  750. return members->get(id, textLength(id));
  751. }
  752. // aktualisiert größe und position aller Zeichnungen gemäß den spezifikationen
  753. // in UIML
  754. void UIMLView::layout()
  755. {
  756. if (dom)
  757. {
  758. for (auto i = dom->getChilds(); i; i++)
  759. {
  760. Text id = i->getAttributeValue("id");
  761. Zeichnung* z = zZeichnungById(id);
  762. if (z)
  763. {
  764. layout(*i.val(),
  765. *z,
  766. this->getInnenBreite(),
  767. this->getInnenHeight(),
  768. *this);
  769. }
  770. }
  771. }
  772. }
  773. // fügt ein element hinzu
  774. // uiml: Ein xml text gemät des KSG UIML standarts, welcher das neue Objekt
  775. // darstellt
  776. Text UIMLView::addMember(Text uiml)
  777. {
  778. XML::Element* e = new XML::Element(uiml);
  779. Zeichnung* z = parseElement(*e, *this);
  780. if (z)
  781. {
  782. dom->addChildAtFront(e);
  783. z->release();
  784. }
  785. return e->getAttributeValue("id");
  786. }
  787. // fügt ein element zu einem Elternelement hinzu (funktioniert momentan nur mit
  788. // frame Objekten)
  789. // uiml: Ein xml text gemät des KSG UIML standarts, welcher das neue Objekt
  790. // darstellt
  791. Text UIMLView::addMember(Text uiml, Text parentId)
  792. {
  793. XML::Element* e = new XML::Element(uiml);
  794. XML::Editor ed = dom->selectChildren();
  795. while (ed.begin())
  796. {
  797. XML::Editor ed2 = ed.whereAttributeEquals("id", parentId);
  798. if (ed2.begin())
  799. {
  800. if (ed2.begin()->getName().istGleich("frame"))
  801. {
  802. Zeichnung* z = parseElement(*e, *this);
  803. if (z)
  804. {
  805. dynamic_cast<Fenster*>(
  806. members->z(parentId, parentId.getLength()))
  807. ->addMember(z);
  808. ed2.begin()->addChild(e);
  809. }
  810. return e->getAttributeValue("id");
  811. }
  812. }
  813. ed = ed.selectChildren();
  814. }
  815. e->release();
  816. return "";
  817. }
  818. // entfernt ein element
  819. // id: id des Elements
  820. void UIMLView::removeMember(Text id)
  821. {
  822. XML::Editor e = dom->selectChildsByAttribute("id", id);
  823. e.remove();
  824. members->remove(id, id.getLength());
  825. }
  826. // Verarbeitet ein Tastatur Ereignis. Wird vom Framework automatisch aufgerufen
  827. // te: Das Ereignis
  828. void UIMLView::doTastaturEreignis(TastaturEreignis& te)
  829. {
  830. bool verarbeitet = te.verarbeitet;
  831. ZeichnungHintergrund::doTastaturEreignis(te);
  832. te.verarbeitet = verarbeitet;
  833. if (dom)
  834. {
  835. for (auto i = dom->getChilds(); i; i++)
  836. { // TODO render elements backwards
  837. Zeichnung* z = members->z(i->getAttributeValue("id"),
  838. i->getAttributeValue("id").getLength());
  839. if (z) z->doTastaturEreignis(te);
  840. }
  841. }
  842. }
  843. // Updated den Zeichenhintergrund
  844. // tickVal: Die vergangene Zeit in Sekunden, die seit dem Letzten Aufruf dieser
  845. // Funktion verstrichen ist return: 1, wenn das Bild neu gezeichnet werden
  846. // muss. 0 sonnst
  847. bool UIMLView::tick(double tickVal)
  848. {
  849. if (dom)
  850. {
  851. for (auto i = dom->getChilds(); i; i++)
  852. { // TODO render elements backwards
  853. Zeichnung* z = members->z(i->getAttributeValue("id"),
  854. i->getAttributeValue("id").getLength());
  855. if (z) rend |= z->tick(tickVal);
  856. }
  857. }
  858. return ZeichnungHintergrund::tick(tickVal);
  859. }
  860. // Zeichnet den Hintergrund eines Zeichnunges nach rObj
  861. void UIMLView::render(Bild& rObj)
  862. {
  863. if (hatStyle(Zeichnung::Style::Sichtbar))
  864. {
  865. ZeichnungHintergrund::render(rObj);
  866. if (dom)
  867. {
  868. if (!rObj.setDrawOptions(pos.x + getRahmenBreite(),
  869. pos.y + getRahmenBreite(),
  870. gr.x + getRahmenBreite() * 2,
  871. gr.y + getRahmenBreite() * 2))
  872. return;
  873. bool vSc = hatStyle(Style::VScroll) && vertikalScrollBar;
  874. bool hSc = hatStyle(Style::HScroll) && horizontalScrollBar;
  875. rObj.addScrollOffset(hSc ? horizontalScrollBar->getScroll() : 0,
  876. vSc ? vertikalScrollBar->getScroll() : 0);
  877. for (int i = dom->getChildCount() - 1; i >= 0; i--)
  878. { // TODO render elements backwards
  879. XML::Element* e = dom->zChild(i);
  880. Zeichnung* z = members->z(e->getAttributeValue("id"),
  881. e->getAttributeValue("id").getLength());
  882. if (z) z->render(rObj);
  883. }
  884. rObj.releaseDrawOptions();
  885. }
  886. }
  887. }
  888. // Gibt den Dom Tree ohne erhöhten reference counter zurück
  889. // Änderungen am Dom Tree sollten vermieden werden (nur änderungen von
  890. // attributen einzelner elemente sind erlaubt)
  891. XML::Element* UIMLView::zDom() const
  892. {
  893. return dom;
  894. }
  895. // Gibt den Dom Tree zurück
  896. // Änderungen am Dom Tree sollten vermieden werden (nur änderungen von
  897. // attributen einzelner elemente sind erlaubt)
  898. XML::Element* UIMLView::getDom() const
  899. {
  900. return dom ? dynamic_cast<XML::Element*>(dom->getThis()) : 0;
  901. }
  902. bool UIMLView::isApplicableFor(XML::Element& element)
  903. {
  904. for (UIMLElement* e : knownElements)
  905. {
  906. if (e->isApplicableFor(element)) return 1;
  907. }
  908. return 0;
  909. }
  910. Zeichnung* UIMLView::parseElement(
  911. XML::Element& element, UIMLContainer& generalFactory)
  912. {
  913. Text id;
  914. if (element.hasAttribute("id"))
  915. id = element.getAttributeValue("id");
  916. else
  917. {
  918. id = Text("_") += nextId++;
  919. element.setAttribute("id", id);
  920. }
  921. Zeichnung* z = members->z(id, id.getLength());
  922. if (!z)
  923. {
  924. // precompute attributes
  925. if (element.hasAttribute("margin"))
  926. {
  927. Text m = element.getAttributeValue("margin");
  928. if (!element.hasAttribute("margin-left"))
  929. element.setAttribute("margin-left", m);
  930. if (!element.hasAttribute("margin-top"))
  931. element.setAttribute("margin-top", m);
  932. if (!element.hasAttribute("margin-right"))
  933. element.setAttribute("margin-right", m);
  934. if (!element.hasAttribute("margin-bottom"))
  935. element.setAttribute("margin-bottom", m);
  936. }
  937. if (element.hasAttribute("class"))
  938. {
  939. Text c = element.getAttributeValue("class");
  940. while (1)
  941. {
  942. Text* t;
  943. if (c.hat(","))
  944. t = c.getTeilText(0, c.positionVon(','));
  945. else
  946. t = new Text(c);
  947. XML::Editor ce
  948. = dom->selectChildsByName("class").whereAttributeEquals(
  949. "id", *t);
  950. for (auto i = ce.begin(); i; i++)
  951. {
  952. for (auto j = i->getAttributeNames(),
  953. k = i->getAttributeValues();
  954. j && k;
  955. j++, k++)
  956. {
  957. if (!element.hasAttribute(j->getText()))
  958. element.setAttribute(j->getText(), i->getText());
  959. }
  960. }
  961. t->release();
  962. if (c.hat(","))
  963. c.remove(0, c.positionVon(',' + 1));
  964. else
  965. break;
  966. }
  967. }
  968. if (element.hasAttribute("text-align"))
  969. {
  970. if (!element.hasAttribute("text-align-horizontal"))
  971. element.setAttribute("text-align-horizontal",
  972. element.getAttributeValue("text-align"));
  973. if (!element.hasAttribute("text-align-vertical"))
  974. element.setAttribute("text-align-vertical",
  975. element.getAttributeValue("text-align"));
  976. }
  977. // create objects
  978. for (UIMLElement* e : knownElements)
  979. {
  980. if (e->isApplicableFor(element))
  981. {
  982. z = e->parseElement(element, *this);
  983. break;
  984. }
  985. }
  986. if (z)
  987. members->set(
  988. id, id.getLength(), dynamic_cast<Zeichnung*>(z->getThis()));
  989. }
  990. else
  991. z->getThis();
  992. return z;
  993. }
  994. void UIMLView::layout(XML::Element& element,
  995. Zeichnung& z,
  996. int pWidth,
  997. int pHeight,
  998. UIMLContainer& generalLayouter)
  999. {
  1000. for (UIMLElement* e : knownElements)
  1001. {
  1002. if (e->isApplicableFor(element))
  1003. {
  1004. e->layout(element, z, pWidth, pHeight, *this);
  1005. break;
  1006. }
  1007. }
  1008. }
  1009. const UIInit& UIMLView::getFactory()
  1010. {
  1011. return init;
  1012. }
  1013. //! calculates the needed size for all content elements to be visible
  1014. Punkt UIMLView::calculateContentSize()
  1015. {
  1016. Punkt maxP(0, 0);
  1017. for (int i = dom->getChildCount() - 1; i >= 0; i--)
  1018. { // TODO render elements backwards
  1019. XML::Element* e = dom->zChild(i);
  1020. Zeichnung* z = members->z(
  1021. e->getAttributeValue("id"), e->getAttributeValue("id").getLength());
  1022. if (z)
  1023. {
  1024. maxP.x = MAX(maxP.x, z->getPosition().x + z->getBreite());
  1025. maxP.y = MAX(maxP.y, z->getPosition().y + z->getHeight());
  1026. }
  1027. }
  1028. maxP.x += 2 * getRahmenBreite();
  1029. maxP.y += 2 * getRahmenBreite();
  1030. return maxP;
  1031. }