#include "UIMLView.h" #include "Bild.h" #include "Bildschirm.h" #include "Fenster.h" #include "Knopf.h" #include "Rahmen.h" #include "Schrift.h" #include "Scroll.h" #include "Tabelle.h" #include "TextFeld.h" #include "XML.h" using namespace Framework; UIMLElement::UIMLElement() : ReferenceCounter() {} UIMLElement::~UIMLElement() {} //! wendet die layout parameter zu einer Zeichnung an void UIMLElement::layout(XML::Element& element, Zeichnung& z, int pWidth, int pHeight, UIMLContainer& generalLayouter) { int width = z.getBreite(); int height = z.getHeight(); if (element.hasAttribute("width")) { Text w = element.getAttributeValue("width"); if (!w.istGleich("auto")) { width = (int)w; if (w.getText()[w.getLength() - 1] == '%') width = (int)((pWidth / 100.0) * width); } } if (element.hasAttribute("height")) { Text h = element.getAttributeValue("height"); if (!h.istGleich("auto")) { height = (int)h; if (h.getText()[h.getLength() - 1] == '%') height = (int)((pHeight / 100.0) * height); } } z.setSize(width, height); if (element.hasAttribute("align-left")) { Text la = element.getAttributeValue("align-left"); int x = 0; if (la.istGleich("start")) x = 0; else if (la.istGleich("end")) x = pWidth; else if (la.istGleich("center")) x = pWidth / 2 - width / 2; else { XML::Editor ed = element.zParent()->selectChildsByAttribute("id", la); generalLayouter.layout(*ed.begin().val(), *generalLayouter.zZeichnungById(la), pWidth, pHeight, generalLayouter); Zeichnung* laz = generalLayouter.zZeichnungById(la); if (laz) x = laz->getX() + laz->getBreite(); } if (element.hasAttribute("margin-left")) { Text mt = element.getAttributeValue("margin-left"); int m = (int)mt; if (mt.getText()[mt.getLength() - 1] == '%') m = (int)((pWidth / 100.0) * m); x += m; } z.setX(x); } else if (element.hasAttribute("align-right")) { Text ra = element.getAttributeValue("align-right"); int x = 0; if (ra.istGleich("start")) x = -z.getBreite(); else if (ra.istGleich("end")) x = pWidth - z.getBreite(); else if (ra.istGleich("center")) x = pWidth / 2 - width / 2; else { XML::Editor ed = element.zParent()->selectChildsByAttribute("id", ra); generalLayouter.layout(*ed.begin().val(), *generalLayouter.zZeichnungById(ra), pWidth, pHeight, generalLayouter); Zeichnung* raz = generalLayouter.zZeichnungById(ra); if (raz) x = raz->getX() - z.getBreite(); } if (element.hasAttribute("margin-right")) { Text mt = element.getAttributeValue("margin-right"); int m = (int)mt; if (mt.getText()[mt.getLength() - 1] == '%') m = (int)((pWidth / 100.0) * m); x -= m; } z.setX(x); } if (element.hasAttribute("align-top")) { Text ta = element.getAttributeValue("align-top"); int y = 0; if (ta.istGleich("start")) y = 0; else if (ta.istGleich("end")) y = pHeight; else if (ta.istGleich("center")) y = pHeight / 2 - height / 2; else { XML::Editor ed = element.zParent()->selectChildsByAttribute("id", ta); generalLayouter.layout(*ed.begin().val(), *generalLayouter.zZeichnungById(ta), pWidth, pHeight, generalLayouter); Zeichnung* taz = generalLayouter.zZeichnungById(ta); if (taz) y = taz->getY() + taz->getHeight(); } if (element.hasAttribute("margin-top")) { Text mt = element.getAttributeValue("margin-top"); int m = (int)mt; if (mt.getText()[mt.getLength() - 1] == '%') m = (int)((pHeight / 100.0) * m); y += m; } z.setY(y); } else if (element.hasAttribute("align-bottom")) { Text ba = element.getAttributeValue("align-bottom"); int y = 0; if (ba.istGleich("start")) y = -z.getHeight(); else if (ba.istGleich("end")) y = pHeight - z.getHeight(); else if (ba.istGleich("center")) y = pHeight / 2 - height / 2; else { XML::Editor ed = element.zParent()->selectChildsByAttribute("id", ba); generalLayouter.layout(*ed.begin().val(), *generalLayouter.zZeichnungById(ba), pWidth, pHeight, generalLayouter); Zeichnung* baz = generalLayouter.zZeichnungById(ba); if (baz) y = baz->getY() - z.getHeight(); } if (element.hasAttribute("margin-bottom")) { Text mt = element.getAttributeValue("margin-bottom"); int m = (int)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 (element.hasAttribute("x")) { Text xt = element.getAttributeValue("x"); x = (int)xt; if (xt.getText()[xt.getLength() - 1] == '%') x = (int)((pWidth / 100.0) * x); } if (element.hasAttribute("y")) { Text yt = element.getAttributeValue("y"); y = (int)yt; if (yt.getText()[yt.getLength() - 1] == '%') y = (int)((pHeight / 100.0) * y); } z.setPosition(x, y); pWidth = z.getInnenBreite(); pHeight = z.getInnenHeight(); // recursive layout for (auto i = element.getChilds(); i; i++) { Zeichnung* z = 0; if (i->hasAttribute("id")) { z = generalLayouter.zZeichnungById(i->getAttributeValue("id")); } if (z) { generalLayouter.layout( *i.val(), *z, pWidth, pHeight, generalLayouter); } } } UIMLContainer::UIMLContainer() : UIMLElement() {} UIMLContainer::~UIMLContainer() {} UIMLTextField::UIMLTextField() : UIMLElement() {} bool UIMLTextField::isApplicableFor(XML::Element& element) { return element.getName().istGleich("textfield"); } Zeichnung* UIMLTextField::parseElement( XML::Element& element, UIMLContainer& generalFactory) { TextFeld* t = generalFactory.getFactory().createTextFeld( generalFactory.getFactory().initParam); if (element.hasAttribute("style")) { Text style = element.getAttributeValue("style"); if (!style.hatAt(0, "0x")) { style.insert(0, "0x"); } t->setStyle((int)style); } else { t->addStyle(TextFeld::Style::TextFeld); } return t; } void UIMLTextField::layout(XML::Element& element, Zeichnung& z, int pWidth, int pHeight, UIMLContainer& generalLayouter) { if (element.hasAttribute("text-align-horizontal")) z.setStyle(TextFeld::Style::HCenter, element.getAttributeValue("text-align-horizontal") .istGleich("center")); if (element.hasAttribute("text-align-vertical")) z.setStyle(TextFeld::Style::VCenter, element.getAttributeValue("text-align-vertical") .istGleich("center")); if (element.hasAttribute("font-size")) ((TextFeld*)&z) ->setSchriftSize( (unsigned char)(int)element.getAttributeValue("font-size")); if (element.hasAttribute("disabled")) z.removeStyle(TextFeld::Style::Editierbar); ((TextFeld*)&z)->setText(element.getText()); if (element.hasAttribute("width")) { Text w = element.getAttributeValue("width"); if (w.istGleich("auto")) { z.setWidth(((TextFeld*)&z)->getNeededWidth()); } } if (element.hasAttribute("height")) { Text h = element.getAttributeValue("height"); if (h.istGleich("auto")) { z.setHeight(((TextFeld*)&z)->getNeededHeight()); } } UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter); } UIMLButton::UIMLButton() : UIMLElement() {} bool UIMLButton::isApplicableFor(XML::Element& element) { return element.getName().istGleich("button"); } Zeichnung* UIMLButton::parseElement( XML::Element& element, UIMLContainer& generalFactory) { Knopf* k = generalFactory.getFactory().createKnopf( generalFactory.getFactory().initParam); if (element.hasAttribute("style")) { Text style = element.getAttributeValue("style"); if (!style.hatAt(0, "0x")) { style.insert(0, "0x"); } k->setStyle((int)style); } return k; } void UIMLButton::layout(XML::Element& element, Zeichnung& z, int pWidth, int pHeight, UIMLContainer& generalLayouter) { if (element.hasAttribute("font-size")) ((Knopf*)&z) ->setSchriftSize( (unsigned char)(int)element.getAttributeValue("font-size")); ((Knopf*)&z)->setText(element.getText()); UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter); } UIMLCheck::UIMLCheck() : UIMLElement() {} bool UIMLCheck::isApplicableFor(XML::Element& element) { return element.getName().istGleich("check"); } Zeichnung* UIMLCheck::parseElement( XML::Element& element, UIMLContainer& generalFactory) { KontrollKnopf* k = generalFactory.getFactory().createKontrollKnopf( generalFactory.getFactory().initParam); if (element.hasAttribute("style")) { Text style = element.getAttributeValue("style"); if (!style.hatAt(0, "0x")) { style.insert(0, "0x"); } k->setStyle((int)style); } return k; } void UIMLCheck::layout(XML::Element& element, Zeichnung& z, int pWidth, int pHeight, UIMLContainer& generalLayouter) { ((KontrollKnopf*)&z)->setText(element.getText()); ((KontrollKnopf*)&z)->setSText(element.getText()); z.setStyle( KontrollKnopf::Style::Selected, element.hasAttribute("selected")); if (element.hasAttribute("font-size")) ((KontrollKnopf*)&z) ->setSSize( (unsigned char)(int)element.getAttributeValue("font-size")); UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter); } UIMLText::UIMLText() : UIMLElement() {} bool UIMLText::isApplicableFor(XML::Element& element) { return element.getName().istGleich("text"); } Zeichnung* UIMLText::parseElement( XML::Element& element, UIMLContainer& generalFactory) { TextFeld* t = generalFactory.getFactory().createTextFeld( generalFactory.getFactory().initParam); if (element.hasAttribute("style")) { Text style = element.getAttributeValue("style"); if (!style.hatAt(0, "0x")) { style.insert(0, "0x"); } t->setStyle((int)style); } else { t->addStyle(TextFeld::Style::Text); } return t; } void UIMLText::layout(XML::Element& element, Zeichnung& z, int pWidth, int pHeight, UIMLContainer& generalLayouter) { if (element.hasAttribute("text-align-horizontal")) z.setStyle(TextFeld::Style::HCenter, element.getAttributeValue("text-align-horizontal") .istGleich("center")); if (element.hasAttribute("text-align-vertical")) z.setStyle(TextFeld::Style::VCenter, element.getAttributeValue("text-align-vertical") .istGleich("center")); if (element.hasAttribute("font-size")) ((TextFeld*)&z) ->setSchriftSize( (unsigned char)(int)element.getAttributeValue("font-size")); if (element.hasAttribute("disabled")) z.removeStyle(TextFeld::Style::Editierbar); ((TextFeld*)&z)->setText(element.getText()); if (element.hasAttribute("width")) { Text w = element.getAttributeValue("width"); if (w.istGleich("auto")) { z.setWidth(((TextFeld*)&z)->getNeededWidth()); } } if (element.hasAttribute("height")) { Text h = element.getAttributeValue("height"); if (h.istGleich("auto")) { z.setHeight(((TextFeld*)&z)->getNeededHeight()); } } UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter); } UIMLTextArea::UIMLTextArea() : UIMLElement() {} bool UIMLTextArea::isApplicableFor(XML::Element& element) { return element.getName().istGleich("textarea"); } Zeichnung* UIMLTextArea::parseElement( XML::Element& element, UIMLContainer& generalFactory) { TextFeld* t = generalFactory.getFactory().createTextFeld( generalFactory.getFactory().initParam); if (element.hasAttribute("style")) { Text style = element.getAttributeValue("style"); if (!style.hatAt(0, "0x")) { style.insert(0, "0x"); } t->setStyle((int)style); } else { t->addStyle(TextFeld::Style::TextGebiet); } return t; } void UIMLTextArea::layout(XML::Element& element, Zeichnung& z, int pWidth, int pHeight, UIMLContainer& generalLayouter) { if (element.hasAttribute("text-align-horizontal")) z.setStyle(TextFeld::Style::HCenter, element.getAttributeValue("text-align-horizontal") .istGleich("center")); if (element.hasAttribute("text-align-vertical")) z.setStyle(TextFeld::Style::VCenter, element.getAttributeValue("text-align-vertical") .istGleich("center")); if (element.hasAttribute("font-size")) ((TextFeld*)&z) ->setSchriftSize( (unsigned char)(int)element.getAttributeValue("font-size")); if (element.hasAttribute("disabled")) z.removeStyle(TextFeld::Style::Editierbar); ((TextFeld*)&z)->setText(element.getText()); ((TextFeld*)&z) ->zTextRenderer() ->textFormatieren(((TextFeld*)&z)->zText(), z.getInnenBreite()); if (element.hasAttribute("width")) { Text w = element.getAttributeValue("width"); if (w.istGleich("auto")) { z.setWidth(((TextFeld*)&z)->getNeededWidth()); } } if (element.hasAttribute("height")) { Text h = element.getAttributeValue("height"); if (h.istGleich("auto")) { z.setHeight(((TextFeld*)&z)->getNeededHeight()); } } UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter); } UIMLTable::UIMLTable() : UIMLElement() {} bool UIMLTable::isApplicableFor(XML::Element& element) { return element.getName().istGleich("table"); } Zeichnung* UIMLTable::parseElement( XML::Element& element, UIMLContainer& generalFactory) { ObjTabelle* t = generalFactory.getFactory().createObjTabelle( generalFactory.getFactory().initParam); int index = 0; for (auto i = element.getChilds(); i; i++) { Text id; if (i->hasAttribute("id")) id = i->getAttributeValue("id"); else { id = Text("_") += index++; i->setAttribute("id", id); } if (i->getName().istGleich("tr")) { t->addZeile(id); Text line = id; int c = 1; for (auto j = i->getChilds(); j; j++) { Zeichnung* z = generalFactory.parseElement(*i.val(), generalFactory); if (t->getSpaltenAnzahl() < c) t->addSpalte(Text(c - 1)); if (z) t->setZeichnungZ(Text(c - 1), line, z); c++; } } } if (element.hasAttribute("style")) { Text style = element.getAttributeValue("style"); if (!style.hatAt(0, "0x")) { style.insert(0, "0x"); } t->setStyle((int)style); } return t; } void UIMLTable::layout(XML::Element& element, Zeichnung& z, int pWidth, int pHeight, UIMLContainer& generalLayouter) { if (element.hasAttribute("scroll")) { z.setStyle(ObjTabelle::Style::HScroll, element.getAttributeValue("scroll").istGleich("horizontal")); z.setStyle(ObjTabelle::Style::VScroll, element.getAttributeValue("scroll").istGleich("vertical")); z.setStyle(ObjTabelle::Style::scroll, element.getAttributeValue("scroll").istGleich("both")); } UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter); ObjTabelle* objT = (ObjTabelle*)&z; if (objT->getZeilenAnzahl() > 0) { if (element.hasAttribute("line-height")) { int height = (int)element.getAttributeValue("line-height"); for (int i = 0; i < objT->getZeilenAnzahl(); i++) objT->setZeilenHeight(i, height); } for (int i = 0; i < objT->getSpaltenAnzahl(); i++) { if (objT->zZeichnung(i, 0)) objT->setSpaltenBreite(i, objT->zZeichnung(i, 0)->getBreite()); } } } UIMLFrame::UIMLFrame() : UIMLElement() {} bool UIMLFrame::isApplicableFor(XML::Element& element) { return element.getName().istGleich("frame"); } Zeichnung* UIMLFrame::parseElement( XML::Element& element, UIMLContainer& generalFactory) { Fenster* f = generalFactory.getFactory().createFenster( generalFactory.getFactory().initParam); if (element.hasAttribute("style")) { Text style = element.getAttributeValue("style"); if (!style.hatAt(0, "0x")) { style.insert(0, "0x"); } f->setStyle((int)style); } for (auto i = element.getChilds(); i; i++) { Zeichnung* z = generalFactory.parseElement(*i.val(), generalFactory); if (z) f->addMember(z); } return f; } void UIMLFrame::layout(XML::Element& element, Zeichnung& z, int pWidth, int pHeight, UIMLContainer& generalLayouter) { if (element.hasAttribute("title")) ((Fenster*)&z)->setTitel(element.getAttributeValue("title")); if (element.hasAttribute("title-height")) ((Fenster*)&z) ->zTTextFeld() ->setSize(((Fenster*)&z)->zTTextFeld()->getBreite(), (int)element.getAttributeValue("title-height")); UIMLElement::layout(element, z, pWidth, pHeight, generalLayouter); } // Erstellt eine UIML View UIMLView::UIMLView() : ZeichnungHintergrund() { style = Style::MEIgnoreInside | Style::MEIgnoreParentInside | Style::MEIgnoreSichtbar | Style::MEIgnoreVerarbeitet; members = new RCTrie(); dom = 0; nextId = 0; memset(&init, 0, sizeof(UIInit)); addKnownElement(new UIMLTextField()); addKnownElement(new UIMLButton()); addKnownElement(new UIMLCheck()); addKnownElement(new UIMLText()); addKnownElement(new UIMLTextArea()); addKnownElement(new UIMLTable()); addKnownElement(new UIMLFrame()); } // 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) : UIMLView() { this->init = init; 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) : UIMLView() { this->init = init; setUIML(uiml); } UIMLView::~UIMLView() { if (dom) dom->release(); members->release(); } // Verarbeitet ein Maus Ereignis. Wird vom Framework automatisch aufgerufen. // me: Das Ereignis void UIMLView::doMausEreignis(MausEreignis& me, bool userRet) { if (dom) { bool verarbeitet = me.verarbeitet; me.verarbeitet |= hatStyleNicht(Style::Sichtbar); bool insideParent = me.insideParent; if (!hatStyle(Style::Sichtbar) || !me.insideParent || me.verarbeitet || me.mx < 0 || me.my < 0 || me.mx >= gr.x || me.my >= gr.y || !userRet) me.insideParent = 0; int rbr = 0; if (hatStyle(Style::Rahmen) && rahmen) rbr = rahmen->getRBreite(); me.mx -= rbr; me.my -= rbr; if (hatStyle(Style::VScroll) && vertikalScrollBar) me.my += vertikalScrollBar->getScroll(); if (hatStyle(Style::HScroll) && horizontalScrollBar) me.mx += horizontalScrollBar->getScroll(); if (dom) { for (auto i = dom->getChilds(); i; i++) { // TODO render elements backwards Zeichnung* z = members->z(i->getAttributeValue("id"), i->getAttributeValue("id").getLength()); if (z) z->doPublicMausEreignis(me); } } me.mx += rbr; me.my += rbr; if (hatStyle(Style::VScroll) && vertikalScrollBar) me.my -= vertikalScrollBar->getScroll(); if (hatStyle(Style::HScroll) && horizontalScrollBar) me.mx -= horizontalScrollBar->getScroll(); if (!hatStyle(Style::Sichtbar) || !me.insideParent || me.verarbeitet || me.mx < 0 || me.my < 0 || me.mx >= gr.x || me.my >= gr.y || !userRet) me.insideParent = insideParent; else me.verarbeitet = 1; if (hatStyleNicht(Style::Sichtbar)) me.verarbeitet = verarbeitet; } } //! entfernt alle bekannten elemente, die im uiml verwendet werden können void UIMLView::removeAllKnownElements() { knownElements.leeren(); } //! fügt ein neues bekanntes element hinzu, dass danach im uiml verwendet werden //! kann. void UIMLView::addKnownElement(UIMLElement* element) { knownElements.add(element); } //! prüft, ob ein xml Element ein bekanntes uiml Element ist; bool UIMLView::isKnownElement(XML::Element* zElement) { for (UIMLElement* element : knownElements) { if (element->isApplicableFor(*zElement)) return 1; } return 0; } // 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++) { Zeichnung* z = parseElement(*i.val(), *this); if (z) z->release(); } } } // 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::zZeichnungById(const char* id) { return members->z(id, textLength(id)); } // Gibt eine zeichnung zurück, welche in uiml eine bestimmte id hat // id: die id der Zeichnung Zeichnung* UIMLView::getZeichnungById(const char* id) { return members->get(id, textLength(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++) { Text id = i->getAttributeValue("id"); Zeichnung* z = zZeichnungById(id); if (z) { layout(*i.val(), *z, this->getInnenBreite(), this->getInnenHeight(), *this); } } } } // 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); Zeichnung* z = parseElement(*e, *this); if (z) { dom->addChildAtFront(e); z->release(); } 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.begin()) { XML::Editor ed2 = ed.whereAttributeEquals("id", parentId); if (ed2.begin()) { if (ed2.begin()->getName().istGleich("frame")) { Zeichnung* z = parseElement(*e, *this); if (z) { dynamic_cast( members->z(parentId, parentId.getLength())) ->addMember(z); ed2.begin()->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, id.getLength()); } // 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"), i->getAttributeValue("id").getLength()); 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"), i->getAttributeValue("id").getLength()); if (z) rend |= z->tick(tickVal); } } return ZeichnungHintergrund::tick(tickVal); } // Zeichnet den Hintergrund eines Zeichnunges nach rObj void UIMLView::render(Bild& rObj) { if (hatStyle(Zeichnung::Style::Sichtbar)) { ZeichnungHintergrund::render(rObj); if (dom) { if (!rObj.setDrawOptions(pos.x + getRahmenBreite(), pos.y + getRahmenBreite(), gr.x + getRahmenBreite() * 2, gr.y + getRahmenBreite() * 2)) return; bool vSc = hatStyle(Style::VScroll) && vertikalScrollBar; bool hSc = hatStyle(Style::HScroll) && horizontalScrollBar; rObj.addScrollOffset(hSc ? horizontalScrollBar->getScroll() : 0, vSc ? vertikalScrollBar->getScroll() : 0); 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"), e->getAttributeValue("id").getLength()); if (z) z->render(rObj); } rObj.releaseDrawOptions(); } } } // 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 ? dynamic_cast(dom->getThis()) : 0; } bool UIMLView::isApplicableFor(XML::Element& element) { for (UIMLElement* e : knownElements) { if (e->isApplicableFor(element)) return 1; } return 0; } Zeichnung* UIMLView::parseElement( XML::Element& element, UIMLContainer& generalFactory) { Text id; if (element.hasAttribute("id")) id = element.getAttributeValue("id"); else { id = Text("_") += nextId++; element.setAttribute("id", id); } Zeichnung* z = members->z(id, id.getLength()); if (!z) { // precompute attributes if (element.hasAttribute("margin")) { Text m = element.getAttributeValue("margin"); if (!element.hasAttribute("margin-left")) element.setAttribute("margin-left", m); if (!element.hasAttribute("margin-top")) element.setAttribute("margin-top", m); if (!element.hasAttribute("margin-right")) element.setAttribute("margin-right", m); if (!element.hasAttribute("margin-bottom")) element.setAttribute("margin-bottom", m); } if (element.hasAttribute("class")) { Text c = element.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.begin(); i; i++) { for (auto j = i->getAttributeNames(), k = i->getAttributeValues(); j && k; j++, k++) { if (!element.hasAttribute(j->getText())) element.setAttribute(j->getText(), i->getText()); } } t->release(); if (c.hat(",")) c.remove(0, c.positionVon(',' + 1)); else break; } } if (element.hasAttribute("text-align")) { if (!element.hasAttribute("text-align-horizontal")) element.setAttribute("text-align-horizontal", element.getAttributeValue("text-align")); if (!element.hasAttribute("text-align-vertical")) element.setAttribute("text-align-vertical", element.getAttributeValue("text-align")); } // create objects for (UIMLElement* e : knownElements) { if (e->isApplicableFor(element)) { z = e->parseElement(element, *this); break; } } if (z) members->set( id, id.getLength(), dynamic_cast(z->getThis())); } else z->getThis(); return z; } void UIMLView::layout(XML::Element& element, Zeichnung& z, int pWidth, int pHeight, UIMLContainer& generalLayouter) { for (UIMLElement* e : knownElements) { if (e->isApplicableFor(element)) { e->layout(element, z, pWidth, pHeight, *this); break; } } } const UIInit& UIMLView::getFactory() { return init; } //! calculates the needed size for all content elements to be visible Punkt UIMLView::calculateContentSize() { Punkt maxP(0, 0); 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"), e->getAttributeValue("id").getLength()); if (z) { maxP.x = MAX(maxP.x, z->getPosition().x + z->getBreite()); maxP.y = MAX(maxP.y, z->getPosition().y + z->getHeight()); } } maxP.x += 2 * getRahmenBreite(); maxP.y += 2 * getRahmenBreite(); return maxP; }