123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576 |
- #include "UIMLView.h"
- #include "XML.h"
- #include "TextFeld.h"
- #include "Knopf.h"
- #include "Tabelle.h"
- #include "Fenster.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<XML::Element*> childs, ObjTabelle *table )
- {
- for( auto i = childs; i; i++ )
- {
- Text id;
- if( i->hasAttribute( "id" ) )
- id = i->getAttributeValue( "id" );
- else
- {
- id = Text( "_" ) += nextId++;
- i->setAttribute( "id", id );
- }
- 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( (char*)Text( c - 1 ), (char*)line, z->getThis() );
- c++;
- }
- }
- }
- }
- void UIMLView::parseFrame( Iterator<XML::Element*> childs, Fenster *frame )
- {
- for( auto i = childs; i; i++ )
- {
- Zeichnung *z = parseElement( i._ );
- if( z )
- frame->addMember( z->getThis() );
- }
- }
- 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 );
- }
- if( e->hasAttribute( "class" ) )
- {
- Text c = e->getAttributeValue( "class" );
- while( 1 )
- {
- Text *t;
- if( c.hat( "," ) )
- t = c.getTeilText( 0, c.positionVon( ',' ) );
- else
- t = new Text( c );
- XML::Editor ce = dom->selectChildsByName( "class" ).whereAttributeEquals( "id", *t );
- for( auto i = ce.getIterator(); i; i++ )
- {
- for( auto j = i->getAttributeNames(), k = i->getAttributeValues(); j && k; j++, k++ )
- {
- if( !e->hasAttribute( j->getText() ) )
- e->setAttribute( j->getText(), i->getText() );
- }
- }
- t->release();
- if( c.hat( "," ) )
- c.remove( 0, c.positionVon( ',' + 1 ) );
- else
- break;
- }
- }
- if( e->hasAttribute( "text-align" ) )
- {
- if( !e->hasAttribute( "text-align-horizontal" ) )
- e->setAttribute( "text-align-horizontal", e->getAttributeValue( "text-align" ) );
- if( !e->hasAttribute( "text-align-vertical" ) )
- e->setAttribute( "text-align-vertical", e->getAttributeValue( "text-align" ) );
- }
- // create objects
- if( e->getName().istGleich( "textfield" ) ||
- e->getName().istGleich( "text" ) ||
- e->getName().istGleich( "textarea" ) )
- {
- TextFeld *t = init.createTextFeld( init.initParam );
- if( e->getName().istGleich( "textfield" ) )
- t->addStyle( TextFeld::Style::TextFeld );
- if( e->getName().istGleich( "text" ) )
- t->addStyle( TextFeld::Style::Text );
- if( e->getName().istGleich( "textarea" ) )
- t->addStyle( TextFeld::Style::TextGebiet );
- t->setText( e->getText() );
- if( e->hasAttribute( "font-size" ) )
- t->setSchriftSize( (unsigned char)(int)e->getAttributeValue( "font-size" ) );
- if( e->hasAttribute( "text-align-horizontal" ) )
- {
- if( e->getAttributeValue( "text-align-horizontal" ).istGleich( "center" ) )
- t->addStyle( TextFeld::Style::HCenter );
- }
- if( e->hasAttribute( "text-align-vertical" ) )
- {
- if( e->getAttributeValue( "text-align-vertical" ).istGleich( "center" ) )
- t->addStyle( TextFeld::Style::VCenter );
- }
- z = t;
- }
- if( e->getName().istGleich( "button" ) )
- {
- Knopf *k = init.createKnopf( init.initParam );
- k->setText( e->getText() );
- if( e->hasAttribute( "font-size" ) )
- k->setSchriftSize( (unsigned char)(int)e->getAttributeValue( "font-size" ) );
- z = k;
- }
- if( e->getName().istGleich( "table" ) )
- {
- ObjTabelle *t = init.createObjTabelle( init.initParam );
- parseTable( e->getChilds(), t );
- if( e->hasAttribute( "scroll" ) )
- {
- if( e->getAttributeValue( "scroll" ).istGleich( "horizontal" ) )
- t->addStyle( ObjTabelle::Style::HScroll );
- if( e->getAttributeValue( "scroll" ).istGleich( "vertical" ) )
- t->addStyle( ObjTabelle::Style::VScroll );
- if( e->getAttributeValue( "scroll" ).istGleich( "both" ) )
- t->addStyle( ObjTabelle::Style::scroll );
- }
- z = t;
- }
- if( e->getName().istGleich( "frame" ) )
- {
- Fenster *f = init.createFenster( init.initParam );
- parseFrame( e->getChilds(), f );
- if( e->hasAttribute( "title" ) )
- f->setTitel( e->getAttributeValue( "title" ) );
- if( e->hasAttribute( "title-height" ) )
- f->zTTextFeld()->setSize( f->zTTextFeld()->getBreite(), e->getAttributeValue( "title-height" ) );
- z = f;
- }
- // add general attributes
- if( z && e->hasAttribute( "tooltip" ) )
- z->setToolTipText( e->getAttributeValue( "tooltip" ), init.initParam.bildschirm, init.initParam.schrift );
- if( z && e->hasAttribute( "style" ) )
- z->setStyle( (__int64)e->getAttributeValue( "style" ) );
- if( z && e->hasAttribute( "hidden" ) )
- z->removeStyle( Zeichnung::Style::Sichtbar );
- if( z && e->hasAttribute( "disabled" ) )
- z->removeStyle( Zeichnung::Style::Erlaubt );
- if( z )
- members->set( id, z );
- }
- return z;
- }
- void UIMLView::layout( XML::Element *e, int pWidth, int pHeight )
- {
- 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 = (int)( ( pWidth / 100.0 ) * width );
- }
- if( e->hasAttribute( "height" ) )
- {
- Text h = e->getAttributeValue( "height" );
- height = h;
- if( h.getText()[ h.getLength() - 1 ] == '%' )
- height = (int)( ( pHeight / 100.0 ) * height );
- }
- z->setSize( width, height );
- if( e->hasAttribute( "align-left" ) )
- {
- Text la = e->getAttributeValue( "align-left" );
- int x;
- if( la.istGleich( "start" ) )
- x = 0;
- else if( la.istGleich( "end" ) )
- x = pWidth;
- else
- {
- XML::Editor ed = e->zParent()->selectChildsByAttribute( "id", la );
- for( auto i = ed.getIterator(); i; i++ )
- layout( i, pWidth, pHeight );
- Zeichnung *laz = members->z( la );
- if( laz )
- 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 = (int)( ( pWidth / 100.0 ) * m );
- x += m;
- }
- z->setX( x );
- }
- else if( e->hasAttribute( "align-right" ) )
- {
- Text ra = e->getAttributeValue( "align-right" );
- int x;
- if( ra.istGleich( "start" ) )
- x = -z->getBreite();
- else if( ra.istGleich( "end" ) )
- x = pWidth - z->getBreite();
- else
- {
- XML::Editor ed = e->zParent()->selectChildsByAttribute( "id", ra );
- for( auto i = ed.getIterator(); i; i++ )
- layout( i, pWidth, pHeight );
- Zeichnung *raz = members->z( ra );
- if( raz )
- x = raz->getX() - z->getBreite();
- }
- if( e->hasAttribute( "margin-right" ) )
- {
- Text mt = e->getAttributeValue( "margin-right" );
- int m = mt;
- if( mt.getText()[ mt.getLength() - 1 ] == '%' )
- m = (int)( ( pWidth / 100.0 ) * m );
- x -= m;
- }
- z->setX( x );
- }
- if( e->hasAttribute( "align-top" ) )
- {
- Text ta = e->getAttributeValue( "align-top" );
- int y;
- if( ta.istGleich( "start" ) )
- y = 0;
- else if( ta.istGleich( "end" ) )
- y = pHeight;
- else
- {
- XML::Editor ed = e->zParent()->selectChildsByAttribute( "id", ta );
- for( auto i = ed.getIterator(); i; i++ )
- layout( i, pWidth, pHeight );
- Zeichnung *taz = members->z( ta );
- if( taz )
- 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 = (int)( ( pHeight / 100.0 ) * m );
- y += m;
- }
- z->setY( y );
- }
- else if( e->hasAttribute( "align-bottom" ) )
- {
- Text ba = e->getAttributeValue( "align-bottom" );
- int y;
- if( ba.istGleich( "start" ) )
- y = -z->getHeight();
- else if( ba.istGleich( "end" ) )
- y = pHeight - z->getHeight();
- else
- {
- XML::Editor ed = e->zParent()->selectChildsByAttribute( "id", ba );
- for( auto i = ed.getIterator(); i; i++ )
- layout( i, pWidth, pHeight );
- Zeichnung *baz = members->z( ba );
- if( baz )
- 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 = (int)( ( pHeight / 100.0 ) * 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 = (int)( ( pWidth / 100.0 ) * x );
- }
- if( e->hasAttribute( "y" ) )
- {
- Text yt = e->getAttributeValue( "y" );
- y = yt;
- if( yt.getText()[ yt.getLength() - 1 ] == '%' )
- y = (int)( ( pHeight / 100.0 ) * y );
- }
- z->setPosition( x, y );
- if( e->getName().istGleich( "textarea" ) )
- {
- ( (TextFeld*)z )->zTextRenderer()->textFormatieren( ( (TextFeld*)z )->zText(), z->getInnenBreite() );
- }
- }
- if( z )
- {
- pWidth = z->getInnenBreite();
- pHeight = z->getInnenHeight();
- }
- // recursive layout
- for( auto i = e->getChilds(); i; i++ )
- layout( i, pWidth, pHeight );
- if( z )
- {
- if( e->getName().istGleich( "table" ) )
- {
- ObjTabelle *objT = (ObjTabelle*)z;
- if( objT->getZeilenAnzahl() > 0 )
- {
- for( int i = 0; i < objT->getSpaltenAnzahl(); i++ )
- {
- if( objT->zZeichnung( i, 0 ) )
- objT->setSpaltenBreite( i, objT->zZeichnung( i, 0 )->getBreite() );
- }
- }
- }
- }
- }
- // 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 )
- {
- 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._, this->getInnenBreite(), this->getInnenHeight() );
- }
- }
- }
- // fügt ein element hinzu
- // uiml: Ein xml text gemät des KSG UIML standarts, welcher das neue Objekt darstellt
- Text UIMLView::addMember( Text uiml )
- {
- XML::Element *e = new XML::Element( uiml );
- if( parseElement( e ) )
- dom->addChildAtFront( e );
- return e->getAttributeValue( "id" );
- }
- // fügt ein element zu einem Elternelement hinzu (funktioniert momentan nur mit frame Objekten)
- // uiml: Ein xml text gemät des KSG UIML standarts, welcher das neue Objekt darstellt
- Text UIMLView::addMember( Text uiml, Text parentId )
- {
- XML::Element *e = new XML::Element( uiml );
- XML::Editor ed = dom->selectChildren();
- while( ed.getIterator() )
- {
- XML::Editor ed2 = ed.whereAttributeEquals( "id", parentId );
- if( ed2.getIterator() )
- {
- if( ed2.getIterator()->getName().istGleich( "frame" ) )
- {
- Zeichnung *z = parseElement( e );
- if( z )
- {
- ( (Fenster*)members->z( parentId ) )->addMember( z->getThis() );
- ed2.getIterator()->addChild( e );
- }
- return e->getAttributeValue( "id" );
- }
- }
- ed = ed.selectChildren();
- }
- e->release();
- return "";
- }
- // entfernt ein element
- // id: id des Elements
- void UIMLView::removeMember( Text id )
- {
- XML::Editor e = dom->selectChildsByAttribute( "id", id );
- e.remove();
- members->remove( id );
- }
- // 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;
- if( dom )
- {
- for( auto i = dom->getChilds(); i; i++ )
- { // TODO render elements backwards
- Zeichnung *z = members->z( i->getAttributeValue( "id" ) );
- if( z )
- z->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;
- if( dom )
- {
- for( auto i = dom->getChilds(); i; i++ )
- { // TODO render elements backwards
- Zeichnung *z = members->z( i->getAttributeValue( "id" ) );
- if( z )
- z->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 )
- {
- if( dom )
- {
- for( auto i = dom->getChilds(); i; i++ )
- { // TODO render elements backwards
- Zeichnung *z = members->z( i->getAttributeValue( "id" ) );
- if( z )
- rend |= z->tick( tickVal );
- }
- }
- return ZeichnungHintergrund::tick( tickVal );
- }
- // Zeichnet den Hintergrund eines Zeichnunges nach rObj
- void UIMLView::render( Bild &rObj )
- {
- ZeichnungHintergrund::render( rObj );
- if( dom )
- {
- for( int i = dom->getChildCount() - 1; i >= 0; i-- )
- { // TODO render elements backwards
- XML::Element *e = dom->zChild( i );
- Zeichnung *z = members->z( e->getAttributeValue( "id" ) );
- if( z )
- z->render( rObj );
- }
- }
- }
- // Gibt den Dom Tree ohne erhöhten reference counter zurück
- // Änderungen am Dom Tree sollten vermieden werden (nur änderungen von attributen einzelner elemente sind erlaubt)
- XML::Element *UIMLView::zDom() const
- {
- return dom;
- }
- // Gibt den Dom Tree zurück
- // Änderungen am Dom Tree sollten vermieden werden (nur änderungen von attributen einzelner elemente sind erlaubt)
- XML::Element *UIMLView::getDom() const
- {
- return dom ? dom->getThis() : 0;
- }
|