UIMLView.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. #include "UIMLView.h"
  2. #include "XML.h"
  3. #include "TextFeld.h"
  4. #include "Knopf.h"
  5. #include "Tabelle.h"
  6. #include "Schrift.h"
  7. #include "Bildschirm.h"
  8. using namespace Framework;
  9. // Erstellt eine UIML View
  10. UIMLView::UIMLView()
  11. : ZeichnungHintergrund()
  12. {
  13. members = new Trie< Zeichnung >();
  14. dom = 0;
  15. nextId = 0;
  16. memset( &init, 0, sizeof( UIInit ) );
  17. }
  18. // Erstellt eine UIML View zu einem UIML Text
  19. // uiml: Ein xml element gemät des ksg uiml standarts
  20. UIMLView::UIMLView( XML::Element *uiml, UIInit &init )
  21. : ZeichnungHintergrund()
  22. {
  23. this->init = init;
  24. members = new Trie< Zeichnung >();
  25. dom = 0;
  26. nextId = 0;
  27. setUIML( uiml );
  28. }
  29. // Erstellt eine UIML View zu einem UIML Text
  30. // uiml: Ein xml text gemät des ksg uiml standarts
  31. UIMLView::UIMLView( Text uiml, UIInit &init )
  32. {
  33. this->init = init;
  34. members = new Trie< Zeichnung >();
  35. dom = 0;
  36. setUIML( uiml );
  37. }
  38. UIMLView::~UIMLView()
  39. {
  40. if( dom )
  41. dom->release();
  42. members->release();
  43. }
  44. void UIMLView::parseTable( Iterator<XML::Element*> childs, ObjTabelle *table )
  45. {
  46. for( auto i = childs; i; i++ )
  47. {
  48. Text id;
  49. if( i->hasAttribute( "id" ) )
  50. id = i->getAttributeValue( "id" );
  51. else
  52. id = Text( "_" ) += nextId++;
  53. if( i->getName().istGleich( "tr" ) )
  54. {
  55. table->addZeile( id );
  56. Text line = id;
  57. int c = 1;
  58. for( auto j = i->getChilds(); j; j++ )
  59. {
  60. Zeichnung *z = parseElement( j._ );
  61. if( table->getSpaltenAnzahl() < c )
  62. table->addSpalte( Text( c - 1 ) );
  63. if( z )
  64. table->setZeichnungZ( c - 1, line, z->getThis() );
  65. c++;
  66. }
  67. }
  68. }
  69. }
  70. Zeichnung *UIMLView::parseElement( XML::Element *e )
  71. {
  72. Text id;
  73. if( e->hasAttribute( "id" ) )
  74. id = e->getAttributeValue( "id" );
  75. else
  76. {
  77. id = Text( "_" ) += nextId++;
  78. e->setAttribute( "id", id );
  79. }
  80. Zeichnung *z = members->z( id );
  81. if( !z )
  82. {
  83. // precompute attributes
  84. if( e->hasAttribute( "margin" ) )
  85. {
  86. Text m = e->getAttributeValue( "margin" );
  87. if( !e->hasAttribute( "margin-left" ) )
  88. e->setAttribute( "margin-left", m );
  89. if( !e->hasAttribute( "margin-top" ) )
  90. e->setAttribute( "margin-top", m );
  91. if( !e->hasAttribute( "margin-right" ) )
  92. e->setAttribute( "margin-right", m );
  93. if( !e->hasAttribute( "margin-bottom" ) )
  94. e->setAttribute( "margin-bottom", m );
  95. }
  96. // create objects
  97. if( e->getName().istGleich( "textfield" ) )
  98. {
  99. TextFeld *t = init.createTextFeld( init.initParam );
  100. t->setStyle( TextFeld::Style::TextFeld );
  101. t->setText( e->getText() );
  102. z = t;
  103. }
  104. if( e->getName().istGleich( "text" ) )
  105. {
  106. TextFeld *t = init.createTextFeld( init.initParam );
  107. t->setStyle( TextFeld::Style::Text );
  108. t->setText( e->getText() );
  109. z = t;
  110. }
  111. if( e->getName().istGleich( "textarea" ) )
  112. {
  113. TextFeld *t = init.createTextFeld( init.initParam );
  114. t->setStyle( TextFeld::Style::TextGebiet );
  115. t->setText( e->getText() );
  116. z = t;
  117. }
  118. if( e->getName().istGleich( "button" ) )
  119. {
  120. Knopf *k = init.createKnopf( init.initParam );
  121. k->setText( e->getText() );
  122. z = k;
  123. }
  124. if( e->getName().istGleich( "table" ) )
  125. {
  126. ObjTabelle *t = init.createObjTabelle( init.initParam );
  127. parseTable( e->getChilds(), t );
  128. z = t;
  129. }
  130. // add general attributes
  131. if( z && e->hasAttribute( "tooltip" ) )
  132. z->setToolTipText( e->getAttributeValue( "tooltip" ), init.initParam.bildschirm );
  133. if( z && e->hasAttribute( "style" ) )
  134. z->setStyle( (__int64)e->getAttributeValue( "style" ) );
  135. members->set( id, z );
  136. }
  137. return z;
  138. }
  139. void UIMLView::layout( XML::Element *e )
  140. {
  141. Text id = e->getAttributeValue( "id" );
  142. Zeichnung *z = members->z( id );
  143. if( z )
  144. {
  145. int width = z->getBreite();
  146. int height = z->getHeight();
  147. if( e->hasAttribute( "width" ) )
  148. {
  149. Text w = e->getAttributeValue( "width" );
  150. width = w;
  151. if( w.getText()[ w.getLength() - 1 ] == '%' )
  152. width = ( getBreite() / 100 ) * width;
  153. }
  154. if( e->hasAttribute( "height" ) )
  155. {
  156. Text h = e->getAttributeValue( "height" );
  157. height = h;
  158. if( h.getText()[ h.getLength() - 1 ] == '%' )
  159. height = ( getHeight() / 100 ) * height;
  160. }
  161. z->setSize( width, height );
  162. if( e->hasAttribute( "align-left" ) )
  163. {
  164. Text la = e->getAttributeValue( "align-left" );
  165. int x;
  166. if( la.istGleich( "start" ) )
  167. x = 0;
  168. else if( la.istGleich( "end" ) )
  169. x = getBreite();
  170. else
  171. {
  172. XML::Editor ed = e->zParent()->selectChildsByAttribute( "id", la );
  173. for( auto i = ed.getIterator(); i; i++ )
  174. layout( i );
  175. Zeichnung *laz = members->z( la );
  176. if( laz )
  177. x = laz->getX() + laz->getBreite();
  178. }
  179. if( e->hasAttribute( "margin-left" ) )
  180. {
  181. Text mt = e->getAttributeValue( "margin-left" );
  182. int m = mt;
  183. if( mt.getText()[ mt.getLength() - 1 ] == '%' )
  184. m = ( getBreite() / 100 ) * m;
  185. x += m;
  186. }
  187. z->setX( x );
  188. }
  189. else if( e->hasAttribute( "align-right" ) )
  190. {
  191. Text ra = e->getAttributeValue( "align-right" );
  192. int x;
  193. if( ra.istGleich( "start" ) )
  194. x = -z->getBreite();
  195. else if( ra.istGleich( "end" ) )
  196. x = getBreite() - z->getBreite();
  197. else
  198. {
  199. XML::Editor ed = e->zParent()->selectChildsByAttribute( "id", ra );
  200. for( auto i = ed.getIterator(); i; i++ )
  201. layout( i );
  202. Zeichnung *raz = members->z( ra );
  203. if( raz )
  204. x = raz->getX() - z->getBreite();
  205. }
  206. if( e->hasAttribute( "margin-right" ) )
  207. {
  208. Text mt = e->getAttributeValue( "margin-right" );
  209. int m = mt;
  210. if( mt.getText()[ mt.getLength() - 1 ] == '%' )
  211. m = ( getBreite() / 100 ) * m;
  212. x -= m;
  213. }
  214. z->setX( x );
  215. }
  216. if( e->hasAttribute( "align-top" ) )
  217. {
  218. Text ta = e->getAttributeValue( "align-top" );
  219. int y;
  220. if( ta.istGleich( "start" ) )
  221. y = 0;
  222. else if( ta.istGleich( "end" ) )
  223. y = getHeight();
  224. else
  225. {
  226. XML::Editor ed = e->zParent()->selectChildsByAttribute( "id", ta );
  227. for( auto i = ed.getIterator(); i; i++ )
  228. layout( i );
  229. Zeichnung *taz = members->z( ta );
  230. if( taz )
  231. y = taz->getY() + taz->getHeight();
  232. }
  233. if( e->hasAttribute( "margin-top" ) )
  234. {
  235. Text mt = e->getAttributeValue( "margin-top" );
  236. int m = mt;
  237. if( mt.getText()[ mt.getLength() - 1 ] == '%' )
  238. m = ( getHeight() / 100 ) * m;
  239. y += m;
  240. }
  241. z->setY( y );
  242. }
  243. else if( e->hasAttribute( "align-bottom" ) )
  244. {
  245. Text ba = e->getAttributeValue( "align-bottom" );
  246. int y;
  247. if( ba.istGleich( "start" ) )
  248. y = -z->getHeight();
  249. else if( ba.istGleich( "end" ) )
  250. y = getHeight() - z->getHeight();
  251. else
  252. {
  253. XML::Editor ed = e->zParent()->selectChildsByAttribute( "id", ba );
  254. for( auto i = ed.getIterator(); i; i++ )
  255. layout( i );
  256. Zeichnung *baz = members->z( ba );
  257. if( baz )
  258. y = baz->getY() - z->getHeight();
  259. }
  260. if( e->hasAttribute( "margin-bottom" ) )
  261. {
  262. Text mt = e->getAttributeValue( "margin-bottom" );
  263. int m = mt;
  264. if( mt.getText()[ mt.getLength() - 1 ] == '%' )
  265. m = ( getHeight() / 100 ) * m;
  266. y -= m;
  267. }
  268. z->setY( y );
  269. }
  270. int x = z->getX();
  271. int y = z->getY();
  272. if( e->hasAttribute( "x" ) )
  273. {
  274. Text xt = e->getAttributeValue( "x" );
  275. x = xt;
  276. if( xt.getText()[ xt.getLength() - 1 ] == '%' )
  277. x = ( getBreite() / 100 ) * x;
  278. }
  279. if( e->hasAttribute( "y" ) )
  280. {
  281. Text yt = e->getAttributeValue( "y" );
  282. y = yt;
  283. if( yt.getText()[ yt.getLength() - 1 ] == '%' )
  284. y = ( getHeight() / 100 ) * y;
  285. }
  286. z->setPosition( x, y );
  287. }
  288. }
  289. // setzt den inhalt der view
  290. // uiml: Ein xml element gemät des ksg uiml standarts
  291. void UIMLView::setUIML( XML::Element *uiml )
  292. {
  293. if( dom )
  294. dom->release();
  295. dom = uiml;
  296. members->leeren();
  297. nextId = 0;
  298. if( dom )
  299. {
  300. for( auto i = dom->getChilds(); i; i++ )
  301. {
  302. parseElement( i._ );
  303. }
  304. }
  305. }
  306. // setzt den inhalt der view
  307. // uiml: Ein xml text gemät des ksg uiml standarts
  308. void UIMLView::setUIML( Text uiml )
  309. {
  310. setUIML( new XML::Element( uiml ) );
  311. }
  312. // Gibt eine zeichnung zurück, welche in uiml eine bestimmte id hat
  313. // id: die id der Zeichnung
  314. Zeichnung *UIMLView::zZeichnung( Text id )
  315. {
  316. return members->z( id );
  317. }
  318. // aktualisiert größe und position aller Zeichnungen gemäß den spezifikationen in UIML
  319. void UIMLView::layout()
  320. {
  321. if( dom )
  322. {
  323. for( auto i = dom->getChilds(); i; i++ )
  324. {
  325. layout( i._ );
  326. }
  327. }
  328. }
  329. // Verarbeitet ein Maus Ereignis. Wird vom Framework automatisch aufgerufen.
  330. // me: Das Ereignis
  331. void UIMLView::doMausEreignis( MausEreignis &me )
  332. {
  333. bool verarbeitet = me.verarbeitet;
  334. ZeichnungHintergrund::doMausEreignis( me );
  335. me.verarbeitet = verarbeitet;
  336. for( auto i = members->getIterator(); i; i++ )
  337. {
  338. // TODO consider only first level childs
  339. if( i._ )
  340. {
  341. i->doMausEreignis( me );
  342. }
  343. }
  344. }
  345. // Verarbeitet ein Tastatur Ereignis. Wird vom Framework automatisch aufgerufen
  346. // te: Das Ereignis
  347. void UIMLView::doTastaturEreignis( TastaturEreignis &te )
  348. {
  349. bool verarbeitet = te.verarbeitet;
  350. ZeichnungHintergrund::doTastaturEreignis( te );
  351. te.verarbeitet = verarbeitet;
  352. for( auto i = members->getIterator(); i; i++ )
  353. {
  354. // TODO consider only first level childs
  355. if( i._ )
  356. {
  357. i->doTastaturEreignis( te );
  358. }
  359. }
  360. }
  361. // Updated den Zeichenhintergrund
  362. // tickVal: Die vergangene Zeit in Sekunden, die seit dem Letzten Aufruf dieser Funktion verstrichen ist
  363. // return: 1, wenn das Bild neu gezeichnet werden muss. 0 sonnst
  364. bool UIMLView::tick( double tickVal )
  365. {
  366. for( auto i = members->getIterator(); i; i++ )
  367. {
  368. // TODO tick only first level childs
  369. if( i._ )
  370. {
  371. rend |= i->tick( tickVal );
  372. }
  373. }
  374. return ZeichnungHintergrund::tick( tickVal );
  375. }
  376. // Zeichnet den Hintergrund eines Zeichnunges nach rObj
  377. void UIMLView::render( Bild &rObj )
  378. {
  379. ZeichnungHintergrund::render( rObj );
  380. for( auto i = members->getIterator(); i; i++ )
  381. { // TODO render elements backwards
  382. // TODO render only first level childs
  383. if( i._ )
  384. {
  385. i->render( rObj );
  386. }
  387. }
  388. }