From 5662b7d9ad9eb6927df7ca83713d3b6108f59ddc Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Tue, 7 Jul 2009 11:23:14 -0600 Subject: Use tmw-skills.xml instead of hardcoding --- src/gui/skilldialog.cpp | 365 +++++++++++++++++--------------------- src/gui/skilldialog.h | 30 +++- src/gui/widgets/tabbedarea.cpp | 10 ++ src/gui/widgets/tabbedarea.h | 5 + src/gui/widgets/vertcontainer.cpp | 53 ++++++ src/gui/widgets/vertcontainer.h | 47 +++++ 6 files changed, 303 insertions(+), 207 deletions(-) create mode 100644 src/gui/widgets/vertcontainer.cpp create mode 100644 src/gui/widgets/vertcontainer.h (limited to 'src/gui') diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index f0cd01ce..a0b8f569 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -25,105 +25,66 @@ #include "gui/widgets/container.h" #include "gui/widgets/icon.h" #include "gui/widgets/label.h" +#include "gui/widgets/layouthelper.h" #include "gui/widgets/listbox.h" #include "gui/widgets/progressbar.h" #include "gui/widgets/scrollarea.h" +#include "gui/widgets/tab.h" #include "gui/widgets/tabbedarea.h" +#include "gui/widgets/vertcontainer.h" #include "gui/widgets/windowcontainer.h" #include "localplayer.h" +#include "log.h" #include "utils/dtor.h" #include "utils/gettext.h" #include "utils/stringutils.h" +#include "utils/xml.h" #include #include -class SkillTab : public Container, public gcn::ActionListener +class SkillEntry; + +struct SkillInfo +{ + unsigned short id; + std::string name; + std::string icon; + bool modifiable; + SkillEntry *display; +}; + +class SkillEntry : public Container { public: - /** - * The type of this skill tab - */ - const std::string type; - - /** - * Constructor - */ - SkillTab(const std::string &type); - - /** - * Update this tab - */ - void update(); + SkillEntry(struct SkillInfo *info); - /** - * Called when receiving actions from widget. - */ - void action(const gcn::ActionEvent &event) {} + void update(); private: - /** - * Update the information of a skill at - * the given index - */ - void updateSkill(int index); - - /** - * Gets the number of skills in this particular - * type of tab. - */ - int getSkillNum(); - - /** - * Get the first enumeration of this skill tab's - * skill type. - */ - int getSkillBegin(); - - /** - * Get the icon associated with the given index - */ - Icon *getIcon(int index); - - std::vector mSkillIcons; - std::vector mSkillNameLabels; - std::vector mSkillLevelLabels; - std::vector mSkillExpLabels; - std::vector mSkillProgress; + struct SkillInfo *mInfo; + Icon *mIcon; + Label *mNameLabel; + Label *mLevelLabel; + Label *mExpLabel; + ProgressBar *mProgress; }; - SkillDialog::SkillDialog(): Window(_("Skills")) { setWindowName("Skills"); setCloseButton(true); + setResizable(true); setSaveVisible(true); setDefaultSize(windowContainer->getWidth() - 280, 30, 275, 425); - TabbedArea *panel = new TabbedArea; - panel->setDimension(gcn::Rectangle(5, 5, 270, 420)); - - SkillTab *tab; + mTabs = new TabbedArea(); - // Add each type of skill tab to the panel - tab = new SkillTab("Weapon"); - panel->addTab(_("Weapons"), tab); - mTabs.push_back(tab); - - tab = new SkillTab("Magic"); - panel->addTab(_("Magic"), tab); - mTabs.push_back(tab); - - tab = new SkillTab("Craft"); - panel->addTab(_("Crafts"), tab); - mTabs.push_back(tab); - - add(panel); - - update(); + place(0, 0, mTabs, 5, 5); + place(0, 5, new Label("TODO")); setLocationRelativeTo(getParent()); loadWindowState(); @@ -131,7 +92,7 @@ SkillDialog::SkillDialog(): SkillDialog::~SkillDialog() { - delete_all(mTabs); + //delete_all(mTabs); } void SkillDialog::action(const gcn::ActionEvent &event) @@ -145,174 +106,182 @@ void SkillDialog::action(const gcn::ActionEvent &event) } } -void SkillDialog::draw(gcn::Graphics *g) -{ - update(); - - Window::draw(g); -} - -void SkillDialog::update() +void SkillDialog::adjustTabSize() { - for(std::list::const_iterator i = mTabs.begin(); - i != mTabs.end(); ++i) - { - (*i)->update(); + gcn::Widget *content = mTabs->getCurrentWidget(); + if (content) { + int width = mTabs->getWidth() - 2 * content->getFrameSize(); + int height = mTabs->getContainerHeight() - 2 * content->getFrameSize(); + content->setSize(width, height); + content->setVisible(true); + content->logic(); } } -SkillTab::SkillTab(const std::string &type): type(type) +void SkillDialog::widgetResized(const gcn::Event &event) { - setOpaque(false); - setDimension(gcn::Rectangle(0, 0, 270, 420)); - int skillNum = getSkillNum(); - - mSkillIcons.resize(skillNum); - mSkillNameLabels.resize(skillNum); - mSkillLevelLabels.resize(skillNum); - mSkillExpLabels.resize(skillNum); - mSkillProgress.resize(skillNum); - - // Set the initial positions of the skill information - for (int a = 0; a < skillNum; a++) - { - mSkillIcons.at(a) = getIcon(a); - mSkillIcons.at(a)->setPosition(1, a*32); - add(mSkillIcons.at(a)); - - mSkillNameLabels.at(a) = new Label(""); - mSkillNameLabels.at(a)->setPosition(35, a*32 ); - add(mSkillNameLabels.at(a)); + Window::widgetResized(event); - mSkillProgress.at(a) = new ProgressBar(0.0f, 200, 20, gcn::Color(150, 150, 150)); - mSkillProgress.at(a)->setPosition(35, a*32 + 13); - add(mSkillProgress.at(a)); + adjustTabSize(); +} - mSkillExpLabels.at(a) = new Label(""); - mSkillExpLabels.at(a)->setPosition(45, a*32 + 16); - add(mSkillExpLabels.at(a)); +void SkillDialog::logic() +{ + Window::logic(); - mSkillLevelLabels.at(a) = new Label(""); - mSkillLevelLabels.at(a)->setPosition(165, a*32); - add(mSkillLevelLabels.at(a)); + Tab *tab = dynamic_cast(mTabs->getSelectedTab()); + if (tab != mCurrentTab) { + mCurrentTab = tab; + adjustTabSize(); } - - update(); } -int SkillTab::getSkillNum() +std::string SkillDialog::update(int id) { - int skillNum = 0; + SkillInfo *info = mSkills[id]; - if (type == "Weapon") - { - skillNum = CHAR_SKILL_WEAPON_NB; - return skillNum; - } - else if (type == "Magic") - { - skillNum = CHAR_SKILL_MAGIC_NB; - return skillNum; - } - else if (type == "Craft") + if (info) { - skillNum = CHAR_SKILL_CRAFT_NB; - return skillNum; + info->display->update(); + return info->name; } - else return skillNum; + else + return ""; } -int SkillTab::getSkillBegin() +void SkillDialog::loadSkills(const std::string &file, bool fixed) { - int skillBegin = 0; + // TODO: mTabs->clear(); + delete_all(mSkills); - if (type == "Weapon") - { - skillBegin = CHAR_SKILL_WEAPON_BEGIN - CHAR_SKILL_BEGIN; - return skillBegin; - } - else if (type == "Magic") + XML::Document doc(file); + xmlNodePtr root = doc.rootNode(); + + if (!root || !xmlStrEqual(root->name, BAD_CAST "skills")) { - skillBegin = CHAR_SKILL_MAGIC_BEGIN - CHAR_SKILL_BEGIN; - return skillBegin; + logger->log("Error loading skills file: %s", file.c_str()); + return; } - else if (type == "Craft") + + int setCount = 0; + std::string setName; + ScrollArea *scroll; + VertContainer *container; + std::string fixedDef = toString(fixed); + + for_each_xml_child_node(set, root) { - skillBegin = CHAR_SKILL_CRAFT_BEGIN - CHAR_SKILL_BEGIN; - return skillBegin; + if (xmlStrEqual(set->name, BAD_CAST "set")) + { + setCount++; + setName = XML::getProperty(set, "name", strprintf(_("Skill Set %d"), setCount)); + + container = new VertContainer(32); + container->setOpaque(false); + scroll = new ScrollArea(container); + scroll->setOpaque(false); + scroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER); + scroll->setVerticalScrollPolicy(ScrollArea::SHOW_ALWAYS); + + mTabs->addTab(setName, scroll); + for_each_xml_child_node(node, set) + { + if (xmlStrEqual(node->name, BAD_CAST "skill")) + { + int id = atoi(XML::getProperty(node, "id", "-1").c_str()); + std::string name = XML::getProperty(node, "name", strprintf(_("Skill %d"), id)); + std::string icon = XML::getProperty(node, "icon", ""); + bool modifiable = !atoi(XML::getProperty(node, "fixed", fixedDef).c_str()); + + SkillInfo *skill = new SkillInfo; + skill->id = id; + skill->name = name; + skill->icon = icon; + skill->modifiable = modifiable; + skill->display = new SkillEntry(skill); + + container->add(skill->display); + + mSkills[id] = skill; + } + } + } } - else return skillBegin; -} -Icon* SkillTab::getIcon(int index) -{ - int skillBegin = getSkillBegin(); - std::string icon = LocalPlayer::getSkillInfo(index + skillBegin).icon; - return new Icon(icon); + adjustTabSize(); } -void SkillTab::updateSkill(int index) +SkillEntry::SkillEntry(struct SkillInfo *info) : mInfo(info), + mIcon(NULL), + mNameLabel(new Label(info->name)), + mProgress(new ProgressBar(0.0f, 200, 20, gcn::Color(150, 150, 150))), + mLevelLabel(new Label("999")) { - int skillBegin = getSkillBegin(); + setOpaque(false); + + if (!info->icon.empty()) + mIcon = new Icon(info->icon); - int baseLevel = player_node->getAttributeBase(index + - skillBegin + - CHAR_SKILL_BEGIN); + /*LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); - int effLevel = player_node->getAttributeEffective(index + - skillBegin + - CHAR_SKILL_BEGIN); - if(baseLevel <= 0) + if (mIcon) + place(0, 0, mIcon, 1, 2); + place(1, 0, mNameLabel, 3); + place(4, 0, mLevelLabel); + place(1, 1, mProgress, 4);*/ + + if (mIcon) { - mSkillProgress.at(index)->setVisible(false); - mSkillExpLabels.at(index)->setVisible(false); - mSkillLevelLabels.at(index)->setVisible(false); - mSkillNameLabels.at(index)->setVisible(false); - mSkillIcons.at(index)->setVisible(false); + mIcon->setPosition(1, 0); + add(mIcon); } - else - { - mSkillProgress.at(index)->setVisible(true); - mSkillExpLabels.at(index)->setVisible(true); - mSkillLevelLabels.at(index)->setVisible(true); - mSkillNameLabels.at(index)->setVisible(true); - mSkillIcons.at(index)->setVisible(true); - std::string skillLevel("Lvl: " + toString(baseLevel)); - if (effLevel < baseLevel) - { - skillLevel.append(" - " + toString(baseLevel - effLevel)); - } - else if (effLevel > baseLevel) - { - skillLevel.append(" + " + toString(effLevel - baseLevel)); - } - mSkillLevelLabels.at(index)->setCaption(skillLevel); - std::pair exp = player_node->getExperience(index + skillBegin); - std::string sExp (toString(exp.first) + " / " + toString(exp.second)); + mNameLabel->setPosition(35, 0); + add(mNameLabel); + mLevelLabel->setPosition(165, 0); + add(mLevelLabel); - mSkillNameLabels.at(index)->setCaption(LocalPlayer::getSkillInfo(index + skillBegin).name); - mSkillNameLabels.at(index)->adjustSize(); - mSkillLevelLabels.at(index)->adjustSize(); - mSkillExpLabels.at(index)->setCaption(sExp); - mSkillExpLabels.at(index)->adjustSize(); - mSkillExpLabels.at(index)->setAlignment(gcn::Graphics::RIGHT); + mProgress->setPosition(35, 13); + add(mProgress); - // More intense red as exp grows - int color = 150 - (int)(150 * ((float) exp.first / exp.second)); - mSkillProgress.at(index)->setColor(244, color, color); - mSkillProgress.at(index)->setProgress((float) exp.first / exp.second); - } + update(); } -void SkillTab::update() +void SkillEntry::update() { - int skillNum = getSkillNum(); + int baseLevel = player_node->getAttributeBase(mInfo->id); + + int effLevel = player_node->getAttributeEffective(mInfo->id); + + if (baseLevel <= 0) + { + setVisible(false); + return; + } - // Update the skill information for reach skill - for (int a = 0; a < skillNum; a++) + setVisible(true); + + std::string skillLevel("Lvl: " + toString(baseLevel)); + if (effLevel < baseLevel) + { + skillLevel.append(" - " + toString(baseLevel - effLevel)); + } + else if (effLevel > baseLevel) { - updateSkill(a); + skillLevel.append(" + " + toString(effLevel - baseLevel)); } + mLevelLabel->setCaption(skillLevel); + + std::pair exp = player_node->getExperience(mInfo->id); + std::string sExp (toString(exp.first) + " / " + toString(exp.second)); + + mLevelLabel->adjustSize(); + mProgress->setText(sExp); + + // More intense red as exp grows + int color = 150 - (int)(150 * ((float) exp.first / exp.second)); + mProgress->setColor(244, color, color); + mProgress->setProgress((float) exp.first / exp.second); } diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h index 56192273..fbd3c26d 100644 --- a/src/gui/skilldialog.h +++ b/src/gui/skilldialog.h @@ -29,10 +29,13 @@ #include #include +#include -class ProgressBar; -class Icon; -class SkillTab; +class ScrollArea; +class Tab; +class TabbedArea; + +struct SkillInfo; /** * The skill dialog. @@ -52,17 +55,26 @@ class SkillDialog : public Window, public gcn::ActionListener void action(const gcn::ActionEvent &event); /** - * Update the tabs in this dialog + * Called when the widget changes size. Used for adapting the size of + * the tabbed area. */ - void update(); + void widgetResized(const gcn::Event &event); + + void logic(); /** - * Draw this window. - */ - void draw(gcn::Graphics *g); + * Update the given skill's display + */ + std::string update(int id); + + void loadSkills(const std::string &file, bool fixed = true); private: - std::list mTabs; + void adjustTabSize(); + + Tab *mCurrentTab; + TabbedArea *mTabs; + std::map mSkills; }; extern SkillDialog *skillDialog; diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index 07f46a94..bb5ae9a4 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -69,6 +69,16 @@ gcn::Widget *TabbedArea::getWidget(const std::string &name) const return NULL; } +gcn::Widget *TabbedArea::getCurrentWidget() +{ + gcn::Tab *tab = getSelectedTab(); + + if (tab) + return getWidget(tab->getCaption()); + else + return NULL; +} + void TabbedArea::addTab(const std::string &caption, gcn::Widget *widget) { Tab *tab = new Tab; diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h index 6aaafe16..29ba2f76 100644 --- a/src/gui/widgets/tabbedarea.h +++ b/src/gui/widgets/tabbedarea.h @@ -63,6 +63,11 @@ class TabbedArea : public gcn::TabbedArea */ gcn::Widget *getWidget(const std::string &name) const; + /** + * Returns the widget for the current tab + */ + gcn::Widget *getCurrentWidget(); + using gcn::TabbedArea::addTab; /** diff --git a/src/gui/widgets/vertcontainer.cpp b/src/gui/widgets/vertcontainer.cpp new file mode 100644 index 00000000..9dd02cdc --- /dev/null +++ b/src/gui/widgets/vertcontainer.cpp @@ -0,0 +1,53 @@ +/* + * The Mana World + * Copyright (C) 2009 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "gui/widgets/vertcontainer.h" + +VertContainer::VertContainer(int spacing): + mSpacing(spacing), + mCount(0) +{ + addWidgetListener(this); +} + +void VertContainer::add(gcn::Widget *widget) +{ + Container::add(widget); + widget->setPosition(0, mCount * mSpacing); + widget->setSize(getWidth(), mSpacing); + mCount++; + setHeight(mCount * mSpacing); +} + +void VertContainer::clear() +{ + Container::clear(); + + mCount = 0; +} + +void VertContainer::widgetResized(const gcn::Event &event) +{ + for (WidgetListIterator it = mWidgets.begin(); it != mWidgets.end(); it++) + { + (*it)->setWidth(getWidth()); + } +} diff --git a/src/gui/widgets/vertcontainer.h b/src/gui/widgets/vertcontainer.h new file mode 100644 index 00000000..9e15e66a --- /dev/null +++ b/src/gui/widgets/vertcontainer.h @@ -0,0 +1,47 @@ +/* + * The Mana World + * Copyright (C) 2009 The Mana World Development Team + * + * This file is part of The Mana World. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef GUI_VERTCONTAINER_H +#define GUI_VERTCONTAINER_H + +#include "gui/widgets/container.h" + +#include + +/** + * A widget container. + * + * This container places it's contents veritcally. + */ +class VertContainer : public Container, public gcn::WidgetListener +{ + public: + VertContainer(int spacing); + virtual void add(gcn::Widget *widget); + virtual void clear(); + void widgetResized(const gcn::Event &event); + + private: + int mSpacing; + int mCount; +}; + +#endif -- cgit v1.2.3-70-g09d2