Minimap, hotkeys and lot of other changes

* Begin working on a new layout system for UIMinimap and later UIMap,
this new layout system allows to add widgets to the minimap
* Add option to disable motd
* Rework hotkey binding
* Lots of fixes in hotkeys manager
* Add fullmap view using Ctrl+Shift+M
* Prevent some crashs in ThingType draw
* Add function to load minimap from PNG files
* Fixes in minimap saving
* Fixes in Tile::isClickable
* Add UIMapAnchorLayout, new layout for maps
* Fix freezes in win32 when pressing alt key
This commit is contained in:
Eduardo Bart
2013-02-18 13:16:22 -03:00
parent f8b078ea91
commit 9a54bfcc90
43 changed files with 842 additions and 499 deletions

View File

@@ -33,6 +33,8 @@ class UIBoxLayout;
class UIHorizontalLayout;
class UIVerticalLayout;
class UIGridLayout;
class UIAnchor;
class UIAnchorGroup;
class UIAnchorLayout;
class UIParticles;
@@ -44,8 +46,11 @@ typedef stdext::shared_object_ptr<UIBoxLayout> UIBoxLayoutPtr;
typedef stdext::shared_object_ptr<UIHorizontalLayout> UIHorizontalLayoutPtr;
typedef stdext::shared_object_ptr<UIVerticalLayout> UIVerticalLayoutPtr;
typedef stdext::shared_object_ptr<UIGridLayout> UIGridLayoutPtr;
typedef stdext::shared_object_ptr<UIAnchor> UIAnchorPtr;
typedef stdext::shared_object_ptr<UIAnchorGroup> UIAnchorGroupPtr;
typedef stdext::shared_object_ptr<UIAnchorLayout> UIAnchorLayoutPtr;
typedef std::deque<UIWidgetPtr> UIWidgetList;
typedef std::vector<UIAnchorPtr> UIAnchorList;
#endif

View File

@@ -23,11 +23,81 @@
#include "uianchorlayout.h"
#include "uiwidget.h"
void UIAnchorGroup::addAnchor(const UIAnchor& anchor)
UIWidgetPtr UIAnchor::getHookedWidget(const UIWidgetPtr& widget, const UIWidgetPtr& parentWidget)
{
// determine hooked widget
UIWidgetPtr hookedWidget;
if(parentWidget) {
if(m_hookedWidgetId == "parent")
hookedWidget = parentWidget;
else if(m_hookedWidgetId == "next")
hookedWidget = parentWidget->getChildAfter(widget);
else if(m_hookedWidgetId == "prev")
hookedWidget = parentWidget->getChildBefore(widget);
else
hookedWidget = parentWidget->getChildById(m_hookedWidgetId);
}
return hookedWidget;
}
int UIAnchor::getHookedPoint(const UIWidgetPtr& hookedWidget, const UIWidgetPtr& parentWidget)
{
// determine hooked widget edge point
Rect hookedWidgetRect = hookedWidget->getRect();
if(hookedWidget == parentWidget)
hookedWidgetRect = parentWidget->getPaddingRect();
int point = 0;
switch(m_hookedEdge) {
case Fw::AnchorLeft:
point = hookedWidgetRect.left();
break;
case Fw::AnchorRight:
point = hookedWidgetRect.right();
break;
case Fw::AnchorTop:
point = hookedWidgetRect.top();
break;
case Fw::AnchorBottom:
point = hookedWidgetRect.bottom();
break;
case Fw::AnchorHorizontalCenter:
point = hookedWidgetRect.horizontalCenter();
break;
case Fw::AnchorVerticalCenter:
point = hookedWidgetRect.verticalCenter();
break;
default:
// must never happens
assert(false);
break;
}
if(hookedWidget == parentWidget) {
switch(m_hookedEdge) {
case Fw::AnchorLeft:
case Fw::AnchorRight:
case Fw::AnchorHorizontalCenter:
point -= parentWidget->getVirtualOffset().x;
break;
case Fw::AnchorBottom:
case Fw::AnchorTop:
case Fw::AnchorVerticalCenter:
point -= parentWidget->getVirtualOffset().y;
break;
default:
break;
}
}
return point;
}
void UIAnchorGroup::addAnchor(const UIAnchorPtr& anchor)
{
// duplicated anchors must be replaced
for(UIAnchor& other : m_anchors) {
if(other.getAnchoredEdge() == anchor.getAnchoredEdge()) {
for(UIAnchorPtr& other : m_anchors) {
if(other->getAnchoredEdge() == anchor->getAnchoredEdge()) {
other = anchor;
return;
}
@@ -43,9 +113,12 @@ void UIAnchorLayout::addAnchor(const UIWidgetPtr& anchoredWidget, Fw::AnchorEdge
assert(anchoredWidget != getParentWidget());
UIAnchor anchor(anchoredEdge, hookedWidgetId, hookedEdge);
UIAnchorGroup& anchorGroup = m_anchorsGroups[anchoredWidget];
anchorGroup.addAnchor(anchor);
UIAnchorPtr anchor(new UIAnchor(anchoredEdge, hookedWidgetId, hookedEdge));
UIAnchorGroupPtr& anchorGroup = m_anchorsGroups[anchoredWidget];
if(!anchorGroup)
anchorGroup = UIAnchorGroupPtr(new UIAnchorGroup);
anchorGroup->addAnchor(anchor);
// layout must be updated because a new anchor got in
update();
@@ -86,7 +159,7 @@ void UIAnchorLayout::removeWidget(const UIWidgetPtr& widget)
removeAnchors(widget);
}
bool UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anchorGroup, UIWidgetPtr first)
bool UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, const UIAnchorGroupPtr& anchorGroup, UIWidgetPtr first)
{
UIWidgetPtr parentWidget = getParentWidget();
if(!parentWidget)
@@ -105,23 +178,13 @@ bool UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anch
bool horizontalMoved = false;
// calculates new rect based on anchors
for(const UIAnchor& anchor : anchorGroup.getAnchors()) {
for(const UIAnchorPtr& anchor : anchorGroup->getAnchors()) {
// skip invalid anchors
if(anchor.getHookedEdge() == Fw::AnchorNone)
if(anchor->getHookedEdge() == Fw::AnchorNone)
continue;
// determine hooked widget
UIWidgetPtr hookedWidget;
if(parentWidget) {
if(anchor.getHookedWidgetId() == "parent")
hookedWidget = parentWidget;
else if(anchor.getHookedWidgetId() == "next")
hookedWidget = parentWidget->getChildAfter(widget);
else if(anchor.getHookedWidgetId() == "prev")
hookedWidget = parentWidget->getChildBefore(widget);
else
hookedWidget = parentWidget->getChildById(anchor.getHookedWidgetId());
}
UIWidgetPtr hookedWidget = anchor->getHookedWidget(widget, parentWidget);
// skip invalid anchors
if(!hookedWidget)
@@ -131,61 +194,15 @@ bool UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anch
// update this hooked widget anchors
auto it = m_anchorsGroups.find(hookedWidget);
if(it != m_anchorsGroups.end()) {
UIAnchorGroup& hookedAnchorGroup = it->second;
if(!hookedAnchorGroup.isUpdated())
const UIAnchorGroupPtr& hookedAnchorGroup = it->second;
if(!hookedAnchorGroup->isUpdated())
updateWidget(hookedWidget, hookedAnchorGroup, first);
}
}
// determine hooked widget edge point
Rect hookedWidgetRect = hookedWidget->getRect();
if(hookedWidget == parentWidget)
hookedWidgetRect = parentWidget->getPaddingRect();
int point = anchor->getHookedPoint(hookedWidget, parentWidget);
int point = 0;
switch(anchor.getHookedEdge()) {
case Fw::AnchorLeft:
point = hookedWidgetRect.left();
break;
case Fw::AnchorRight:
point = hookedWidgetRect.right();
break;
case Fw::AnchorTop:
point = hookedWidgetRect.top();
break;
case Fw::AnchorBottom:
point = hookedWidgetRect.bottom();
break;
case Fw::AnchorHorizontalCenter:
point = hookedWidgetRect.horizontalCenter();
break;
case Fw::AnchorVerticalCenter:
point = hookedWidgetRect.verticalCenter();
break;
default:
// must never happens
assert(false);
break;
}
if(hookedWidget == parentWidget) {
switch(anchor.getHookedEdge()) {
case Fw::AnchorLeft:
case Fw::AnchorRight:
case Fw::AnchorHorizontalCenter:
point -= parentWidget->getVirtualOffset().x;
break;
case Fw::AnchorBottom:
case Fw::AnchorTop:
case Fw::AnchorVerticalCenter:
point -= parentWidget->getVirtualOffset().y;
break;
default:
break;
}
}
switch(anchor.getAnchoredEdge()) {
switch(anchor->getAnchoredEdge()) {
case Fw::AnchorHorizontalCenter:
newRect.moveHorizontalCenter(point + widget->getMarginLeft() - widget->getMarginRight());
horizontalMoved = true;
@@ -230,7 +247,7 @@ bool UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anch
bool changed = false;
if(widget->setRect(newRect))
changed = true;
anchorGroup.setUpdated(true);
anchorGroup->setUpdated(true);
return changed;
}
@@ -240,15 +257,15 @@ bool UIAnchorLayout::internalUpdate()
// reset all anchors groups update state
for(auto& it : m_anchorsGroups) {
UIAnchorGroup& anchorGroup = it.second;
anchorGroup.setUpdated(false);
const UIAnchorGroupPtr& anchorGroup = it.second;
anchorGroup->setUpdated(false);
}
// update all anchors
for(auto& it : m_anchorsGroups) {
const UIWidgetPtr& widget = it.first;
UIAnchorGroup& anchorGroup = it.second;
if(!anchorGroup.isUpdated()) {
const UIAnchorGroupPtr& anchorGroup = it.second;
if(!anchorGroup->isUpdated()) {
if(updateWidget(widget, anchorGroup))
changed = true;
}

View File

@@ -25,30 +25,30 @@
#include "uilayout.h"
class UIAnchor
class UIAnchor : public stdext::shared_object
{
public:
UIAnchor(Fw::AnchorEdge anchoredEdge, const std::string& hookedWidgetId, Fw::AnchorEdge hookedEdge) :
m_anchoredEdge(anchoredEdge), m_hookedEdge(hookedEdge), m_hookedWidgetId(hookedWidgetId) { }
Fw::AnchorEdge getAnchoredEdge() const { return m_anchoredEdge; }
std::string getHookedWidgetId() const { return m_hookedWidgetId; }
Fw::AnchorEdge getHookedEdge() const { return m_hookedEdge; }
private:
virtual UIWidgetPtr getHookedWidget(const UIWidgetPtr& widget, const UIWidgetPtr& parentWidget);
virtual int getHookedPoint(const UIWidgetPtr& hookedWidget, const UIWidgetPtr& parentWidget);
protected:
Fw::AnchorEdge m_anchoredEdge;
Fw::AnchorEdge m_hookedEdge;
std::string m_hookedWidgetId;
};
typedef std::vector<UIAnchor> UIAnchorList;
class UIAnchorGroup
class UIAnchorGroup : public stdext::shared_object
{
public:
UIAnchorGroup() : m_updated(true) { }
void addAnchor(const UIAnchor& anchor);
void addAnchor(const UIAnchorPtr& anchor);
const UIAnchorList& getAnchors() { return m_anchors; }
bool isUpdated() { return m_updated; }
void setUpdated(bool updated) { m_updated = updated; }
@@ -77,11 +77,9 @@ public:
bool isUIAnchorLayout() { return true; }
protected:
bool internalUpdate();
private:
bool updateWidget(const UIWidgetPtr& widget, UIAnchorGroup& anchorGroup, UIWidgetPtr first = nullptr);
std::unordered_map<UIWidgetPtr, UIAnchorGroup> m_anchorsGroups;
virtual bool internalUpdate();
virtual bool updateWidget(const UIWidgetPtr& widget, const UIAnchorGroupPtr& anchorGroup, UIWidgetPtr first = nullptr);
std::unordered_map<UIWidgetPtr, UIAnchorGroupPtr> m_anchorsGroups;
};
#endif

View File

@@ -31,6 +31,7 @@
#include <framework/platform/platformwindow.h>
#include <framework/graphics/texturemanager.h>
#include <framework/core/application.h>
#include <framework/luaengine/luainterface.h>
UIWidget::UIWidget()
{

View File

@@ -407,4 +407,4 @@ void UIWidget::setIcon(const std::string& iconFile)
m_icon = g_textures.getTexture(iconFile);
if(m_icon && !m_iconClipRect.isValid())
m_iconClipRect = Rect(0, 0, m_icon->getSize());
}
}