ui and graphics changes

* implement draw clipping using opengl stencil buffers
* allow to create Widgets by style name with g_ui.createWidgetByStyle
* styles can now have children widgets
* make proper use of the isNotPathable in pathfinding
* add scrollbar skin
This commit is contained in:
Eduardo Bart
2012-03-24 12:22:40 -03:00
parent efa9811342
commit de0008caf1
34 changed files with 210 additions and 86 deletions

View File

@@ -197,6 +197,7 @@ void UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anch
}
}
newRect.translate(-parentWidget->getVirtualOffset());
widget->setRect(newRect);
anchorGroup.setUpdated(true);
}

View File

@@ -36,9 +36,9 @@ UIFrameCounter::UIFrameCounter()
m_frameCount = 0;
}
void UIFrameCounter::draw()
void UIFrameCounter::drawSelf()
{
UIWidget::draw();
UIWidget::drawSelf();
if(g_clock.ticksElapsed(m_lastFrameTicks) >= 1000) {
m_fpsText = Fw::formatString("FPS: %d", m_frameCount);

View File

@@ -29,7 +29,7 @@ class UIFrameCounter : public UIWidget
{
public:
UIFrameCounter();
virtual void draw();
void drawSelf();
void setAlign(Fw::AlignmentFlag align) { m_align = align; }
Fw::AlignmentFlag getAlign() { return m_align; }

View File

@@ -53,7 +53,7 @@ void UIManager::terminate()
void UIManager::render()
{
m_rootWidget->draw();
m_rootWidget->draw(m_rootWidget->getRect());
}
void UIManager::resize(const Size& size)
@@ -349,23 +349,24 @@ UIWidgetPtr UIManager::loadUI(const std::string& file, const UIWidgetPtr& parent
else {
if(widget)
Fw::throwException("cannot have multiple main widgets in otui files");
widget = loadWidgetFromOTML(node, parent);
widget = createWidgetFromOTML(node, parent);
}
}
return widget;
} catch(Exception& e) {
logError("Failed to load UI from '", file, "': ", e.what());
logError("failed to load UI from '", file, "': ", e.what());
return nullptr;
}
}
/*
UIWidgetPtr UIManager::loadWidgetFromStyle()
{
UIWidgetPtr UIManager::createWidgetFromStyle(const std::string& styleName, const UIWidgetPtr& parent)
{
OTMLNodePtr node = OTMLNode::create(styleName);
return createWidgetFromOTML(node, parent);
}
*/
UIWidgetPtr UIManager::loadWidgetFromOTML(const OTMLNodePtr& widgetNode, const UIWidgetPtr& parent)
UIWidgetPtr UIManager::createWidgetFromOTML(const OTMLNodePtr& widgetNode, const UIWidgetPtr& parent)
{
OTMLNodePtr originalStyleNode = getStyle(widgetNode->tag());
if(!originalStyleNode)
@@ -384,9 +385,11 @@ UIWidgetPtr UIManager::loadWidgetFromOTML(const OTMLNodePtr& widgetNode, const U
if(widget) {
widget->setStyleFromNode(styleNode);
for(const OTMLNodePtr& childNode : widgetNode->children()) {
if(!childNode->isUnique())
loadWidgetFromOTML(childNode, widget);
for(const OTMLNodePtr& childNode : styleNode->children()) {
if(!childNode->isUnique()) {
createWidgetFromOTML(childNode, widget);
styleNode->removeChild(childNode);
}
}
} else
Fw::throwException("unable to create widget of type '", widgetType, "'");

View File

@@ -46,8 +46,9 @@ public:
OTMLNodePtr getStyle(const std::string& styleName);
std::string getStyleClass(const std::string& styleName);
UIWidgetPtr loadUI(const std::string& file, const UIWidgetPtr& parent = nullptr);
UIWidgetPtr loadWidgetFromOTML(const OTMLNodePtr& widgetNode, const UIWidgetPtr& parent);
UIWidgetPtr loadUI(const std::string& file, const UIWidgetPtr& parent);
UIWidgetPtr createWidgetFromStyle(const std::string& styleName, const UIWidgetPtr& parent);
UIWidgetPtr createWidgetFromOTML(const OTMLNodePtr& widgetNode, const UIWidgetPtr& parent);
void setMouseReceiver(const UIWidgetPtr& widget) { m_mouseReceiver = widget; }
void setKeyboardReceiver(const UIWidgetPtr& widget) { m_keyboardReceiver = widget; }

View File

@@ -51,10 +51,22 @@ UIWidget::~UIWidget()
#endif
}
void UIWidget::draw()
void UIWidget::draw(const Rect& visibleRect)
{
drawSelf();
drawChildren();
if(m_children.size() > 0) {
bool clip = true;
if(this == g_ui.getRootWidget().get())
clip = false;
if(clip)
g_graphics.beginClipping(visibleRect);
drawChildren(visibleRect);
if(clip)
g_graphics.endClipping();
}
}
void UIWidget::drawSelf()
@@ -72,33 +84,35 @@ void UIWidget::drawSelf()
drawText(m_rect);
}
void UIWidget::drawChildren()
void UIWidget::drawChildren(const Rect& visibleRect)
{
// draw children
for(const UIWidgetPtr& child : m_children) {
// render only visible children with a valid rect inside parent rect
if(child->isExplicitlyVisible() &&
child->getRect().isValid() &&
child->getOpacity() > 0.0f &&
child->getRect().intersects(m_rect)) {
// store current graphics opacity
float oldOpacity = g_painter.getOpacity();
if(!child->isExplicitlyVisible() || !child->getRect().isValid() || child->getOpacity() == 0.0f)
continue;
// decrease to self opacity
if(child->getOpacity() < oldOpacity)
g_painter.setOpacity(child->getOpacity());
Rect childVisibleRect = visibleRect.intersection(child->getRect());
if(!childVisibleRect.isValid())
continue;
child->draw();
// store current graphics opacity
float oldOpacity = g_painter.getOpacity();
// debug draw box
if(g_ui.isDrawingDebugBoxes()) {
g_painter.setColor(Color::green);
g_painter.drawBoundingRect(child->getRect());
}
//g_fonts.getDefaultFont()->renderText(child->getId(), child->getPosition() + Point(2, 0), Color::red);
// decrease to self opacity
if(child->getOpacity() < oldOpacity)
g_painter.setOpacity(child->getOpacity());
g_painter.setOpacity(oldOpacity);
child->draw(childVisibleRect);
// debug draw box
if(g_ui.isDrawingDebugBoxes()) {
g_painter.setColor(Color::green);
g_painter.drawBoundingRect(child->getRect());
}
//g_fonts.getDefaultFont()->renderText(child->getId(), child->getPosition() + Point(2, 0), Color::red);
g_painter.setOpacity(oldOpacity);
}
}
@@ -747,6 +761,7 @@ void UIWidget::setStyle(const std::string& styleName)
logTraceError("unable to retrive style '", styleName, "': not a defined style");
return;
}
styleNode = styleNode->clone();
applyStyle(styleNode);
m_style = styleNode;
updateStyle();
@@ -839,6 +854,13 @@ void UIWidget::setLastFocusReason(Fw::FocusReason reason)
m_lastFocusReason = reason;
}
void UIWidget::setVirtualOffset(const Point& offset)
{
m_virtualOffset = offset;
if(m_layout)
m_layout->update();
}
bool UIWidget::isVisible()
{
if(!m_visible)

View File

@@ -49,14 +49,15 @@ public:
virtual ~UIWidget();
protected:
virtual void draw();
virtual void draw(const Rect& visibleRect);
virtual void drawSelf();
virtual void drawChildren();
virtual void drawChildren(const Rect& visibleRect);
friend class UIManager;
std::string m_id;
Rect m_rect;
Point m_virtualOffset;
Boolean<true> m_enabled;
Boolean<true> m_visible;
Boolean<true> m_focusable;
@@ -121,6 +122,7 @@ public:
void setFixedSize(bool fixed);
void setLastFocusReason(Fw::FocusReason reason);
void setAutoRepeatDelay(int delay) { m_autoRepeatDelay = delay; }
void setVirtualOffset(const Point& offset);
bool isVisible();
bool isChildLocked(const UIWidgetPtr& child);
@@ -240,6 +242,7 @@ public:
int getChildCount() { return m_children.size(); }
Fw::FocusReason getLastFocusReason() { return m_lastFocusReason; }
int getAutoRepeatDelay() { return m_autoRepeatDelay; }
Point getVirtualOffset() { return m_virtualOffset; }
std::string getStyleName() { return m_style->tag(); }

View File

@@ -81,9 +81,9 @@ void UIWidget::parseBaseStyle(const OTMLNodePtr& styleNode)
else if(node->tag() == "background-rect")
setBackgroundRect(node->value<Rect>());
else if(node->tag() == "icon")
setIcon(node->value());
setIcon(Fw::resolvePath(node->value(), node->source()));
else if(node->tag() == "icon-source")
setIcon(node->value());
setIcon(Fw::resolvePath(node->value(), node->source()));
else if(node->tag() == "icon-color")
setIconColor(node->value<Color>());
else if(node->tag() == "icon-offset-x")

View File

@@ -35,7 +35,7 @@ void UIWidget::parseImageStyle(const OTMLNodePtr& styleNode)
{
for(const OTMLNodePtr& node : styleNode->children()) {
if(node->tag() == "image-source")
setImageSource(Fw::resolvePath(node->value(), styleNode->source()));
setImageSource(Fw::resolvePath(node->value(), node->source()));
else if(node->tag() == "image-offset-x")
setImageOffsetX(node->value<int>());
else if(node->tag() == "image-offset-y")