#include "UIMLView.h" #include "XML.h" #include "TextFeld.h" #include "Knopf.h" #include "Tabelle.h" #include "Schrift.h" #include "Bildschirm.h" using namespace Framework; // Erstellt eine UIML View UIMLView::UIMLView() : ZeichnungHintergrund() { members = new Trie< Zeichnung >(); dom = 0; nextId = 0; memset( &init, 0, sizeof( UIInit ) ); } // Erstellt eine UIML View zu einem UIML Text // uiml: Ein xml element gemät des ksg uiml standarts UIMLView::UIMLView( XML::Element *uiml, UIInit &init ) : ZeichnungHintergrund() { this->init = init; members = new Trie< Zeichnung >(); dom = 0; nextId = 0; setUIML( uiml ); } // Erstellt eine UIML View zu einem UIML Text // uiml: Ein xml text gemät des ksg uiml standarts UIMLView::UIMLView( Text uiml, UIInit &init ) { this->init = init; members = new Trie< Zeichnung >(); dom = 0; setUIML( uiml ); } UIMLView::~UIMLView() { if( dom ) dom->release(); members->release(); } void UIMLView::parseTable( Iterator childs, ObjTabelle *table ) { for( auto i = childs; i; i++ ) { Text id; if( i->hasAttribute( "id" ) ) id = i->getAttributeValue( "id" ); else id = Text( "_" ) += nextId++; if( i->getName().istGleich( "tr" ) ) { table->addZeile( id ); Text line = id; int c = 1; for( auto j = i->getChilds(); j; j++ ) { Zeichnung *z = parseElement( j._ ); if( table->getSpaltenAnzahl() < c ) table->addSpalte( Text( c - 1 ) ); if( z ) table->setZeichnungZ( c - 1, line, z->getThis() ); c++; } } } } Zeichnung *UIMLView::parseElement( XML::Element *e ) { Text id; if( e->hasAttribute( "id" ) ) id = e->getAttributeValue( "id" ); else { id = Text( "_" ) += nextId++; e->setAttribute( "id", id ); } Zeichnung *z = members->z( id ); if( !z ) { // precompute attributes if( e->hasAttribute( "margin" ) ) { Text m = e->getAttributeValue( "margin" ); if( !e->hasAttribute( "margin-left" ) ) e->setAttribute( "margin-left", m ); if( !e->hasAttribute( "margin-top" ) ) e->setAttribute( "margin-top", m ); if( !e->hasAttribute( "margin-right" ) ) e->setAttribute( "margin-right", m ); if( !e->hasAttribute( "margin-bottom" ) ) e->setAttribute( "margin-bottom", m ); } // create objects if( e->getName().istGleich( "textfield" ) ) { TextFeld *t = init.createTextFeld( init.initParam ); t->setStyle( TextFeld::Style::TextFeld ); t->setText( e->getText() ); z = t; } if( e->getName().istGleich( "text" ) ) { TextFeld *t = init.createTextFeld( init.initParam ); t->setStyle( TextFeld::Style::Text ); t->setText( e->getText() ); z = t; } if( e->getName().istGleich( "textarea" ) ) { TextFeld *t = init.createTextFeld( init.initParam ); t->setStyle( TextFeld::Style::TextGebiet ); t->setText( e->getText() ); z = t; } if( e->getName().istGleich( "button" ) ) { Knopf *k = init.createKnopf( init.initParam ); k->setText( e->getText() ); z = k; } if( e->getName().istGleich( "table" ) ) { ObjTabelle *t = init.createObjTabelle( init.initParam ); parseTable( e->getChilds(), t ); z = t; } // add general attributes if( z && e->hasAttribute( "tooltip" ) ) z->setToolTipText( e->getAttributeValue( "tooltip" ), init.initParam.bildschirm ); if( z && e->hasAttribute( "style" ) ) z->setStyle( (__int64)e->getAttributeValue( "style" ) ); members->set( id, z ); } return z; } void UIMLView::layout( XML::Element *e ) { if( e->hasAttribute( "width" ) ) { Text id = e->getAttributeValue( "id" ); Zeichnung *z = members->z( id ); if( z ) { int width = z->getBreite(); int height = z->getHeight(); if( e->hasAttribute( "width" ) ) { Text w = e->getAttributeValue( "width" ); width = w; if( w.getText()[ w.getLength() - 1 ] == '%' ) width = ( getBreite() / 100 ) * width; } if( e->hasAttribute( "height" ) ) { Text h = e->getAttributeValue( "height" ); height = h; if( h.getText()[ h.getLength() - 1 ] == '%' ) height = ( getHeight() / 100 ) * height; } z->setSize( width, height ); if( e->hasAttribute( "align-left" ) ) { Text la = e->getAttributeValue( "align-left" ); XML::Editor ed = e->zParent()->selectChildsByAttribute( "id", la ); for( auto i = ed.getIterator(); i; i++ ) layout( i ); Zeichnung *laz = members->z( la ); if( laz ) { int x = laz->getX() + laz->getBreite(); if( e->hasAttribute( "margin-left" ) ) { Text mt = e->getAttributeValue( "margin-left" ); int m = mt; if( mt.getText()[ mt.getLength() - 1 ] == '%' ) m = ( getBreite() / 100 ) * m; x += m; } z->setX( x ); } } else if( e->hasAttribute( "align-right" ) ) { Text ra = e->getAttributeValue( "align-right" ); XML::Editor ed = e->zParent()->selectChildsByAttribute( "id", ra ); for( auto i = ed.getIterator(); i; i++ ) layout( i ); Zeichnung *raz = members->z( ra ); if( raz ) { int x = raz->getX() - z->getBreite(); if( e->hasAttribute( "margin-left" ) ) { Text mt = e->getAttributeValue( "margin-right" ); int m = mt; if( mt.getText()[ mt.getLength() - 1 ] == '%' ) m = ( getBreite() / 100 ) * m; x -= m; } z->setX( x ); } } if( e->hasAttribute( "align-top" ) ) { Text ta = e->getAttributeValue( "align-top" ); XML::Editor ed = e->zParent()->selectChildsByAttribute( "id", ta ); for( auto i = ed.getIterator(); i; i++ ) layout( i ); Zeichnung *taz = members->z( ta ); if( taz ) { int y = taz->getY() + taz->getHeight(); if( e->hasAttribute( "margin-top" ) ) { Text mt = e->getAttributeValue( "margin-top" ); int m = mt; if( mt.getText()[ mt.getLength() - 1 ] == '%' ) m = ( getHeight() / 100 ) * m; y += m; } z->setY( y ); } } else if( e->hasAttribute( "align-bottom" ) ) { Text ba = e->getAttributeValue( "align-bottom" ); XML::Editor ed = e->zParent()->selectChildsByAttribute( "id", ba ); for( auto i = ed.getIterator(); i; i++ ) layout( i ); Zeichnung *baz = members->z( ba ); if( baz ) { int y = baz->getY() - z->getHeight(); if( e->hasAttribute( "margin-bottom" ) ) { Text mt = e->getAttributeValue( "margin-bottom" ); int m = mt; if( mt.getText()[ mt.getLength() - 1 ] == '%' ) m = ( getHeight() / 100 ) * m; y -= m; } z->setY( y ); } } int x = z->getX(); int y = z->getY(); if( e->hasAttribute( "x" ) ) { Text xt = e->getAttributeValue( "x" ); x = xt; if( xt.getText()[ xt.getLength() - 1 ] == '%' ) x = ( getBreite() / 100 ) * x; } if( e->hasAttribute( "y" ) ) { Text yt = e->getAttributeValue( "y" ); y = yt; if( yt.getText()[ yt.getLength() - 1 ] == '%' ) y = ( getHeight() / 100 ) * y; } z->setPosition( x, y ); } } } // setzt den inhalt der view // uiml: Ein xml element gemät des ksg uiml standarts void UIMLView::setUIML( XML::Element *uiml ) { if( dom ) dom->release(); dom = uiml; members->leeren(); nextId = 0; if( dom ) { for( auto i = dom->getChilds(); i; i++ ) { parseElement( i._ ); } } } // setzt den inhalt der view // uiml: Ein xml text gemät des ksg uiml standarts void UIMLView::setUIML( Text uiml ) { uiml.toLowerCase(); setUIML( new XML::Element( uiml ) ); } // Gibt eine zeichnung zurück, welche in uiml eine bestimmte id hat // id: die id der Zeichnung Zeichnung *UIMLView::zZeichnung( Text id ) { return members->z( id ); } // aktualisiert größe und position aller Zeichnungen gemäß den spezifikationen in UIML void UIMLView::layout() { if( dom ) { for( auto i = dom->getChilds(); i; i++ ) { layout( i._ ); } } } // Verarbeitet ein Maus Ereignis. Wird vom Framework automatisch aufgerufen. // me: Das Ereignis void UIMLView::doMausEreignis( MausEreignis &me ) { bool verarbeitet = me.verarbeitet; ZeichnungHintergrund::doMausEreignis( me ); me.verarbeitet = verarbeitet; for( auto i = members->getIterator(); i; i++ ) { if( i._ ) { i->doMausEreignis( me ); } } } // Verarbeitet ein Tastatur Ereignis. Wird vom Framework automatisch aufgerufen // te: Das Ereignis void UIMLView::doTastaturEreignis( TastaturEreignis &te ) { bool verarbeitet = te.verarbeitet; ZeichnungHintergrund::doTastaturEreignis( te ); te.verarbeitet = verarbeitet; for( auto i = members->getIterator(); i; i++ ) { if( i._ ) { i->doTastaturEreignis( te ); } } } // Updated den Zeichenhintergrund // tickVal: Die vergangene Zeit in Sekunden, die seit dem Letzten Aufruf dieser Funktion verstrichen ist // return: 1, wenn das Bild neu gezeichnet werden muss. 0 sonnst bool UIMLView::tick( double tickVal ) { for( auto i = members->getIterator(); i; i++ ) { if( i._ ) { rend |= i->tick( tickVal ); } } return ZeichnungHintergrund::tick( tickVal ); } // Zeichnet den Hintergrund eines Zeichnunges nach rObj void UIMLView::render( Bild &rObj ) { ZeichnungHintergrund::render( rObj ); for( auto i = members->getIterator(); i; i++ ) { // TODO render elements backwards if( i._ ) { i->render( rObj ); } } }