diff options
Diffstat (limited to 'src/gui')
83 files changed, 1974 insertions, 880 deletions
diff --git a/src/gui/button.cpp b/src/gui/button.cpp index 1d3a04e4..f9e5e9dc 100644 --- a/src/gui/button.cpp +++ b/src/gui/button.cpp @@ -23,6 +23,7 @@ #include <guichan/font.hpp> #include "button.h" +#include "palette.h" #include "../configuration.h" #include "../graphics.h" @@ -72,9 +73,9 @@ Button::Button(const std::string& caption, const std::string &actionEventId, { init(); setActionEventId(actionEventId); - if (listener) { + + if (listener) addActionListener(listener); - } } void Button::init() @@ -93,8 +94,10 @@ void Button::init() { btn[mode] = resman->getImage(data[mode].file); a = 0; - for (y = 0; y < 3; y++) { - for (x = 0; x < 3; x++) { + for (y = 0; y < 3; y++) + { + for (x = 0; x < 3; x++) + { button[mode].grid[a] = btn[mode]->getSubImage( data[x].gridX, data[y].gridY, data[x + 1].gridX - data[x].gridX + 1, @@ -150,7 +153,7 @@ void Button::draw(gcn::Graphics *graphics) static_cast<Graphics*>(graphics)-> drawImageRect(0, 0, getWidth(), getHeight(), button[mode]); - graphics->setColor(getForegroundColor()); + graphics->setColor(guiPalette->getColor(Palette::TEXT)); int textX; int textY = getHeight() / 2 - getFont()->getHeight() / 2; diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp index 7e03c591..c5c37601 100644 --- a/src/gui/buy.cpp +++ b/src/gui/buy.cpp @@ -19,10 +19,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/widgets/label.hpp> - #include "button.h" #include "buy.h" +#include "label.h" #include "scrollarea.h" #include "shop.h" #include "shoplistbox.h" @@ -40,34 +39,39 @@ #include "../utils/strprintf.h" BuyDialog::BuyDialog(Network *network): - Window(_("Buy")), mNetwork(network), + Window("Buy"), mNetwork(network), mMoney(0), mAmountItems(0), mMaxItems(0) { setWindowName("Buy"); setResizable(true); + setCloseButton(true); setMinWidth(260); setMinHeight(230); - setDefaultSize(0, 0, 260, 230); + setDefaultSize(260, 230, ImageRect::CENTER); mShopItems = new ShopItems; mShopItemList = new ShopListBox(mShopItems, mShopItems); mScrollArea = new ScrollArea(mShopItemList); + mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mSlider = new Slider(1.0); - mQuantityLabel = new gcn::Label("0"); + mQuantityLabel = new Label(strprintf("%d / %d", mAmountItems, mMaxItems)); + mQuantityLabel->setAlignment(gcn::Graphics::CENTER); mMoneyLabel = new gcn::Label(strprintf(_("Price: %s / Total: %s"), "", "")); + mIncreaseButton = new Button("+", "+", this); mDecreaseButton = new Button("-", "-", this); mBuyButton = new Button(_("Buy"), "buy", this); mQuitButton = new Button(_("Quit"), "quit", this); - mItemDescLabel = new gcn::Label(strprintf(_("Description: %s"), "")); - mItemEffectLabel = new gcn::Label(strprintf(_("Effect: %s"), "")); + mAddMaxButton = new Button(_("Max"), "max", this); + mItemDescLabel = new Label(strprintf(_("Description: %s"), "")); + mItemEffectLabel = new Label(strprintf(_("Effect: %s"), "")); - mIncreaseButton->setSize(20, 20); - mDecreaseButton->setSize(20, 20); + mDecreaseButton->adjustSize(); + mDecreaseButton->setWidth(mIncreaseButton->getWidth()); - mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); mIncreaseButton->setEnabled(false); mDecreaseButton->setEnabled(false); mBuyButton->setEnabled(false); @@ -77,16 +81,21 @@ BuyDialog::BuyDialog(Network *network): mSlider->addActionListener(this); mShopItemList->addSelectionListener(this); - place(0, 0, mScrollArea, 5).setPadding(3); - place(0, 1, mQuantityLabel, 2); - place(2, 1, mSlider, 3); - place(0, 2, mMoneyLabel, 5); - place(0, 3, mItemEffectLabel, 5); - place(0, 4, mItemDescLabel, 5); + ContainerPlacer place; + place = getPlacer(0, 0); + + place(0, 0, mScrollArea, 8, 5).setPadding(3); place(0, 5, mDecreaseButton); - place(1, 5, mIncreaseButton); - place(3, 5, mBuyButton); - place(4, 5, mQuitButton); + place(1, 5, mSlider, 3); + place(4, 5, mIncreaseButton); + place(5, 5, mQuantityLabel, 2); + place(7, 5, mAddMaxButton); + place(0, 6, mMoneyLabel, 8); + place(0, 7, mItemEffectLabel, 8); + place(0, 8, mItemDescLabel, 8); + place(6, 9, mBuyButton); + place(7, 9, mQuitButton); + Layout &layout = getLayout(); layout.setRowHeight(0, Layout::AUTO_SET); @@ -127,15 +136,14 @@ void BuyDialog::addItem(int id, int price) void BuyDialog::action(const gcn::ActionEvent &event) { - int selectedItem = mShopItemList->getSelected(); - if (event.getId() == "quit") { - setVisible(false); - current_npc = 0; + close(); return; } + int selectedItem = mShopItemList->getSelected(); + // The following actions require a valid selection if (selectedItem < 0 || selectedItem >= (int) mShopItems->getNumberOfElements()) @@ -160,6 +168,12 @@ void BuyDialog::action(const gcn::ActionEvent &event) mSlider->setValue(mAmountItems); updateButtonsAndLabels(); } + else if (event.getId() == "max") + { + mAmountItems = mMaxItems; + mSlider->setValue(mAmountItems); + updateButtonsAndLabels(); + } // TODO: Actually we'd have a bug elsewhere if this check for the number // of items to be bought ever fails, Bertram removed the assertions, is // there a better way to ensure this fails in an _obvious_ way in C++? @@ -253,5 +267,12 @@ void BuyDialog::setVisible(bool visible) { Window::setVisible(visible); - if (visible) requestFocus(); + if (visible) + requestFocus(); +} + +void BuyDialog::close() +{ + setVisible(false); + current_npc = 0; } diff --git a/src/gui/buy.h b/src/gui/buy.h index 5e2f0b8f..2e6b5377 100644 --- a/src/gui/buy.h +++ b/src/gui/buy.h @@ -100,12 +100,20 @@ class BuyDialog : public Window, public gcn::ActionListener, */ void logic(); + /** + * Sets the visibility of this window. + */ void setVisible(bool visible); + /** + * Closes the Buy Window, as well as resetting the current npc. + */ + void close(); private: Network *mNetwork; gcn::Button *mBuyButton; gcn::Button *mQuitButton; + gcn::Button *mAddMaxButton; gcn::Button *mIncreaseButton; gcn::Button *mDecreaseButton; ShopListBox *mShopItemList; diff --git a/src/gui/buysell.cpp b/src/gui/buysell.cpp index e6dc7c1f..04a27b8c 100644 --- a/src/gui/buysell.cpp +++ b/src/gui/buysell.cpp @@ -60,16 +60,16 @@ void BuySellDialog::logic() { Window::logic(); - if (isVisible() && !current_npc) { + if (isVisible() && !current_npc) setVisible(false); - } } void BuySellDialog::setVisible(bool visible) { Window::setVisible(visible); - if (visible) requestFocus(); + if (visible) + requestFocus(); } void BuySellDialog::action(const gcn::ActionEvent &event) diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp index 709988a3..aaf4e8c4 100644 --- a/src/gui/char_select.cpp +++ b/src/gui/char_select.cpp @@ -23,11 +23,10 @@ #include <guichan/font.hpp> -#include <guichan/widgets/label.hpp> - #include "button.h" #include "char_select.h" #include "confirm_dialog.h" +#include "label.h" #include "ok_dialog.h" #include "playerbox.h" #include "textfield.h" @@ -94,10 +93,10 @@ CharSelectDialog::CharSelectDialog(Network *network, mPlayerBox = new PlayerBox; mPlayerBox->setWidth(74); - mNameLabel = new gcn::Label(strprintf(_("Name: %s"), "")); - mLevelLabel = new gcn::Label(strprintf(_("Level: %d"), 0)); - mJobLevelLabel = new gcn::Label(strprintf(_("Job Level: %d"), 0)); - mMoneyLabel = new gcn::Label(strprintf(_("Money: %s"), mMoney.c_str())); + mNameLabel = new Label(strprintf(_("Name: %s"), "")); + mLevelLabel = new Label(strprintf(_("Level: %d"), 0)); + mJobLevelLabel = new Label(strprintf(_("Job Level: %d"), 0)); + mMoneyLabel = new Label(strprintf(_("Money: %s"), mMoney.c_str())); const std::string tempString = getFont()->getWidth(_("New")) < getFont()->getWidth(_("Delete")) ? @@ -271,13 +270,13 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network, mPlayer->setHairStyle(rand() % mPlayer->getNumOfHairstyles(), rand() % numberOfHairColors); mNameField = new TextField(""); - mNameLabel = new gcn::Label(_("Name:")); + mNameLabel = new Label(_("Name:")); mNextHairColorButton = new Button(">", "nextcolor", this); mPrevHairColorButton = new Button("<", "prevcolor", this); - mHairColorLabel = new gcn::Label(_("Hair Color:")); + mHairColorLabel = new Label(_("Hair Color:")); mNextHairStyleButton = new Button(">", "nextstyle", this); mPrevHairStyleButton = new Button("<", "prevstyle", this); - mHairStyleLabel = new gcn::Label(_("Hair Style:")); + mHairStyleLabel = new Label(_("Hair Style:")); mCreateButton = new Button(_("Create"), "create", this); mCancelButton = new Button(_("Cancel"), "cancel", this); mPlayerBox = new PlayerBox(mPlayer); diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index 55bc2696..94a554e8 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -54,7 +54,7 @@ Window(""), mNetwork(network), mTmpVisible(false) setWindowName("Chat"); setResizable(true); - setDefaultSize(0, windowContainer->getHeight() - 123, 600, 123); + setDefaultSize(600, 123, ImageRect::LOWER_LEFT); setMinWidth(150); setMinHeight(90); @@ -112,6 +112,12 @@ ChatWindow::~ChatWindow() delete mParty; } +void ChatWindow::resetToDefaultSize() +{ + mRecorder->resetToDefaultSize(); + Window::resetToDefaultSize(); +} + void ChatWindow::chatLog(std::string line, int own, bool ignoreRecord) { // Trim whitespace @@ -142,12 +148,12 @@ void ChatWindow::chatLog(std::string line, int own, bool ignoreRecord) // *implements actions in a backwards compatible way* if (own == BY_PLAYER && - tmp.text.at(0) == '*' && - tmp.text.at(tmp.text.length()-1) == '*') + tmp.text.at(0) == '*' && + tmp.text.at(tmp.text.length()-1) == '*') { - tmp.text[0] = ' '; - tmp.text.erase(tmp.text.length() - 1); - own = ACT_IS; + tmp.text[0] = ' '; + tmp.text.erase(tmp.text.length() - 1); + own = ACT_IS; } std::string lineColor = "##C"; @@ -629,9 +635,9 @@ void ChatWindow::chatSend(const std::string &nick, std::string msg) } else if (command == "me") { - std::stringstream actionStr; - actionStr << "*" << msg << "*"; - chatSend(player_node->getName(), actionStr.str()); + std::stringstream actionStr; + actionStr << "*" << msg << "*"; + chatSend(player_node->getName(), actionStr.str()); } else { diff --git a/src/gui/chat.h b/src/gui/chat.h index 6002fed3..09f3260b 100644 --- a/src/gui/chat.h +++ b/src/gui/chat.h @@ -119,6 +119,12 @@ class ChatWindow : public Window, public gcn::ActionListener, ~ChatWindow(); /** + * Reset the chat window and recorder window attached to it to their + * default positions. + */ + void resetToDefaultSize(); + + /** * Adds a line of text to our message list. Parameters: * * @param line Text message. @@ -238,12 +244,12 @@ class ChatWindow : public Window, public gcn::ActionListener, typedef std::list<std::string> History; typedef History::iterator HistoryIterator; History mHistory; /**< Command history */ - HistoryIterator mCurHist; /**< History iterator */ - Recorder *mRecorder; /**< Recording class */ - char mPartyPrefix; /**< Messages beginning with the prefix are sent to - the party */ - bool mReturnToggles; /**< Marks whether <Return> toggles the chat log - or not */ + HistoryIterator mCurHist; /**< History iterator */ + Recorder *mRecorder; /**< Recording class */ + char mPartyPrefix; /**< Messages beginning with the prefix are + sent to the party */ + bool mReturnToggles; /**< Marks whether <Return> toggles the chat + log or not */ Party *mParty; }; extern ChatWindow *chatWindow; diff --git a/src/gui/checkbox.cpp b/src/gui/checkbox.cpp index 7fa4fa81..5695a23f 100644 --- a/src/gui/checkbox.cpp +++ b/src/gui/checkbox.cpp @@ -20,6 +20,7 @@ */ #include "checkbox.h" +#include "palette.h" #include "../configuration.h" #include "../graphics.h" @@ -68,6 +69,18 @@ CheckBox::~CheckBox() } } +void CheckBox::draw(gcn::Graphics* graphics) +{ + drawBox(graphics); + + graphics->setFont(getFont()); + graphics->setColor(guiPalette->getColor(Palette::TEXT)); + + const int h = getHeight() + getHeight() / 2; + + graphics->drawText(getCaption(), h - 2, 0); +} + void CheckBox::drawBox(gcn::Graphics* graphics) { Image *box; diff --git a/src/gui/checkbox.h b/src/gui/checkbox.h index 20adb43c..dd59493c 100644 --- a/src/gui/checkbox.h +++ b/src/gui/checkbox.h @@ -45,6 +45,11 @@ class CheckBox : public gcn::CheckBox ~CheckBox(); /** + * Draws the caption, then calls drawBox to draw the check box. + */ + void draw(gcn::Graphics* graphics); + + /** * Draws the check box, not the caption. */ void drawBox(gcn::Graphics* graphics); diff --git a/src/gui/connection.cpp b/src/gui/connection.cpp index 981100f9..658eade7 100644 --- a/src/gui/connection.cpp +++ b/src/gui/connection.cpp @@ -21,10 +21,9 @@ #include <guichan/actionlistener.hpp> -#include <guichan/widgets/label.hpp> - #include "button.h" #include "connection.h" +#include "label.h" #include "progressbar.h" #include "../main.h" @@ -46,7 +45,7 @@ ConnectionDialog::ConnectionDialog(): Button *cancelButton = new Button(_("Cancel"), "cancelButton", &listener); mProgressBar = new ProgressBar(0.0, 200 - 10, 20, 128, 128, 128); - gcn::Label *label = new gcn::Label(_("Connecting...")); + gcn::Label *label = new Label(_("Connecting...")); cancelButton->setPosition(5, 100 - 5 - cancelButton->getHeight()); mProgressBar->setPosition(5, cancelButton->getY() - 25); diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp index cf2f9613..a98c9af4 100644 --- a/src/gui/debugwindow.cpp +++ b/src/gui/debugwindow.cpp @@ -19,9 +19,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/widgets/label.hpp> - #include "debugwindow.h" +#include "label.h" #include "viewport.h" #include "widgets/layout.h" @@ -40,14 +39,14 @@ DebugWindow::DebugWindow(): setResizable(true); setCloseButton(true); - setDefaultSize(0, 0, 400, 60); - - mFPSLabel = new gcn::Label("0 FPS"); - mMusicFileLabel = new gcn::Label("Music: "); - mMapLabel = new gcn::Label("Map: "); - mMiniMapLabel = new gcn::Label("Mini-Map: "); - mTileMouseLabel = new gcn::Label("Mouse: 0, 0"); - mParticleCountLabel = new gcn::Label("Particle count: 0"); + setDefaultSize(400, 100, ImageRect::CENTER); + + mFPSLabel = new Label("0 FPS"); + mMusicFileLabel = new Label("Music: "); + mMapLabel = new Label("Map: "); + mMiniMapLabel = new Label("Mini-Map: "); + mTileMouseLabel = new Label("Mouse: 0, 0"); + mParticleCountLabel = new Label("Particle count: 0"); place(0, 0, mFPSLabel, 3); place(3, 0, mTileMouseLabel); diff --git a/src/gui/debugwindow.h b/src/gui/debugwindow.h index e089de27..8097132c 100644 --- a/src/gui/debugwindow.h +++ b/src/gui/debugwindow.h @@ -50,4 +50,6 @@ class DebugWindow : public Window gcn::Label *mParticleCountLabel; }; +extern DebugWindow *debugWindow; + #endif diff --git a/src/gui/emoteshortcutcontainer.cpp b/src/gui/emoteshortcutcontainer.cpp index c96ea855..661f42a7 100644 --- a/src/gui/emoteshortcutcontainer.cpp +++ b/src/gui/emoteshortcutcontainer.cpp @@ -20,6 +20,7 @@ */ #include "emoteshortcutcontainer.h" +#include "palette.h" #include "../animatedsprite.h" #include "../configuration.h" @@ -98,7 +99,7 @@ void EmoteShortcutContainer::draw(gcn::Graphics *graphics) // Draw emote keyboard shortcut. const char *key = SDL_GetKeyName( (SDLKey) keyboard.getKeyValue(keyboard.KEY_EMOTE_1 + i)); - graphics->setColor(0x000000); + graphics->setColor(guiPalette->getColor(Palette::TEXT)); g->drawText(key, emoteX + 2, emoteY + 2, gcn::Graphics::LEFT); if (emoteShortcut->getEmote(i)) diff --git a/src/gui/emotewindow.cpp b/src/gui/emotewindow.cpp index 48635720..d4b3cf2e 100644 --- a/src/gui/emotewindow.cpp +++ b/src/gui/emotewindow.cpp @@ -40,7 +40,7 @@ EmoteWindow::EmoteWindow(): setCloseButton(true); setMinWidth(80); setMinHeight(130); - setDefaultSize(115, 25, 322, 200); + setDefaultSize(322, 200, ImageRect::CENTER); mUseButton = new Button(_("Use"), "use", this); diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp index 9a00f7a7..856d7d03 100644 --- a/src/gui/equipmentwindow.cpp +++ b/src/gui/equipmentwindow.cpp @@ -27,6 +27,7 @@ #include "button.h" #include "equipmentwindow.h" #include "itempopup.h" +#include "palette.h" #include "playerbox.h" #include "viewport.h" @@ -62,6 +63,7 @@ EquipmentWindow::EquipmentWindow(): mSelected(-1) { mItemPopup = new ItemPopup; + mItemPopup->setOpaque(false); // Control that shows the Player mPlayerBox = new PlayerBox; @@ -70,7 +72,7 @@ EquipmentWindow::EquipmentWindow(): setWindowName("Equipment"); setCloseButton(true); - setDefaultSize(5, 195, 180, 300); + setDefaultSize(180, 300, ImageRect::CENTER); loadWindowState(); mUnequip = new Button(_("Unequip"), "unequip", this); @@ -112,6 +114,22 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) for (int i = EQUIP_LEGS_SLOT; i < EQUIP_VECTOREND; i++) { + if (i == mSelected) + { + const gcn::Color color = guiPalette->getColor(Palette::HIGHLIGHT); + + // Set color to the highligh color + g->setColor(gcn::Color(color.r, color.g, color.b, getGuiAlpha())); + g->fillRectangle(gcn::Rectangle(mEquipBox[i].posX, mEquipBox[i].posY, + BOX_WIDTH, BOX_HEIGHT)); + } + + // Set color black. + g->setColor(gcn::Color(0, 0, 0)); + // Draw box border. + g->drawRectangle(gcn::Rectangle(mEquipBox[i].posX, mEquipBox[i].posY, + BOX_WIDTH, BOX_HEIGHT)); + item = (i != EQUIP_AMMO_SLOT) ? mInventory->getItem(mEquipment->getEquipment(i)) : mInventory->getItem(mEquipment->getArrows()); @@ -122,28 +140,13 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) g->drawImage(image, mEquipBox[i].posX, mEquipBox[i].posY); if (i == EQUIP_AMMO_SLOT) { - g->setColor(gcn::Color(0, 0, 0)); + g->setColor(guiPalette->getColor(Palette::TEXT)); graphics->drawText(toString(item->getQuantity()), mEquipBox[i].posX + (BOX_WIDTH / 2), mEquipBox[i].posY - getFont()->getHeight(), gcn::Graphics::CENTER); } } - - if (i == mSelected) - { - // Set color red. - g->setColor(gcn::Color(255, 0, 0)); - } - else - { - // Set color black. - g->setColor(gcn::Color(0, 0, 0)); - } - - // Draw box border. - g->drawRectangle(gcn::Rectangle(mEquipBox[i].posX, mEquipBox[i].posY, - BOX_WIDTH, BOX_HEIGHT)); } } @@ -234,8 +237,9 @@ void EquipmentWindow::mouseMoved(gcn::MouseEvent &event) int mouseX, mouseY; SDL_GetMouseState(&mouseX, &mouseY); - mItemPopup->setItem(item->getInfo()); - mItemPopup->setOpaque(false); + if (item->getInfo().getName() != mItemPopup->getItemName()) + mItemPopup->setItem(item->getInfo()); + mItemPopup->updateColors(); mItemPopup->view(x + getX(), y + getY()); } else diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 4081eeac..83441e1b 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -27,6 +27,7 @@ #include "gui.h" #include "palette.h" #include "sdlinput.h" +#include "skin.h" #include "truetypefont.h" #include "viewport.h" #include "window.h" @@ -239,3 +240,8 @@ void Gui::handleMouseMoved(const gcn::MouseInput &mouseInput) gcn::Gui::handleMouseMoved(mouseInput); mMouseInactivityTimer = 0; } + +const int Gui::getFontHeight() const +{ + return mGuiFont->getHeight(); +} diff --git a/src/gui/gui.h b/src/gui/gui.h index 340eec09..2ce153db 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -77,6 +77,11 @@ class Gui : public gcn::Gui { return mGuiFont; } /** + * Return game font height. + */ + const int getFontHeight() const; + + /** * Return the Font used for "Info Particles", i.e. ones showing, what * you picked up, etc. */ diff --git a/src/gui/help.cpp b/src/gui/help.cpp index 78b3c93a..03dfd08d 100644 --- a/src/gui/help.cpp +++ b/src/gui/help.cpp @@ -39,16 +39,17 @@ HelpWindow::HelpWindow(): setWindowName("Help"); setResizable(true); + setDefaultSize(500, 400, ImageRect::CENTER); + mBrowserBox = new BrowserBox; mBrowserBox->setOpaque(false); mScrollArea = new ScrollArea(mBrowserBox); Button *okButton = new Button(_("Close"), "close", this); - mScrollArea->setDimension(gcn::Rectangle( - 5, 5, 445, 335 - okButton->getHeight())); - okButton->setPosition( - 450 - okButton->getWidth(), - 345 - okButton->getHeight()); + mScrollArea->setDimension(gcn::Rectangle(5, 5, 445, + 335 - okButton->getHeight())); + okButton->setPosition(450 - okButton->getWidth(), + 345 - okButton->getHeight()); mBrowserBox->setLinkHandler(this); @@ -58,7 +59,7 @@ HelpWindow::HelpWindow(): Layout &layout = getLayout(); layout.setRowHeight(0, Layout::AUTO_SET); - center(); + loadWindowState(); } void HelpWindow::action(const gcn::ActionEvent &event) diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index 80017d28..50fae483 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -24,12 +24,11 @@ #include <guichan/font.hpp> #include <guichan/mouseinput.hpp> -#include <guichan/widgets/label.hpp> - #include "button.h" #include "inventorywindow.h" #include "item_amount.h" #include "itemcontainer.h" +#include "label.h" #include "progressbar.h" #include "scrollarea.h" #include "viewport.h" @@ -57,7 +56,7 @@ InventoryWindow::InventoryWindow(int invSize): setCloseButton(true); // If you adjust these defaults, don't forget to adjust the trade window's. - setDefaultSize(115, 25, 375, 300); + setDefaultSize(375, 300, ImageRect::CENTER); std::string longestUseString = getFont()->getWidth(_("Equip")) > getFont()->getWidth(_("Use")) ? @@ -82,8 +81,8 @@ InventoryWindow::InventoryWindow(int invSize): mMaxWeight = -1; mUsedSlots = toString(player_node->getInventory()->getNumberOfSlotsUsed()); - mSlotsLabel = new gcn::Label(_("Slots: ")); - mWeightLabel = new gcn::Label(_("Weight: ")); + mSlotsLabel = new Label(_("Slots: ")); + mWeightLabel = new Label(_("Weight: ")); mSlotsBar = new ProgressBar(1.0f, 100, 20, 225, 200, 25); mWeightBar = new ProgressBar(1.0f, 100, 20, 0, 0, 255); diff --git a/src/gui/item_amount.cpp b/src/gui/item_amount.cpp index 9398dc47..a8242aae 100644 --- a/src/gui/item_amount.cpp +++ b/src/gui/item_amount.cpp @@ -20,8 +20,8 @@ */ #include "button.h" -#include "inttextfield.h" #include "item_amount.h" +#include "label.h" #include "slider.h" #include "storagewindow.h" #include "trade.h" @@ -32,19 +32,20 @@ #include "../localplayer.h" #include "../utils/gettext.h" +#include "../utils/strprintf.h" ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item): Window("", true, parent), mItem(item), - mMax(mItem->getQuantity()), + mMax(item->getQuantity()), mUsage(usage) { + setCloseButton(true); + // Integer field - mItemAmountTextField = new IntTextField(1); - mItemAmountTextField->setRange(1, mMax); - mItemAmountTextField->setWidth(30); - mItemAmountTextField->setActionEventId("Dummy"); - mItemAmountTextField->addActionListener(this); + + mItemAmountLabel = new Label(strprintf("%d / %d", 1, mMax)); + mItemAmountLabel->setAlignment(gcn::Graphics::CENTER); // Slider mItemAmountSlide = new Slider(1.0, mMax); @@ -54,22 +55,27 @@ ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item): // Buttons Button *minusButton = new Button("-", "Minus", this); - minusButton->setSize(20, 20); Button *plusButton = new Button("+", "Plus", this); - plusButton->setSize(20, 20); Button *okButton = new Button(_("Ok"), "Ok", this); Button *cancelButton = new Button(_("Cancel"), "Cancel", this); Button *addAllButton = new Button(_("All"), "All", this); + minusButton->adjustSize(); + minusButton->setWidth(plusButton->getWidth()); + // Set positions + ContainerPlacer place; + place = getPlacer(0, 0); + place(0, 0, minusButton); - place(1, 0, mItemAmountTextField).setPadding(2); - place(2, 0, plusButton); - place(4, 0, addAllButton, 2); - place(0, 1, mItemAmountSlide, 6); - place(4, 2, okButton); - place(5, 2, cancelButton); - reflowLayout(250, 0); + place(1, 0, mItemAmountSlide, 3); + place(4, 0, plusButton); + place(5, 0, mItemAmountLabel, 2); + place(7, 0, addAllButton); + place = getPlacer(0, 1); + place(4, 0, cancelButton); + place(5, 0, okButton); + reflowLayout(225, 0); resetAmount(); @@ -97,22 +103,22 @@ ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item): void ItemAmountWindow::resetAmount() { - mItemAmountTextField->setValue(1); + mItemAmountLabel->setCaption(strprintf("%d / %d", 1, mMax)); } void ItemAmountWindow::action(const gcn::ActionEvent &event) { - int amount = mItemAmountTextField->getValue(); + int amount = mItemAmountSlide->getValue(); if (event.getId() == "Cancel") { - scheduleDelete(); + close(); } - else if (event.getId() == "Plus") + else if (event.getId() == "Plus" && amount < mMax) { amount++; } - else if (event.getId() == "Minus") + else if (event.getId() == "Minus" && amount > 1) { amount--; } @@ -122,9 +128,8 @@ void ItemAmountWindow::action(const gcn::ActionEvent &event) } else if (event.getId() == "Ok" || event.getId() == "All") { - if (event.getId() == "All") { + if (event.getId() == "All") amount = mMax; - } switch (mUsage) { @@ -149,9 +154,11 @@ void ItemAmountWindow::action(const gcn::ActionEvent &event) return; } - if (amount < 0) amount = 0; - else if (amount > mMax) amount = mMax; - - mItemAmountTextField->setValue(amount); + mItemAmountLabel->setCaption(strprintf("%d / %d", amount, mMax)); mItemAmountSlide->setValue(amount); } + +void ItemAmountWindow::close() +{ + scheduleDelete(); +} diff --git a/src/gui/item_amount.h b/src/gui/item_amount.h index f0534ec8..d8253e3c 100644 --- a/src/gui/item_amount.h +++ b/src/gui/item_amount.h @@ -57,8 +57,13 @@ class ItemAmountWindow : public Window, public gcn::ActionListener */ void resetAmount(); + /** + * Schedules the Item Amount window for deletion. + */ + void close(); + private: - IntTextField *mItemAmountTextField; /**< Item amount caption. */ + gcn::Label *mItemAmountLabel; /**< Item amount caption. */ Item *mItem; int mMax, mUsage; diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp index 8285a491..8a780eb4 100644 --- a/src/gui/itemcontainer.cpp +++ b/src/gui/itemcontainer.cpp @@ -24,6 +24,7 @@ #include "itemcontainer.h" #include "itempopup.h" +#include "palette.h" #include "viewport.h" #include "../graphics.h" @@ -50,13 +51,14 @@ ItemContainer::ItemContainer(Inventory *inventory, int offset): mOffset(offset) { mItemPopup = new ItemPopup; + mItemPopup->setOpaque(false); ResourceManager *resman = ResourceManager::getInstance(); mSelImg = resman->getImage("graphics/gui/selection.png"); if (!mSelImg) logger->error("Unable to load selection.png"); - mMaxItems = mInventory->getLastUsedSlot() - 1; // Count from 0, usage from 2 + mMaxItems = mInventory->getLastUsedSlot() - (mOffset - 1); // Count from 0, usage from 2 addMouseListener(this); addWidgetListener(this); @@ -75,7 +77,7 @@ void ItemContainer::logic() gcn::Widget::logic(); - int i = mInventory->getLastUsedSlot() - 1; // Count from 0, usage from 2 + int i = mInventory->getLastUsedSlot() - (mOffset - 1); // Count from 0, usage from 2 if (i != mMaxItems) { @@ -122,7 +124,7 @@ void ItemContainer::draw(gcn::Graphics *graphics) // Draw item caption graphics->setFont(getFont()); - graphics->setColor(gcn::Color(0, 0, 0)); + graphics->setColor(guiPalette->getColor(Palette::TEXT)); graphics->drawText( (item->isEquipped() ? "Eq." : toString(item->getQuantity())), itemX + gridWidth / 2, itemY + gridHeight - 11, @@ -254,8 +256,9 @@ void ItemContainer::mouseMoved(gcn::MouseEvent &event) if (item) { - mItemPopup->setItem(item->getInfo()); - mItemPopup->setOpaque(false); + if (item->getInfo().getName() != mItemPopup->getItemName()) + mItemPopup->setItem(item->getInfo()); + mItemPopup->updateColors(); mItemPopup->view(viewport->getMouseX(), viewport->getMouseY()); } else diff --git a/src/gui/itemlinkhandler.cpp b/src/gui/itemlinkhandler.cpp index bd8985dc..29fa310d 100644 --- a/src/gui/itemlinkhandler.cpp +++ b/src/gui/itemlinkhandler.cpp @@ -32,6 +32,7 @@ ItemLinkHandler::ItemLinkHandler() { mItemPopup = new ItemPopup; + mItemPopup->setOpaque(false); } ItemLinkHandler::~ItemLinkHandler() @@ -49,11 +50,17 @@ void ItemLinkHandler::handleLink(const std::string &link) { const ItemInfo &iteminfo = ItemDB::get(id); - mItemPopup->setItem(iteminfo); + if (iteminfo.getName() != mItemPopup->getItemName()) + mItemPopup->setItem(iteminfo); if (mItemPopup->isVisible()) + { mItemPopup->setVisible(false); + } else + { + mItemPopup->updateColors(); mItemPopup->view(viewport->getMouseX(), viewport->getMouseY()); + } } } diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp index efbee6b0..61cb18fb 100644 --- a/src/gui/itempopup.cpp +++ b/src/gui/itempopup.cpp @@ -26,11 +26,11 @@ #include "gui.h" #include "itempopup.h" +#include "palette.h" #include "scrollarea.h" #include "textbox.h" -#include "windowcontainer.h" -#include "widgets/layout.h" +#include "../graphics.h" #include "../units.h" @@ -40,14 +40,12 @@ #include "../utils/stringutils.h" ItemPopup::ItemPopup(): - Window() + Popup() { - setResizable(false); - setShowTitle(false); - setTitleBarHeight(0); + mItemType = ""; // Item Name - mItemName = new gcn::Label("Label"); + mItemName = new gcn::Label(""); mItemName->setFont(boldFont); mItemName->setPosition(2, 2); @@ -88,8 +86,6 @@ ItemPopup::ItemPopup(): add(mItemDescScroll); add(mItemEffectScroll); add(mItemWeightScroll); - - center(); } ItemPopup::~ItemPopup() @@ -109,12 +105,12 @@ void ItemPopup::setItem(const ItemInfo &item) return; mItemName->setCaption(item.getName()); - mItemName->setForegroundColor(getColor(item.getType())); mItemName->setWidth(boldFont->getWidth(item.getName())); mItemDesc->setTextWrapped(item.getDescription(), 196); mItemEffect->setTextWrapped(item.getEffect(), 196); mItemWeight->setTextWrapped(_("Weight: ") + Units::formatWeight(item.getWeight()), 196); + mItemType = item.getType(); int minWidth = mItemName->getWidth(); @@ -167,40 +163,51 @@ void ItemPopup::setItem(const ItemInfo &item) (2 * getFont()->getHeight())); } +void ItemPopup::updateColors() +{ + mItemName->setForegroundColor(getColor(mItemType)); + graphics->setColor(guiPalette->getColor(Palette::TEXT)); +} + gcn::Color ItemPopup::getColor(const std::string& type) { gcn::Color color; if (type.compare("generic") == 0) - color = 0x21a5b1; + color = guiPalette->getColor(Palette::GENERIC); else if (type.compare("equip-head") == 0) - color = 0x527fa4; + color = guiPalette->getColor(Palette::HEAD); else if (type.compare("usable") == 0) - color = 0x268d24; + color = guiPalette->getColor(Palette::USABLE); else if (type.compare("equip-torso") == 0) - color = 0xd12aa4; + color = guiPalette->getColor(Palette::TORSO); else if (type.compare("equip-1hand") == 0) - color = 0xf42a2a; + color = guiPalette->getColor(Palette::ONEHAND); else if (type.compare("equip-legs") == 0) - color = 0x699900; + color = guiPalette->getColor(Palette::LEGS); else if (type.compare("equip-feet") == 0) - color = 0xaa1d48; + color = guiPalette->getColor(Palette::FEET); else if (type.compare("equip-2hand") == 0) - color = 0xf46d0e; + color = guiPalette->getColor(Palette::TWOHAND); else if (type.compare("equip-shield") == 0) - color = 0x9c2424; + color = guiPalette->getColor(Palette::SHIELD); else if (type.compare("equip-ring") == 0) - color = 0x0000ff; + color = guiPalette->getColor(Palette::RING); else if (type.compare("equip-arms") == 0) - color = 0x9c24e8; + color = guiPalette->getColor(Palette::ARMS); else if (type.compare("equip-ammo") == 0) - color = 0x8b6311; + color = guiPalette->getColor(Palette::AMMO); else - color = 0x000000; + color = guiPalette->getColor(Palette::UNKNOWN_ITEM); return color; } +std::string ItemPopup::getItemName() +{ + return mItemName->getCaption(); +} + unsigned int ItemPopup::getNumRows() { return mItemDesc->getNumberOfRows() + mItemEffect->getNumberOfRows() + @@ -209,8 +216,8 @@ unsigned int ItemPopup::getNumRows() void ItemPopup::view(int x, int y) { - if (windowContainer->getWidth() < (x + getWidth() + 5)) - x = windowContainer->getWidth() - getWidth(); + if (graphics->getWidth() < (x + getWidth() + 5)) + x = graphics->getWidth() - getWidth(); if ((y - getHeight() - 10) < 0) y = 0; else diff --git a/src/gui/itempopup.h b/src/gui/itempopup.h index c820e3a0..03e79886 100644 --- a/src/gui/itempopup.h +++ b/src/gui/itempopup.h @@ -23,20 +23,48 @@ #ifndef ITEMPOPUP_H #define ITEMPOPUP_H -#include "window.h" +#include "popup.h" class ItemInfo; class ScrollArea; class TextBox; -class ItemPopup : public Window +class ItemPopup : public Popup { public: + /** + * Constructor. Initializes the item popup. + */ ItemPopup(); + + /** + * Destructor. Cleans up the item popup on deletion. + */ ~ItemPopup(); + /** + * Sets the info to be displayed given a particular item. + */ void setItem(const ItemInfo &item); + + /** + * Gets the number of rows that the item popup currently has. + */ unsigned int getNumRows(); + + /** + * Gets the name of the currently stored item in this popup. + */ + std::string getItemName(); + + /** + * Updates the colors used within the item popup. + */ + void updateColors(); + + /** + * Sets the location to display the item popup. + */ void view(int x, int y); private: @@ -44,6 +72,7 @@ class ItemPopup : public Window TextBox *mItemDesc; TextBox *mItemEffect; TextBox *mItemWeight; + std::string mItemType; ScrollArea *mItemDescScroll; ScrollArea *mItemEffectScroll; ScrollArea *mItemWeightScroll; diff --git a/src/gui/itemshortcutcontainer.cpp b/src/gui/itemshortcutcontainer.cpp index 67525140..9f77fd65 100644 --- a/src/gui/itemshortcutcontainer.cpp +++ b/src/gui/itemshortcutcontainer.cpp @@ -22,6 +22,7 @@ #include "inventorywindow.h" #include "itemshortcutcontainer.h" #include "itempopup.h" +#include "palette.h" #include "viewport.h" #include "../configuration.h" @@ -46,6 +47,7 @@ ItemShortcutContainer::ItemShortcutContainer(): addWidgetListener(this); mItemPopup = new ItemPopup; + mItemPopup->setOpaque(false); ResourceManager *resman = ResourceManager::getInstance(); @@ -64,22 +66,6 @@ ItemShortcutContainer::~ItemShortcutContainer() delete mItemPopup; } -void ItemShortcutContainer::logic() -{ - if (!isVisible()) - return; - - gcn::Widget::logic(); - - int i = itemShortcut->getItemCount(); - - if (i != mMaxItems) - { - mMaxItems = i; - setWidth(getWidth()); - } -} - void ItemShortcutContainer::draw(gcn::Graphics *graphics) { if (!isVisible()) @@ -93,7 +79,6 @@ void ItemShortcutContainer::draw(gcn::Graphics *graphics) Graphics *g = static_cast<Graphics*>(graphics); - graphics->setColor(gcn::Color(0, 0, 0)); graphics->setFont(getFont()); for (int i = 0; i < mMaxItems; i++) @@ -106,7 +91,7 @@ void ItemShortcutContainer::draw(gcn::Graphics *graphics) // Draw item keyboard shortcut. const char *key = SDL_GetKeyName( (SDLKey) keyboard.getKeyValue(keyboard.KEY_SHORTCUT_1 + i)); - graphics->setColor(0x000000); + graphics->setColor(guiPalette->getColor(Palette::TEXT)); g->drawText(key, itemX + 2, itemY + 2, gcn::Graphics::LEFT); if (itemShortcut->getItem(i) < 0) @@ -249,8 +234,9 @@ void ItemShortcutContainer::mouseMoved(gcn::MouseEvent &event) if (item && inventoryWindow->isVisible()) { - mItemPopup->setItem(item->getInfo()); - mItemPopup->setOpaque(false); + if (item->getInfo().getName() != mItemPopup->getItemName()) + mItemPopup->setItem(item->getInfo()); + mItemPopup->updateColors(); mItemPopup->view(viewport->getMouseX(), viewport->getMouseY()); } else diff --git a/src/gui/itemshortcutcontainer.h b/src/gui/itemshortcutcontainer.h index 22d94ec2..9d188bf0 100644 --- a/src/gui/itemshortcutcontainer.h +++ b/src/gui/itemshortcutcontainer.h @@ -49,11 +49,6 @@ class ItemShortcutContainer : public ShortcutContainer virtual ~ItemShortcutContainer(); /** - * Handles the logic of the ItemContainer - */ - void logic(); - - /** * Draws the items. */ void draw(gcn::Graphics *graphics); diff --git a/src/gui/label.cpp b/src/gui/label.cpp new file mode 100644 index 00000000..e8d72ace --- /dev/null +++ b/src/gui/label.cpp @@ -0,0 +1,40 @@ +/* + * Aethyra + * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson + * Copyright (c) 2009 Aethyra Development Team + * + * This file is part of Aethyra based on original code + * from GUIChan. + * + * 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 "label.h" +#include "palette.h" + +Label::Label() : + gcn::Label() +{ +} + +Label::Label(const std::string& caption) : + gcn::Label(caption) +{ +} + +void Label::draw(gcn::Graphics* graphics) +{ + setForegroundColor(guiPalette->getColor(Palette::TEXT)); + gcn::Label::draw(static_cast<gcn::Graphics*>(graphics)); +} diff --git a/src/gui/label.h b/src/gui/label.h new file mode 100644 index 00000000..961286e0 --- /dev/null +++ b/src/gui/label.h @@ -0,0 +1,55 @@ +/* + * Aethyra + * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson + * Copyright (c) 2009 Aethyra Development Team + * + * This file is part of Aethyra based on original code + * from GUIChan. + * + * 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 LABEL_H +#define LABEL_H + +#include <guichan/widgets/label.hpp> + +/** + * Label widget. Same as the Guichan label but modified to use the palette + * system. + * + * \ingroup GUI + */ +class Label : public gcn::Label +{ + public: + /** + * Constructor. + */ + Label(); + + /** + * Constructor. This version of the constructor sets the label with an + * inintialization string. + */ + Label(const std::string& caption); + + /** + * Draws the label. + */ + void draw(gcn::Graphics* graphics); +}; + +#endif diff --git a/src/gui/login.cpp b/src/gui/login.cpp index 414de40e..5eaf6626 100644 --- a/src/gui/login.cpp +++ b/src/gui/login.cpp @@ -19,10 +19,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/widgets/label.hpp> - #include "button.h" #include "checkbox.h" +#include "label.h" #include "listbox.h" #include "login.h" #include "ok_dialog.h" @@ -48,11 +47,11 @@ static const int FIELD_WIDTH = LOGIN_DIALOG_WIDTH - 70; LoginDialog::LoginDialog(LoginData *loginData): Window(_("Login")), mLoginData(loginData) { - gcn::Label *userLabel = new gcn::Label(_("Name:")); - gcn::Label *passLabel = new gcn::Label(_("Password:")); - gcn::Label *serverLabel = new gcn::Label(_("Server:")); - gcn::Label *portLabel = new gcn::Label(_("Port:")); - gcn::Label *dropdownLabel = new gcn::Label(_("Recent:")); + gcn::Label *userLabel = new Label(_("Name:")); + gcn::Label *passLabel = new Label(_("Password:")); + gcn::Label *serverLabel = new Label(_("Server:")); + gcn::Label *portLabel = new Label(_("Port:")); + gcn::Label *dropdownLabel = new Label(_("Recent:")); std::vector<std::string> dfltServer; dfltServer.push_back("server.themanaworld.org"); std::vector<std::string> dfltPort; @@ -113,11 +112,10 @@ LoginDialog::LoginDialog(LoginData *loginData): center(); setVisible(true); - if (mUserField->getText().empty()) { + if (mUserField->getText().empty()) mUserField->requestFocus(); - } else { + else mPassField->requestFocus(); - } mOkButton->setEnabled(canSubmit()); } @@ -152,14 +150,12 @@ void LoginDialog::action(const gcn::ActionEvent &event) { // Transfer these fields on to the register dialog mLoginData->hostname = mServerField->getText(); + if (isUShort(mPortField->getText())) - { mLoginData->port = getUShort(mPortField->getText()); - } else - { mLoginData->port = 6901; - } + mLoginData->username = mUserField->getText(); mLoginData->password = mPassField->getText(); @@ -192,14 +188,12 @@ bool LoginDialog::isUShort(const std::string &str) strPtr != strEnd; ++strPtr) { if (*strPtr < '0' || *strPtr > '9') - { return false; - } + l = l * 10 + (*strPtr - '0'); // *strPtr - '0' will never be negative + if (l > 65535) - { return false; - } } return true; } @@ -275,9 +269,7 @@ void LoginDialog::DropDownList::save(const std::string &server, ++sPtr, ++pPtr) { if (*sPtr != server || *pPtr != port) - { saveEntry(*sPtr, *pPtr, position); - } } } @@ -289,26 +281,23 @@ int LoginDialog::DropDownList::getNumberOfElements() std::string LoginDialog::DropDownList::getElementAt(int i) { if (i < 0 || i >= getNumberOfElements()) - { - return ""; - } + return ""; + return getServerAt(i) + ":" + getPortAt(i); } std::string LoginDialog::DropDownList::getServerAt(int i) { if (i < 0 || i >= getNumberOfElements()) - { return ""; - } + return mServers.at(i); } std::string LoginDialog::DropDownList::getPortAt(int i) { if (i < 0 || i >= getNumberOfElements()) - { return ""; - } + return mPorts.at(i); } diff --git a/src/gui/menuwindow.cpp b/src/gui/menuwindow.cpp index 97553586..62f3766f 100644 --- a/src/gui/menuwindow.cpp +++ b/src/gui/menuwindow.cpp @@ -25,7 +25,9 @@ #include "button.h" #include "menuwindow.h" -#include "windowcontainer.h" +#include "window.h" + +#include "../graphics.h" #include "../utils/gettext.h" @@ -49,13 +51,8 @@ namespace { } MenuWindow::MenuWindow(): - Window("") + Popup("Menu") { - setResizable(false); - setWindowName("Menu"); - setMovable(false); - setTitleBarHeight(0); - // Buttons static const char *buttonNames[] = { @@ -80,7 +77,7 @@ MenuWindow::MenuWindow(): h = btn->getHeight(); } - setPosition(windowContainer->getWidth() - x - 3, 3); + setPosition(graphics->getWidth() - x - 3, 3); setContentSize(x - 3, h); } diff --git a/src/gui/menuwindow.h b/src/gui/menuwindow.h index 9bb54e29..c3d5673e 100644 --- a/src/gui/menuwindow.h +++ b/src/gui/menuwindow.h @@ -22,14 +22,14 @@ #ifndef MENU_H #define MENU_H -#include "window.h" +#include "popup.h" /** * The Button Menu. * * \ingroup Interface */ -class MenuWindow : public Window +class MenuWindow : public Popup { public: /** diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp index 57fd7457..d8c5d742 100644 --- a/src/gui/minimap.cpp +++ b/src/gui/minimap.cpp @@ -79,19 +79,6 @@ void Minimap::setMapImage(Image *img) mMapImage->getWidth() + offsetX : titleWidth); setMaxHeight(mMapImage->getHeight() + offsetY); - // Make sure the window is within the minimum and maximum boundaries - // TODO: Shouldn't this be happening automatically within the Window - // class? - if (getMinWidth() > getWidth()) - setWidth(getMinWidth()); - else if (getMaxWidth() < getWidth()) - setWidth(getMaxWidth()); - if (getMinHeight() > getHeight()) - setHeight(getMinHeight()); - else if (getMaxHeight() < getHeight()) - setHeight(getMaxHeight()); - - setContentSize(getWidth() - offsetX, getHeight() - offsetY); setDefaultSize(getX(), getY(), getWidth(), getHeight()); resetToDefaultSize(); diff --git a/src/gui/ministatus.cpp b/src/gui/ministatus.cpp index 9a3d27cc..9f789a9d 100644 --- a/src/gui/ministatus.cpp +++ b/src/gui/ministatus.cpp @@ -32,13 +32,8 @@ #include "../utils/stringutils.h" MiniStatusWindow::MiniStatusWindow(): - Window("") + Popup("MiniStatus") { - setWindowName("MiniStatus"); - setResizable(false); - setMovable(false); - setTitleBarHeight(0); - mHpBar = new ProgressBar(1.0f, 100, 20, 0, 171, 34); mMpBar = new ProgressBar(1.0f, 100, 20, 26, 102, 230); mXpBar = new ProgressBar(1.0f, 100, 20, 143, 192, 211); @@ -53,8 +48,6 @@ MiniStatusWindow::MiniStatusWindow(): setContentSize(mXpBar->getX() + mXpBar->getWidth(), mXpBar->getY() + mXpBar->getHeight()); - setDefaultSize(0, 0, getWidth(), getHeight()); - loadWindowState(); } void MiniStatusWindow::setIcon(int index, AnimatedSprite *sprite) diff --git a/src/gui/ministatus.h b/src/gui/ministatus.h index f262a2a0..6e47f490 100644 --- a/src/gui/ministatus.h +++ b/src/gui/ministatus.h @@ -22,7 +22,7 @@ #ifndef MINISTATUS_H #define MINISTATUS_H -#include "window.h" +#include "popup.h" #include <vector> @@ -34,7 +34,7 @@ class ProgressBar; * * \ingroup Interface */ -class MiniStatusWindow : public Window +class MiniStatusWindow : public Popup { public: /** diff --git a/src/gui/npc_text.cpp b/src/gui/npc_text.cpp index 5bc654b8..5bde7f36 100644 --- a/src/gui/npc_text.cpp +++ b/src/gui/npc_text.cpp @@ -43,7 +43,7 @@ NpcTextDialog::NpcTextDialog(Network *network): setMinWidth(200); setMinHeight(150); - setDefaultSize(0, 0, 260, 200); + setDefaultSize(260, 200, ImageRect::CENTER); mTextBox = new TextBox; mTextBox->setEditable(false); @@ -140,3 +140,9 @@ void NpcTextDialog::widgetResized(const gcn::Event &event) setText(mText); } + +void NpcTextDialog::requestFocus() +{ + loadWindowState(); + setVisible(true); +} diff --git a/src/gui/npc_text.h b/src/gui/npc_text.h index f030115b..011c7bcf 100644 --- a/src/gui/npc_text.h +++ b/src/gui/npc_text.h @@ -77,11 +77,24 @@ class NpcTextDialog : public Window, public gcn::ActionListener void showCloseButton(); + /** + * Notifies the server that the client has performed a next action. + */ void nextDialog(int npcID = current_npc); + /** + * Notifies the server that the client has performed a close action. + */ void closeDialog(int npcID = current_npc); /** + * Initializes window width to the last known setting. Since the dialog + * doesn't need any extra focus outside of what it's given in the Game + * class, this is all it does for now. + */ + void requestFocus(); + + /** * Called when resizing the window. * * @param event The calling event diff --git a/src/gui/npcintegerdialog.cpp b/src/gui/npcintegerdialog.cpp index 643a7ef8..896f3380 100644 --- a/src/gui/npcintegerdialog.cpp +++ b/src/gui/npcintegerdialog.cpp @@ -40,14 +40,16 @@ NpcIntegerDialog::NpcIntegerDialog(Network *network): setWindowName("NPCInteger"); mValueField = new IntTextField; + setDefaultSize(175, 75, ImageRect::CENTER); + mDecButton = new Button("-", "decvalue", this); mIncButton = new Button("+", "incvalue", this); gcn::Button *okButton = new Button(_("OK"), "ok", this); gcn::Button *cancelButton = new Button(_("Cancel"), "cancel", this); gcn::Button *resetButton = new Button(_("Reset"), "reset", this); - mDecButton->setSize(20, 20); - mIncButton->setSize(20, 20); + mDecButton->adjustSize(); + mDecButton->setWidth(mIncButton->getWidth()); ContainerPlacer place; place = getPlacer(0, 0); diff --git a/src/gui/npclistdialog.cpp b/src/gui/npclistdialog.cpp index d280a982..ef8b0627 100644 --- a/src/gui/npclistdialog.cpp +++ b/src/gui/npclistdialog.cpp @@ -38,7 +38,7 @@ #include "../utils/strprintf.h" NpcListDialog::NpcListDialog(Network *network): - Window(_("NPC")), mNetwork(network) + Window("NPC"), mNetwork(network) { setWindowName("NPCList"); setResizable(true); @@ -46,7 +46,7 @@ NpcListDialog::NpcListDialog(Network *network): setMinWidth(200); setMinHeight(150); - setDefaultSize(0, 0, 260, 200); + setDefaultSize(260, 200, ImageRect::CENTER); mItemList = new ListBox(this); mItemList->setWrappingEnabled(true); @@ -60,8 +60,8 @@ NpcListDialog::NpcListDialog(Network *network): scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); place(0, 0, scrollArea, 5).setPadding(3); - place(3, 1, okButton); - place(4, 1, cancelButton); + place(3, 1, cancelButton); + place(4, 1, okButton); Layout &layout = getLayout(); layout.setRowHeight(0, Layout::AUTO_SET); @@ -121,6 +121,7 @@ void NpcListDialog::action(const gcn::ActionEvent &event) if (choice) { setVisible(false); + saveWindowState(); reset(); MessageOut outMsg(mNetwork); @@ -144,4 +145,6 @@ void NpcListDialog::requestFocus() { mItemList->requestFocus(); mItemList->setSelected(0); + loadWindowState(); + setVisible(true); } diff --git a/src/gui/npclistdialog.h b/src/gui/npclistdialog.h index b5a62515..f5f2147b 100644 --- a/src/gui/npclistdialog.h +++ b/src/gui/npclistdialog.h @@ -77,7 +77,8 @@ class NpcListDialog : public Window, public gcn::ActionListener, void setVisible(bool visible); /** - * Requests the listbox to take focus for input. + * Requests the listbox to take focus for input and sets window width + * to the last known setting. */ void requestFocus(); diff --git a/src/gui/npcstringdialog.cpp b/src/gui/npcstringdialog.cpp index 7ae2d5ed..c2379e7a 100644 --- a/src/gui/npcstringdialog.cpp +++ b/src/gui/npcstringdialog.cpp @@ -40,6 +40,8 @@ NpcStringDialog::NpcStringDialog(Network *network): setWindowName("NPCString"); mValueField = new TextField(""); + setDefaultSize(175, 75, ImageRect::CENTER); + gcn::Button *okButton = new Button(_("OK"), "ok", this); gcn::Button *cancelButton = new Button(_("Cancel"), "cancel", this); diff --git a/src/gui/palette.cpp b/src/gui/palette.cpp index fec04145..b1e165aa 100644 --- a/src/gui/palette.cpp +++ b/src/gui/palette.cpp @@ -1,6 +1,7 @@ /* * Configurable text colors * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> + * Copyright (C) 2009 The Mana World Development Team * * This file is part of The Mana World. * @@ -32,7 +33,7 @@ const gcn::Color Palette::BLACK = gcn::Color(0, 0, 0); -const gcn::Color Palette::RAINBOW_COLORS[8] = { +const gcn::Color Palette::RAINBOW_COLORS[7] = { gcn::Color(255, 0, 0), gcn::Color(255, 153, 0), gcn::Color(255, 255, 0), @@ -54,9 +55,8 @@ std::string Palette::getConfigName(const std::string &typeName) if (i == 0 || typeName[i] == '_') { if (i > 0) - { i++; - } + res[pos] = typeName[i]; } else @@ -72,9 +72,9 @@ std::string Palette::getConfigName(const std::string &typeName) DEFENUMNAMES(ColorType, COLOR_TYPE) -const int Palette::GRADIENT_DELAY = 20; +const int Palette::GRADIENT_DELAY = 40; -Palette::Palette() : +Palette::Palette() : mRainbowTime(tick_time), mColVector(ColVector(TYPE_COUNT)) { @@ -82,10 +82,12 @@ Palette::Palette() : addColor(TEXT, 0x000000, STATIC, _("Text")); addColor(SHADOW, 0x000000, STATIC, indent + _("Text Shadow")); addColor(OUTLINE, 0x000000, STATIC, indent + _("Text Outline")); + addColor(PROGRESS_BAR, 0xffffff, STATIC, indent + _("Progress Bar Labels")); addColor(BACKGROUND, 0xffffff, STATIC, _("Background")); addColor(HIGHLIGHT, 0xebc873, STATIC, _("Highlight"), 'H'); + addColor(TAB_HIGHLIGHT, 0xff0000, PULSE, indent + _("Tab Highlight")); addColor(SHOP_WARNING, 0x910000, STATIC, indent + _("Item too expensive")); @@ -106,6 +108,20 @@ Palette::Palette() : addColor(NPC, 0xc8c8ff, STATIC, indent + _("NPCs")); addColor(MONSTER, 0xff4040, STATIC, indent + _("Monsters")); + addColor(UNKNOWN_ITEM, 0x000000, STATIC, _("Unknown Item Type")); + addColor(GENERIC, 0x21a5b1, STATIC, indent + _("Generic")); + addColor(HEAD, 0x527fa4, STATIC, indent + _("Hat")); + addColor(USABLE, 0x268d24, STATIC, indent + _("Usable")); + addColor(TORSO, 0xd12aa4, STATIC, indent + _("Shirt")); + addColor(ONEHAND, 0xf42a2a, STATIC, indent + _("1 Handed Weapons")); + addColor(LEGS, 0x699900, STATIC, indent + _("Pants")); + addColor(FEET, 0xaa1d48, STATIC, indent + _("Shoes")); + addColor(TWOHAND, 0xf46d0e, STATIC, indent + _("2 Handed Weapons")); + addColor(SHIELD, 0x9c2424, STATIC, indent + _("Shield")); + addColor(RING, 0x0000ff, STATIC, indent + _("Ring")); + addColor(ARMS, 0x9c24e8, STATIC, indent + _("Arms")); + addColor(AMMO, 0x8b6311, STATIC, indent + _("Ammo")); + addColor(PARTICLE, 0xffffff, STATIC, _("Particle Effects")); addColor(PICKUP_INFO, 0x28dc28, STATIC, indent + _("Pickup Notification")); addColor(EXP_INFO, 0xffff00, STATIC, indent + _("Exp Notification")); @@ -122,12 +138,11 @@ Palette::~Palette() { const std::string *configName; for (ColVector::iterator col = mColVector.begin(), - colEnd = mColVector.end(); - col != colEnd; ++col) + colEnd = mColVector.end(); col != colEnd; ++col) { configName = &ColorTypeNames[col->type]; config.setValue(*configName + "Gradient", col->committedGrad); - if (col->grad == STATIC) + if (col->grad == STATIC || col->grad == PULSE) { config.setValue(*configName, toString(col->getRGB())); } @@ -137,7 +152,7 @@ Palette::~Palette() const gcn::Color& Palette::getColor(char c, bool &valid) { for (ColVector::const_iterator col = mColVector.begin(), - colEnd = mColVector.end(); col != colEnd; ++col) + colEnd = mColVector.end(); col != colEnd; ++col) { if (col->ch == c) { @@ -209,6 +224,10 @@ void Palette::commit(bool commitNonStatic) { i->committedColor = i->color; } + else if (i->grad == PULSE) + { + i->committedColor = i->testColor; + } } } @@ -223,13 +242,19 @@ void Palette::rollback() setGradient(i->type, i->committedGrad); } setColor(i->type, i->committedColor.r, i->committedColor.g, - i->committedColor.b); + i->committedColor.b); + if (i->grad == PULSE) + { + i->testColor.r = i->committedColor.r; + i->testColor.g = i->committedColor.g; + i->testColor.b = i->committedColor.b; + } } } void Palette::addColor(Palette::ColorType type, int rgb, - Palette::GradientType grad, - const std::string &text, char c) + Palette::GradientType grad, + const std::string &text, char c) { const std::string *configName = &ColorTypeNames[type]; gcn::Color trueCol = (int)config.getValue(*configName, rgb); @@ -246,7 +271,7 @@ void Palette::advanceGradient () if (get_elapsed_time(mRainbowTime) > 5) { int pos, colIndex, colVal; - // For slower systems, advance can be greater than one (adcanve > 1 + // For slower systems, advance can be greater than one (advance > 1 // skips advance-1 steps). Should make gradient look the same // independent of the framerate. int advance = get_elapsed_time(mRainbowTime) / 5; @@ -256,25 +281,35 @@ void Palette::advanceGradient () { mGradVector[i]->gradientIndex = (mGradVector[i]->gradientIndex + advance) % - (GRADIENT_DELAY * - ((mGradVector[i]->grad == SPECTRUM) ? 6 : - RAINBOW_COLOR_COUNT)); + (GRADIENT_DELAY * ((mGradVector[i]->grad == SPECTRUM) ? + (mGradVector[i]->grad == PULSE) ? 255 : 6 : + RAINBOW_COLOR_COUNT)); pos = mGradVector[i]->gradientIndex % GRADIENT_DELAY; colIndex = mGradVector[i]->gradientIndex / GRADIENT_DELAY; + if (mGradVector[i]->grad == PULSE) + { + colVal = (int) (255.0 * (sin(M_PI * + (mGradVector[i]->gradientIndex) / 255) + 1) / 2); + + const gcn::Color* col = &mGradVector[i]->testColor; + + mGradVector[i]->color.r = ((colVal * col->r) / 255) % (col->r + 1); + mGradVector[i]->color.g = ((colVal * col->g) / 255) % (col->g + 1); + mGradVector[i]->color.b = ((colVal * col->b) / 255) % (col->b + 1); + } if (mGradVector[i]->grad == SPECTRUM) { if (colIndex % 2) { // falling curve - colVal = (int)(255.0 * - (cos(M_PI * pos / GRADIENT_DELAY) + 1) / 2); + colVal = (int)(255.0 * (cos(M_PI * pos / GRADIENT_DELAY) + + 1) / 2); } else { // ascending curve - colVal = (int)(255.0 * - (cos(M_PI * (GRADIENT_DELAY-pos) / GRADIENT_DELAY) + - 1) / 2); + colVal = (int)(255.0 * (cos(M_PI * (GRADIENT_DELAY-pos) / + GRADIENT_DELAY) + 1) / 2); } mGradVector[i]->color.r = @@ -287,7 +322,7 @@ void Palette::advanceGradient () (colIndex == 3 || colIndex == 4) ? 255 : (colIndex == 2 || colIndex == 5) ? colVal : 0; } - else + else if (mGradVector[i]->grad == RAINBOW) { const gcn::Color* startCol = &RAINBOW_COLORS[colIndex]; const gcn::Color* destCol = @@ -296,17 +331,14 @@ void Palette::advanceGradient () startColVal = (cos(M_PI * pos / GRADIENT_DELAY) + 1) / 2; destColVal = 1 - startColVal; - mGradVector[i]->color.r =(int)( - startColVal * startCol->r + - destColVal * destCol->r); + mGradVector[i]->color.r =(int)(startColVal * startCol->r + + destColVal * destCol->r); - mGradVector[i]->color.g =(int)( - startColVal * startCol->g + - destColVal * destCol->g); + mGradVector[i]->color.g =(int)(startColVal * startCol->g + + destColVal * destCol->g); - mGradVector[i]->color.b =(int)( - startColVal * startCol->b + - destColVal * destCol->b); + mGradVector[i]->color.b =(int)(startColVal * startCol->b + + destColVal * destCol->b); } } diff --git a/src/gui/palette.h b/src/gui/palette.h index e56bf9c5..1a466ed4 100644 --- a/src/gui/palette.h +++ b/src/gui/palette.h @@ -1,6 +1,7 @@ /* * Configurable text colors * Copyright (C) 2008 Douglas Boffey <dougaboffey@netscape.net> + * Copyright (C) 2009 The Mana World Development Team * * This file is part of The Mana World. * @@ -50,8 +51,10 @@ class Palette : public gcn::ListModel ENTRY(TEXT)\ ENTRY(SHADOW)\ ENTRY(OUTLINE)\ + ENTRY(PROGRESS_BAR)\ ENTRY(BACKGROUND)\ ENTRY(HIGHLIGHT)\ + ENTRY(TAB_HIGHLIGHT)\ ENTRY(SHOP_WARNING)\ ENTRY(CHAT)\ ENTRY(GM)\ @@ -68,6 +71,19 @@ class Palette : public gcn::ListModel ENTRY(GM_NAME)\ ENTRY(NPC)\ ENTRY(MONSTER)\ + ENTRY(UNKNOWN_ITEM)\ + ENTRY(GENERIC)\ + ENTRY(HEAD)\ + ENTRY(USABLE)\ + ENTRY(TORSO)\ + ENTRY(ONEHAND)\ + ENTRY(LEGS)\ + ENTRY(FEET)\ + ENTRY(TWOHAND)\ + ENTRY(SHIELD)\ + ENTRY(RING)\ + ENTRY(ARMS)\ + ENTRY(AMMO)\ ENTRY(PARTICLE)\ ENTRY(EXP_INFO)\ ENTRY(PICKUP_INFO)\ @@ -82,6 +98,7 @@ class Palette : public gcn::ListModel /** Colors can be static or can alter over time. */ enum GradientType { STATIC, + PULSE, SPECTRUM, RAINBOW }; @@ -136,6 +153,29 @@ class Palette : public gcn::ListModel } /** + * Gets the test color associated with the specified type. + * + * @param type the color type requested + * + * @return the requested test color + */ + inline const gcn::Color& getTestColor(ColorType type) + { + return mColVector[type].testColor; + } + + /** + * Sets the test color associated with the specified type. + * + * @param type the color type requested + * @param color the color that should be tested + */ + inline void setTestColor(ColorType type, gcn::Color color) + { + mColVector[type].testColor = color; + } + + /** * Gets the GradientType associated with the specified type. * * @param type the color type of the color @@ -252,6 +292,7 @@ class Palette : public gcn::ListModel { ColorType type; gcn::Color color; + gcn::Color testColor; gcn::Color committedColor; std::string text; char ch; @@ -270,7 +311,8 @@ class Palette : public gcn::ListModel ColorElem::gradientIndex = rand(); } - inline int getRGB() { + inline int getRGB() + { return (committedColor.r << 16) | (committedColor.g << 8) | committedColor.b; } diff --git a/src/gui/popup.cpp b/src/gui/popup.cpp new file mode 100644 index 00000000..17d299a5 --- /dev/null +++ b/src/gui/popup.cpp @@ -0,0 +1,209 @@ +/* + * Aethyra + * Copyright (C) 2009 Aethyra Development Team + * + * This file is part of Aethyra based on original code + * from 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 <algorithm> +#include <cassert> +#include <climits> + +#include <guichan/exception.hpp> + +#include "gui.h" +#include "skin.h" +#include "popup.h" +#include "window.h" +#include "windowcontainer.h" + +#include "../configlistener.h" +#include "../configuration.h" +#include "../log.h" + +#include "../resources/image.h" + +ConfigListener *Popup::popupConfigListener = 0; +int Popup::instances = 0; +bool Popup::mAlphaChanged = false; + +class PopupConfigListener : public ConfigListener +{ + void optionChanged(const std::string &) + { + Popup::mAlphaChanged = true; + } +}; + +Popup::Popup(const std::string& name, Window *parent, + const std::string& skin): + mParent(parent), + mPopupName(name), + mMinWidth(100), + mMinHeight(40), + mMaxWidth(INT_MAX), + mMaxHeight(INT_MAX) +{ + logger->log("Popup::Popup(\"%s\")", name.c_str()); + + if (!windowContainer) + throw GCN_EXCEPTION("Popup::Popup(): no windowContainer set"); + + if (instances == 0) + { + popupConfigListener = new PopupConfigListener(); + // Send GUI alpha changed for initialization + popupConfigListener->optionChanged("guialpha"); + config.addListener("guialpha", popupConfigListener); + } + + setPadding(3); + + instances++; + + // Loads the skin + mSkin = skinLoader->load(skin); + + setGuiAlpha(); + + // Add this window to the window container + windowContainer->add(this); + + // Popups are invisible by default + setVisible(false); +} + +Popup::~Popup() +{ + logger->log("Popup::~Popup(\"%s\")", mPopupName.c_str()); + + while (!mWidgets.empty()) + { + gcn::Widget *w = mWidgets.front(); + remove(w); + delete(w); + } + + instances--; + + mSkin->instances--; + + if (instances == 0) + { + config.removeListener("guialpha", popupConfigListener); + delete popupConfigListener; + popupConfigListener = NULL; + } +} + +void Popup::setWindowContainer(WindowContainer *wc) +{ + windowContainer = wc; +} + +void Popup::draw(gcn::Graphics *graphics) +{ + if (!isVisible()) + return; + + Graphics *g = static_cast<Graphics*>(graphics); + + g->drawImageRect(0, 0, getWidth(), getHeight(), mSkin->getBorder()); + + // Update Popup alpha values + if (mAlphaChanged) + { + for_each(mSkin->getBorder().grid, mSkin->getBorder().grid + 9, + std::bind2nd(std::mem_fun(&Image::setAlpha), + config.getValue("guialpha", 0.8))); + } + drawChildren(graphics); +} + +gcn::Rectangle Popup::getChildrenArea() +{ + return gcn::Rectangle(getPadding(), 0, getWidth() - getPadding() * 2, + getHeight() - getPadding() * 2); +} + +void Popup::setContentSize(int width, int height) +{ + width += 2 * getPadding(); + height += 2 * getPadding(); + + if (getMinWidth() > width) + width = getMinWidth(); + else if (getMaxWidth() < width) + width = getMaxWidth(); + if (getMinHeight() > height) + height = getMinHeight(); + else if (getMaxHeight() < height) + height = getMaxHeight(); + + setSize(width, height); +} + +void Popup::setLocationRelativeTo(gcn::Widget *widget) +{ + int wx, wy; + int x, y; + + widget->getAbsolutePosition(wx, wy); + getAbsolutePosition(x, y); + + setPosition(getX() + (wx + (widget->getWidth() - getWidth()) / 2 - x), + getY() + (wy + (widget->getHeight() - getHeight()) / 2 - y)); +} + +void Popup::setMinWidth(unsigned int width) +{ + mMinWidth = width > mSkin->getMinWidth() ? width : mSkin->getMinWidth(); +} + +void Popup::setMinHeight(unsigned int height) +{ + mMinHeight = height > mSkin->getMinHeight() ? height : mSkin->getMinHeight(); +} + +void Popup::setMaxWidth(unsigned int width) +{ + mMaxWidth = width; +} + +void Popup::setMaxHeight(unsigned int height) +{ + mMaxHeight = height; +} + +void Popup::scheduleDelete() +{ + windowContainer->scheduleDelete(this); +} + +void Popup::setGuiAlpha() +{ + //logger->log("Popup::setGuiAlpha: Alpha Value %f", config.getValue("guialpha", 0.8)); + for (int i = 0; i < 9; i++) + { + //logger->log("Popup::setGuiAlpha: Border Image (%i)", i); + mSkin->getBorder().grid[i]->setAlpha(config.getValue("guialpha", 0.8)); + } + + mAlphaChanged = false; +} + diff --git a/src/gui/popup.h b/src/gui/popup.h new file mode 100644 index 00000000..bfe8d7e9 --- /dev/null +++ b/src/gui/popup.h @@ -0,0 +1,194 @@ +/* + * Aethyra + * Copyright (C) 2009 Aethyra Development Team + * + * This file is part of Aethyra based on original code + * from 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 POPUP_H +#define POPUP_H + +#include <guichan/widgets/container.hpp> + +#include "../graphics.h" +#include "../guichanfwd.h" + +class ConfigListener; +class Skin; +class SkinLoader; +class Window; +class WindowContainer; + +/** + * A rather reduced down version of the Window class that is particularly suited + * for + * + * \ingroup GUI + */ +class Popup : public gcn::Container +{ + public: + friend class PopupConfigListener; + + /** + * Constructor. Initializes the title to the given text and hooks + * itself into the popup container. + * + * @param name A human readable name for the popup. Only useful for + * debugging purposes. + * @param parent The parent Window. This is the Window standing above + * this one in the Window hiearchy. When reordering, + * a Popup will never go below its parent Window. + * @param skin The location where the Popup's skin XML can be found. + */ + Popup(const std::string& name = "", Window *parent = NULL, + const std::string &skin = "graphics/gui/gui.xml"); + + /** + * Destructor. Deletes all the added widgets. + */ + ~Popup(); + + /** + * Sets the window container to be used by new popups. + */ + static void setWindowContainer(WindowContainer *windowContainer); + + /** + * Draws the popup. + */ + void draw(gcn::Graphics *graphics); + + /** + * Sets the size of this popup. + */ + void setContentSize(int width, int height); + + /** + * Sets the location relative to the given widget. + */ + void setLocationRelativeTo(gcn::Widget *widget); + + /** + * Sets the minimum width of the popup. + */ + void setMinWidth(unsigned int width); + + /** + * Sets the minimum height of the popup. + */ + void setMinHeight(unsigned int height); + + /** + * Sets the maximum width of the popup. + */ + void setMaxWidth(unsigned int width); + + /** + * Sets the minimum height of the popup. + */ + void setMaxHeight(unsigned int height); + + /** + * Gets the minimum width of the popup. + */ + int getMinWidth() { return mMinWidth; } + + /** + * Gets the minimum height of the popup. + */ + int getMinHeight() { return mMinHeight; } + + /** + * Gets the maximum width of the popup. + */ + int getMaxWidth() { return mMaxWidth; } + + /** + * Gets the minimum height of the popup. + */ + int getMaxHeight() { return mMaxHeight; } + + /** + * Gets the padding of the popup. The padding is the distance between + * the popup border and the content. + * + * @return The padding of the popup. + * @see setPadding + */ + unsigned int getPadding() const { return mPadding; } + + /** + * Sets the padding of the popup. The padding is the distance between the + * popup border and the content. + * + * @param padding The padding of the popup. + * @see getPadding + */ + void setPadding(unsigned int padding) { mPadding = padding; } + + /** + * Returns the parent Window. + * + * @return The parent Window or <code>NULL</code> if there is none. + */ + Window* getParentWindow() { return mParent; } + + /** + * Sets the name of the popup. This is only useful for debug purposes. + */ + void setPopupName(const std::string &name) { mPopupName = name; } + + /** + * Returns the name of the popup. This is only useful for debug purposes. + */ + const std::string& getPopupName() { return mPopupName; } + + /** + * Schedule this popup for deletion. It will be deleted at the start + * of the next logic update. + */ + void scheduleDelete(); + + // Inherited from BasicContainer + + virtual gcn::Rectangle getChildrenArea(); + + private: + void setGuiAlpha(); + + Window *mParent; /**< The parent Window (if there is one) */ + std::string mPopupName; /**< Name of the Popup */ + static bool mAlphaChanged; /**< Whether the alpha percent was changed */ + int mMinWidth; /**< Minimum Popup width */ + int mMinHeight; /**< Minimum Popup height */ + int mMaxWidth; /**< Maximum Popup width */ + int mMaxHeight; /**< Maximum Popup height */ + unsigned int mPadding; /**< Holds the padding of the window. */ + + /** + * The config listener that listens to changes relevant to all Popups. + */ + static ConfigListener *popupConfigListener; + + static int instances; /**< Number of Popup instances */ + + Skin* mSkin; /**< Skin in use by this Popup */ +}; + +#endif diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index 4577baee..7627c1ad 100644 --- a/src/gui/popupmenu.cpp +++ b/src/gui/popupmenu.cpp @@ -26,11 +26,11 @@ #include "inventorywindow.h" #include "item_amount.h" #include "popupmenu.h" -#include "windowcontainer.h" #include "../being.h" #include "../beingmanager.h" #include "../floor_item.h" +#include "../graphics.h" #include "../item.h" #include "../localplayer.h" #include "../npc.h" @@ -305,10 +305,10 @@ void PopupMenu::showPopup(int x, int y, Item *item) void PopupMenu::showPopup(int x, int y) { setContentSize(mBrowserBox->getWidth() + 8, mBrowserBox->getHeight() + 8); - if (windowContainer->getWidth() < (x + getWidth() + 5)) - x = windowContainer->getWidth() - getWidth(); - if (windowContainer->getHeight() < (y + getHeight() + 5)) - y = windowContainer->getHeight() - getHeight(); + if (graphics->getWidth() < (x + getWidth() + 5)) + x = graphics->getWidth() - getWidth(); + if (graphics->getHeight() < (y + getHeight() + 5)) + y = graphics->getHeight() - getHeight(); setPosition(x, y); setVisible(true); requestMoveToTop(); diff --git a/src/gui/progressbar.cpp b/src/gui/progressbar.cpp index f0acfecf..58d7d815 100644 --- a/src/gui/progressbar.cpp +++ b/src/gui/progressbar.cpp @@ -22,6 +22,7 @@ #include <guichan/font.hpp> #include "gui.h" +#include "palette.h" #include "progressbar.h" #include "textrenderer.h" @@ -35,8 +36,6 @@ ImageRect ProgressBar::mBorder; int ProgressBar::mInstances = 0; float ProgressBar::mAlpha = config.getValue("guialpha", 0.8); -const gcn::Color ProgressBar::TEXT_COLOR = gcn::Color(255, 255, 255); - ProgressBar::ProgressBar(float progress, unsigned int width, unsigned int height, Uint8 red, Uint8 green, Uint8 blue): @@ -121,23 +120,22 @@ void ProgressBar::draw(gcn::Graphics *graphics) // The bar if (mProgress > 0) { - graphics->setColor(gcn::Color(mRed, mGreen, mBlue, alpha)); graphics->fillRectangle(gcn::Rectangle(4, 4, - (int) (mProgress * (getWidth() - 8)), - getHeight() - 8)); + (int) (mProgress * (getWidth() - 8)), + getHeight() - 8)); } // The label if (!mText.empty()) { - gcn::Font *f = boldFont; - int textX = getWidth() / 2; - int textY = (getHeight() - f->getHeight()) / 2; + const int textX = getWidth() / 2; + const int textY = (getHeight() - boldFont->getHeight()) / 2; TextRenderer::renderText(graphics, mText, textX, textY, - gcn::Graphics::CENTER, &TEXT_COLOR, f, true, - false); + gcn::Graphics::CENTER, + guiPalette->getColor(Palette::PROGRESS_BAR, + alpha), boldFont, true, false); } } diff --git a/src/gui/recorder.cpp b/src/gui/recorder.cpp index ce097db2..479ab76b 100644 --- a/src/gui/recorder.cpp +++ b/src/gui/recorder.cpp @@ -40,9 +40,11 @@ Recorder::Recorder(ChatWindow *chat, const std::string &title, mChat = chat; Button *button = new Button(buttonTxt, "activate", this); - setDefaultSize(0, windowContainer->getHeight() - 123 - button->getHeight() - - offsetY, button->getWidth() + offsetX, button->getHeight() + - offsetY); + + // 123 is the default chat window height. If you change this in Chat, please + // change it here as well + setDefaultSize(button->getWidth() + offsetX, button->getHeight() + + offsetY, ImageRect::LOWER_LEFT, 0, 123); place(0, 0, button); diff --git a/src/gui/register.cpp b/src/gui/register.cpp index 25c97713..0e8a99ca 100644 --- a/src/gui/register.cpp +++ b/src/gui/register.cpp @@ -19,8 +19,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/widgets/label.hpp> - #include "../configuration.h" #include "../log.h" #include "../logindata.h" @@ -28,6 +26,7 @@ #include "button.h" #include "checkbox.h" +#include "label.h" #include "login.h" #include "ok_dialog.h" #include "passwordfield.h" @@ -46,7 +45,8 @@ * to the field which contained wrong data when the Ok button was pressed on * the error notice. */ -class WrongDataNoticeListener : public gcn::ActionListener { +class WrongDataNoticeListener : public gcn::ActionListener +{ public: void setTarget(gcn::TextField *textField); void action(const gcn::ActionEvent &event); @@ -62,22 +62,19 @@ void WrongDataNoticeListener::setTarget(gcn::TextField *textField) void WrongDataNoticeListener::action(const gcn::ActionEvent &event) { if (event.getId() == "ok") - { mTarget->requestFocus(); - } } - RegisterDialog::RegisterDialog(LoginData *loginData): Window(_("Register")), mWrongDataNoticeListener(new WrongDataNoticeListener), mLoginData(loginData) { - gcn::Label *userLabel = new gcn::Label(_("Name:")); - gcn::Label *passwordLabel = new gcn::Label(_("Password:")); - gcn::Label *confirmLabel = new gcn::Label(_("Confirm:")); - gcn::Label *serverLabel = new gcn::Label(_("Server:")); - gcn::Label *portLabel = new gcn::Label(_("Port:")); + gcn::Label *userLabel = new Label(_("Name:")); + gcn::Label *passwordLabel = new Label(_("Password:")); + gcn::Label *confirmLabel = new Label(_("Confirm:")); + gcn::Label *serverLabel = new Label(_("Server:")); + gcn::Label *portLabel = new Label(_("Port:")); mUserField = new TextField(loginData->username); mPasswordField = new PasswordField(loginData->password); mConfirmField = new PasswordField; diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp index e1b15bac..fe391636 100644 --- a/src/gui/sell.cpp +++ b/src/gui/sell.cpp @@ -19,9 +19,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/widgets/label.hpp> - #include "button.h" +#include "label.h" #include "scrollarea.h" #include "sell.h" #include "shop.h" @@ -46,30 +45,36 @@ SellDialog::SellDialog(Network *network): { setWindowName("Sell"); setResizable(true); + setCloseButton(true); setMinWidth(260); setMinHeight(230); - setDefaultSize(0, 0, 260, 230); + setDefaultSize(260, 230, ImageRect::CENTER); // Create a ShopItems instance, that is aware of duplicate entries. mShopItems = new ShopItems(true); mShopItemList = new ShopListBox(mShopItems, mShopItems); mScrollArea = new ScrollArea(mShopItemList); + mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); + mSlider = new Slider(1.0); - mQuantityLabel = new gcn::Label("0"); - mMoneyLabel = new gcn::Label(strprintf(_("Price: %s / Total: %s"), - "", "")); + + mQuantityLabel = new Label(strprintf("%d / %d", mAmountItems, mMaxItems)); + mQuantityLabel->setAlignment(gcn::Graphics::CENTER); + mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"), + "", "")); + mIncreaseButton = new Button("+", "+", this); mDecreaseButton = new Button("-", "-", this); mSellButton = new Button(_("Sell"), "sell", this); mQuitButton = new Button(_("Quit"), "quit", this); - mItemDescLabel = new gcn::Label(strprintf(_("Description: %s"), "")); - mItemEffectLabel = new gcn::Label(strprintf(_("Effect: %s"), "")); + mAddMaxButton = new Button(_("Max"), "max", this); + mItemDescLabel = new Label(strprintf(_("Description: %s"), "")); + mItemEffectLabel = new Label(strprintf(_("Effect: %s"), "")); - mIncreaseButton->setSize(20, 20); - mDecreaseButton->setSize(20, 20); + mDecreaseButton->adjustSize(); + mDecreaseButton->setWidth(mIncreaseButton->getWidth()); - mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); mIncreaseButton->setEnabled(false); mDecreaseButton->setEnabled(false); mSellButton->setEnabled(false); @@ -80,16 +85,21 @@ SellDialog::SellDialog(Network *network): mSlider->setActionEventId("slider"); mSlider->addActionListener(this); - place(0, 0, mScrollArea, 5).setPadding(3); - place(0, 1, mQuantityLabel, 2); - place(2, 1, mSlider, 3); - place(0, 2, mMoneyLabel, 5); - place(0, 3, mItemEffectLabel, 5); - place(0, 4, mItemDescLabel, 5); + ContainerPlacer place; + place = getPlacer(0, 0); + + place(0, 0, mScrollArea, 8, 5).setPadding(3); place(0, 5, mDecreaseButton); - place(1, 5, mIncreaseButton); - place(3, 5, mSellButton); - place(4, 5, mQuitButton); + place(1, 5, mSlider, 3); + place(4, 5, mIncreaseButton); + place(5, 5, mQuantityLabel, 2); + place(7, 5, mAddMaxButton); + place(0, 6, mMoneyLabel, 8); + place(0, 7, mItemEffectLabel, 8); + place(0, 8, mItemDescLabel, 8); + place(6, 9, mSellButton); + place(7, 9, mQuitButton); + Layout &layout = getLayout(); layout.setRowHeight(0, Layout::AUTO_SET); @@ -116,9 +126,7 @@ void SellDialog::reset() void SellDialog::addItem(const Item *item, int price) { if (!item) - { return; - } mShopItems->addItem(item->getInvIndex(), item->getId(), item->getQuantity(), price); @@ -128,15 +136,14 @@ void SellDialog::addItem(const Item *item, int price) void SellDialog::action(const gcn::ActionEvent &event) { - int selectedItem = mShopItemList->getSelected(); - if (event.getId() == "quit") { - setVisible(false); - current_npc = 0; + close(); return; } + int selectedItem = mShopItemList->getSelected(); + // The following actions require a valid item selection if (selectedItem == -1 || selectedItem >= (int) mShopItems->getNumberOfElements()) @@ -161,6 +168,12 @@ void SellDialog::action(const gcn::ActionEvent &event) mSlider->setValue(mAmountItems); updateButtonsAndLabels(); } + else if (event.getId() == "max") + { + mAmountItems = mMaxItems; + mSlider->setValue(mAmountItems); + updateButtonsAndLabels(); + } else if (event.getId() == "sell" && mAmountItems > 0 && mAmountItems <= mMaxItems) { @@ -279,5 +292,12 @@ void SellDialog::setVisible(bool visible) { Window::setVisible(visible); - if (visible) requestFocus(); + if (visible) + requestFocus(); +} + +void SellDialog::close() +{ + setVisible(false); + current_npc = 0; } diff --git a/src/gui/sell.h b/src/gui/sell.h index 3ae5e320..45b6a704 100644 --- a/src/gui/sell.h +++ b/src/gui/sell.h @@ -86,8 +86,15 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener */ void logic(); + /** + * Sets the visibility of this window. + */ void setVisible(bool visible); + /** + * Closes the Buy Window, as well as resetting the current npc. + */ + void close(); private: /** * Updates the state of buttons and labels. @@ -97,6 +104,7 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener Network *mNetwork; gcn::Button *mSellButton; gcn::Button *mQuitButton; + gcn::Button *mAddMaxButton; gcn::Button *mIncreaseButton; gcn::Button *mDecreaseButton; ShopListBox *mShopItemList; diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp index 872596b0..849a30c2 100644 --- a/src/gui/setup.cpp +++ b/src/gui/setup.cpp @@ -34,16 +34,23 @@ #include "../utils/gettext.h" extern Window *chatWindow; -extern Window *equipmentWindow; -extern Window *helpWindow; +extern Window *statusWindow; +extern Window *buyDialog; +extern Window *sellDialog; +extern Window *buySellDialog; extern Window *inventoryWindow; -extern Window *minimap; +extern Window *emoteWindow; +extern Window *npcTextDialog; +extern Window *npcStringDialog; extern Window *skillDialog; -extern Window *statusWindow; +extern Window *minimap; +extern Window *equipmentWindow; +extern Window *tradeWindow; +extern Window *helpWindow; +extern Window *debugWindow; extern Window *itemShortcutWindow; extern Window *emoteShortcutWindow; -extern Window *emoteWindow; -extern Window *tradeWindow; +extern Window *storageWindow; Setup::Setup(): Window(_("Setup")) @@ -65,9 +72,8 @@ Setup::Setup(): add(btn); // Store this button, as it needs to be enabled/disabled - if (!strcmp(*curBtn, "Reset Windows")) { + if (!strcmp(*curBtn, "Reset Windows")) mResetWindows = btn; - } } TabbedArea *panel = new TabbedArea; @@ -130,17 +136,24 @@ void Setup::action(const gcn::ActionEvent &event) if (!statusWindow) return; - statusWindow->resetToDefaultSize(); - minimap->resetToDefaultSize(); chatWindow->resetToDefaultSize(); + statusWindow->resetToDefaultSize(); + buyDialog->resetToDefaultSize(); + sellDialog->resetToDefaultSize(); + buySellDialog->resetToDefaultSize(); inventoryWindow->resetToDefaultSize(); + emoteWindow->resetToDefaultSize(); + npcTextDialog->resetToDefaultSize(); + npcStringDialog->resetToDefaultSize(); + skillDialog->resetToDefaultSize(); + minimap->resetToDefaultSize(); equipmentWindow->resetToDefaultSize(); + tradeWindow->resetToDefaultSize(); helpWindow->resetToDefaultSize(); - skillDialog->resetToDefaultSize(); + debugWindow->resetToDefaultSize(); itemShortcutWindow->resetToDefaultSize(); emoteShortcutWindow->resetToDefaultSize(); - emoteWindow->resetToDefaultSize(); - tradeWindow->resetToDefaultSize(); + storageWindow->resetToDefaultSize(); } } diff --git a/src/gui/setup.h b/src/gui/setup.h index 919445b7..4c387d34 100644 --- a/src/gui/setup.h +++ b/src/gui/setup.h @@ -31,7 +31,6 @@ #include "../guichanfwd.h" class SetupTab; -class Button; /** * The setup dialog. @@ -51,13 +50,16 @@ class Setup : public Window, public gcn::ActionListener */ ~Setup(); - void setInGame(bool inGame); - /** * Event handling method. */ void action(const gcn::ActionEvent &event); + /** + * Enables the reset button when in game. + */ + void setInGame(bool inGame); + private: std::list<SetupTab*> mTabs; gcn::Button *mResetWindows; diff --git a/src/gui/setup_audio.cpp b/src/gui/setup_audio.cpp index a4bc05ae..2ca39282 100644 --- a/src/gui/setup_audio.cpp +++ b/src/gui/setup_audio.cpp @@ -19,9 +19,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/widgets/label.hpp> - #include "checkbox.h" +#include "label.h" #include "ok_dialog.h" #include "setup_audio.h" #include "slider.h" @@ -44,8 +43,8 @@ Setup_Audio::Setup_Audio(): { setOpaque(false); - gcn::Label *sfxLabel = new gcn::Label(_("Sfx volume")); - gcn::Label *musicLabel = new gcn::Label(_("Music volume")); + gcn::Label *sfxLabel = new Label(_("Sfx volume")); + gcn::Label *musicLabel = new Label(_("Music volume")); mSfxSlider->setActionEventId("sfx"); mMusicSlider->setActionEventId("music"); @@ -79,7 +78,8 @@ void Setup_Audio::apply() if (mSoundCheckBox->isSelected()) { config.setValue("sound", 1); - try { + try + { sound.init(); } catch (const char *err) diff --git a/src/gui/setup_colors.cpp b/src/gui/setup_colors.cpp index dcad8670..033ba372 100644 --- a/src/gui/setup_colors.cpp +++ b/src/gui/setup_colors.cpp @@ -23,12 +23,12 @@ #include <cmath> #include <guichan/listmodel.hpp> -#include <guichan/widgets/label.hpp> #include <guichan/widgets/slider.hpp> #include "browserbox.h" #include "gui.h" #include "itemlinkhandler.h" +#include "label.h" #include "listbox.h" #include "palette.h" #include "scrollarea.h" @@ -60,7 +60,7 @@ Setup_Colors::Setup_Colors() : mTextPreview = new TextPreview(&rawmsg); mPreview = new BrowserBox(BrowserBox::AUTO_WRAP); - mPreview->setOpaque(true); + mPreview->setOpaque(false); // don't do anything with links mPreview->setLinkHandler(NULL); @@ -70,18 +70,18 @@ Setup_Colors::Setup_Colors() : mPreviewBox->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER, gcn::ScrollArea::SHOW_NEVER); - mGradTypeLabel = new gcn::Label(_("Type: ")); + mGradTypeLabel = new Label(_("Type: ")); - mGradTypeSlider = new Slider(0, 2); + mGradTypeSlider = new Slider(0, 3); mGradTypeSlider->setWidth(160); mGradTypeSlider->setActionEventId("slider_grad"); mGradTypeSlider->setValue(0); mGradTypeSlider->addActionListener(this); mGradTypeSlider->setEnabled(false); - mGradTypeText = new gcn::Label(); + mGradTypeText = new Label(); - mRedLabel = new gcn::Label(_("Red: ")); + mRedLabel = new Label(_("Red: ")); mRedText = new TextField; mRedText->setWidth(40); @@ -97,7 +97,7 @@ Setup_Colors::Setup_Colors() : mRedSlider->addActionListener(this); mRedSlider->setEnabled(false); - mGreenLabel = new gcn::Label(_("Green: ")); + mGreenLabel = new Label(_("Green: ")); mGreenText = new TextField; mGreenText->setWidth(40); @@ -113,7 +113,7 @@ Setup_Colors::Setup_Colors() : mGreenSlider->addActionListener(this); mGreenSlider->setEnabled(false); - mBlueLabel = new gcn::Label(_("Blue: ")); + mBlueLabel = new Label(_("Blue: ")); mBlueText = new TextField; mBlueText->setWidth(40); @@ -156,13 +156,9 @@ Setup_Colors::Setup_Colors() : Setup_Colors::~Setup_Colors() { if (mPreviewBox->getContent() == mPreview) - { delete mTextPreview; - } else - { delete mPreview; - } } void Setup_Colors::action(const gcn::ActionEvent &event) @@ -180,11 +176,12 @@ void Setup_Colors::action(const gcn::ActionEvent &event) mPreview->clearRows(); mPreviewBox->setContent(mTextPreview); mTextPreview->setFont(gui->getFont()); - mTextPreview->setTextColor( - &guiPalette->getColor(Palette::TEXT)); + mTextPreview->setTextColor(&guiPalette->getColor(Palette::TEXT)); mTextPreview->setTextBGColor(NULL); + mTextPreview->setOpaque(false); mTextPreview->setShadow(true); mTextPreview->setOutline(true); + mTextPreview->useTextAlpha(false); switch (type) { @@ -192,13 +189,30 @@ void Setup_Colors::action(const gcn::ActionEvent &event) case Palette::SHADOW: case Palette::OUTLINE: mTextPreview->setFont(gui->getFont()); - mTextPreview->setOutline(true); mTextPreview->setShadow(type == Palette::SHADOW); mTextPreview->setOutline(type == Palette::OUTLINE); break; + case Palette::PROGRESS_BAR: + mTextPreview->useTextAlpha(true); + mTextPreview->setFont(boldFont); + mTextPreview->setTextColor(col); + mTextPreview->setOutline(true); + mTextPreview->setShadow(false); + break; + case Palette::TAB_HIGHLIGHT: + mTextPreview->setFont(gui->getFont()); + mTextPreview->setTextColor(col); + mTextPreview->setOutline(false); + mTextPreview->setShadow(false); + break; case Palette::BACKGROUND: - case Palette::HIGHLIGHT: case Palette::SHOP_WARNING: + mTextPreview->setBGColor(col); + mTextPreview->setOpaque(true); + mTextPreview->setOutline(false); + mTextPreview->setShadow(false); + break; + case Palette::HIGHLIGHT: mTextPreview->setTextBGColor(col); mTextPreview->setOutline(false); mTextPreview->setShadow(false); @@ -217,15 +231,30 @@ void Setup_Colors::action(const gcn::ActionEvent &event) mPreview->clearRows(); if (ch == '<') - { msg = toString("@@|") + rawmsg + "@@"; - } else - { msg = "##" + toString(ch) + rawmsg; - } + mPreview->addRow(msg); break; + case Palette::UNKNOWN_ITEM: + case Palette::GENERIC: + case Palette::HEAD: + case Palette::USABLE: + case Palette::TORSO: + case Palette::ONEHAND: + case Palette::LEGS: + case Palette::FEET: + case Palette::TWOHAND: + case Palette::SHIELD: + case Palette::RING: + case Palette::ARMS: + case Palette::AMMO: + mTextPreview->setFont(boldFont); + mTextPreview->setTextColor(col); + mTextPreview->setOutline(false); + mTextPreview->setShadow(false); + break; case Palette::PARTICLE: case Palette::EXP_INFO: case Palette::PICKUP_INFO: @@ -242,14 +271,19 @@ void Setup_Colors::action(const gcn::ActionEvent &event) case Palette::MONSTER: mTextPreview->setFont(boldFont); mTextPreview->setTextColor(col); + case Palette::TYPE_COUNT: break; } - if (grad != Palette::STATIC) + if (grad != Palette::STATIC && grad != Palette::PULSE) { // If nonstatic color, don't display the current, but the committed // color at the sliders col = &guiPalette->getCommittedColor(type); } + else if (grad == Palette::PULSE) + { + col = &guiPalette->getTestColor(type); + } setEntry(mRedSlider, mRedText, col->r); setEntry(mGreenSlider, mGreenText, col->g); @@ -337,11 +371,10 @@ void Setup_Colors::listen(const TextField *tf) } } -void Setup_Colors::updateGradType() { +void Setup_Colors::updateGradType() +{ if (mSelected == -1) - { return; - } mSelected = mColorBox->getSelected(); Palette::ColorType type = guiPalette->getColorTypeAt(mSelected); @@ -349,9 +382,10 @@ void Setup_Colors::updateGradType() { mGradTypeText->setCaption( (grad == Palette::STATIC) ? _("Static") : + (grad == Palette::PULSE) ? _("Pulse") : (grad == Palette::RAINBOW) ? _("Rainbow") : _("Spectrum")); - bool enable = (grad == Palette::STATIC); + bool enable = (grad == Palette::STATIC || grad == Palette::PULSE); mRedText->setEnabled(enable); mRedSlider->setEnabled(enable); mGreenText->setEnabled(enable); @@ -363,13 +397,11 @@ void Setup_Colors::updateGradType() { void Setup_Colors::updateColor() { if (mSelected == -1) - { return; - } Palette::ColorType type = guiPalette->getColorTypeAt(mSelected); Palette::GradientType grad = - static_cast<Palette::GradientType>((int)mGradTypeSlider->getValue()); + static_cast<Palette::GradientType>(mGradTypeSlider->getValue()); guiPalette->setGradient(type, grad); if (grad == Palette::STATIC) @@ -379,4 +411,11 @@ void Setup_Colors::updateColor() static_cast<int>(mGreenSlider->getValue()), static_cast<int>(mBlueSlider->getValue())); } + else if (grad == Palette::PULSE) + { + guiPalette->setTestColor(type, gcn::Color( + static_cast<int>(mRedSlider->getValue()), + static_cast<int>(mGreenSlider->getValue()), + static_cast<int>(mBlueSlider->getValue()))); + } } diff --git a/src/gui/setup_joystick.cpp b/src/gui/setup_joystick.cpp index c0c04949..59a882c7 100644 --- a/src/gui/setup_joystick.cpp +++ b/src/gui/setup_joystick.cpp @@ -19,10 +19,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/widgets/label.hpp> - #include "button.h" #include "checkbox.h" +#include "label.h" #include "setup_joystick.h" #include "widgets/layouthelper.h" @@ -35,7 +34,7 @@ extern Joystick *joystick; Setup_Joystick::Setup_Joystick(): - mCalibrateLabel(new gcn::Label(_("Press the button to start calibration"))), + mCalibrateLabel(new Label(_("Press the button to start calibration"))), mCalibrateButton(new Button(_("Calibrate"), "calibrate", this)), mJoystickEnabled(new CheckBox(_("Enable joystick"))) { diff --git a/src/gui/setup_players.cpp b/src/gui/setup_players.cpp index 84dbed55..1451e71e 100644 --- a/src/gui/setup_players.cpp +++ b/src/gui/setup_players.cpp @@ -22,10 +22,9 @@ #include <string> #include <vector> -#include <guichan/widgets/label.hpp> - #include "button.h" #include "checkbox.h" +#include "label.h" #include "listbox.h" #include "ok_dialog.h" #include "scrollarea.h" @@ -137,7 +136,7 @@ public: for (unsigned int r = 0; r < player_names->size(); ++r) { std::string name = (*player_names)[r]; - gcn::Widget *widget = new gcn::Label(name); + gcn::Widget *widget = new Label(name); mWidgets.push_back(widget); gcn::ListModel *playerRelation = new PlayerRelationListModel; @@ -247,7 +246,7 @@ Setup_Players::Setup_Players(): for (int i = 0; i < COLUMNS_NR; i++) { mPlayerTableTitleModel->set(0, i, - new gcn::Label(gettext(table_titles[i]))); + new Label(gettext(table_titles[i]))); } mPlayerTitleTable->setLinewiseSelection(true); @@ -257,7 +256,7 @@ Setup_Players::Setup_Players(): mPlayerTable->setLinewiseSelection(true); mPlayerTable->addActionListener(this); - gcn::Label *ignore_action_label = new gcn::Label(_("When ignoring:")); + gcn::Label *ignore_action_label = new Label(_("When ignoring:")); mIgnoreActionChoicesBox->setActionEventId(ACTION_STRATEGY); mIgnoreActionChoicesBox->addActionListener(this); diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp index ad133e7e..74574ec7 100644 --- a/src/gui/setup_video.cpp +++ b/src/gui/setup_video.cpp @@ -26,9 +26,8 @@ #include <guichan/key.hpp> #include <guichan/listmodel.hpp> -#include <guichan/widgets/label.hpp> - #include "checkbox.h" +#include "label.h" #include "listbox.h" #include "ok_dialog.h" #include "scrollarea.h" @@ -88,13 +87,15 @@ ModeListModel::ModeListModel() SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE); /* Check which modes are available */ - if (modes == (SDL_Rect **)0) { + if (modes == (SDL_Rect **)0) logger->log("No modes available"); - } else if (modes == (SDL_Rect **)-1) { + else if (modes == (SDL_Rect **)-1) logger->log("All resolutions available"); - } else { + else + { //logger->log("Available Modes"); - for (int i = 0; modes[i]; ++i) { + for (int i = 0; modes[i]; ++i) + { const std::string modeString = toString((int)modes[i]->w) + "x" + toString((int)modes[i]->h); //logger->log(modeString.c_str()); @@ -121,15 +122,15 @@ Setup_Video::Setup_Video(): mCustomCursorCheckBox(new CheckBox(_("Custom cursor"), mCustomCursorEnabled)), mParticleEffectsCheckBox(new CheckBox(_("Particle effects"), mParticleEffectsEnabled)), mNameCheckBox(new CheckBox(_("Show name"), mNameEnabled)), - mPickupNotifyLabel(new gcn::Label(_("Show pickup notification"))), + mPickupNotifyLabel(new Label(_("Show pickup notification"))), mPickupChatCheckBox(new CheckBox(_("in chat"), mPickupChatEnabled)), mPickupParticleCheckBox(new CheckBox(_("as particle"), mPickupParticleEnabled)), mSpeechSlider(new Slider(0, 3)), - mSpeechLabel(new gcn::Label("")), + mSpeechLabel(new Label("")), mAlphaSlider(new Slider(0.2, 1.0)), mFpsCheckBox(new CheckBox(_("FPS Limit:"))), - mFpsSlider(new Slider(10, 200)), + mFpsSlider(new Slider(10, 120)), mFpsField(new TextField), mOriginalScrollLaziness((int) config.getValue("ScrollLaziness", 16)), mScrollLazinessSlider(new Slider(1, 64)), @@ -139,22 +140,22 @@ Setup_Video::Setup_Video(): mScrollRadiusField(new TextField), mOverlayDetail((int) config.getValue("OverlayDetail", 2)), mOverlayDetailSlider(new Slider(0, 2)), - mOverlayDetailField(new gcn::Label("")), + mOverlayDetailField(new Label("")), mParticleDetail(3 - (int) config.getValue("particleEmitterSkip", 1)), mParticleDetailSlider(new Slider(0, 3)), - mParticleDetailField(new gcn::Label("")) + mParticleDetailField(new Label("")) { setOpaque(false); ScrollArea *scrollArea = new ScrollArea(mModeList); scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); - speechLabel = new gcn::Label(_("Overhead text")); - alphaLabel = new gcn::Label(_("Gui opacity")); - scrollRadiusLabel = new gcn::Label(_("Scroll radius")); - scrollLazinessLabel = new gcn::Label(_("Scroll laziness")); - overlayDetailLabel = new gcn::Label(_("Ambient FX")); - particleDetailLabel = new gcn::Label(_("Particle Detail")); + speechLabel = new Label(_("Overhead text")); + alphaLabel = new Label(_("Gui opacity")); + scrollRadiusLabel = new Label(_("Scroll radius")); + scrollLazinessLabel = new Label(_("Scroll laziness")); + overlayDetailLabel = new Label(_("Ambient FX")); + particleDetailLabel = new Label(_("Particle Detail")); mModeList->setEnabled(true); #ifndef USE_OPENGL @@ -337,9 +338,11 @@ void Setup_Video::apply() } } #if defined(WIN32) || defined(__APPLE__) - } else { + } + else + { new OkDialog(_("Switching to full screen"), - _("Restart needed for changes to take effect.")); + _("Restart needed for changes to take effect.")); } #endif config.setValue("screen", fullscreen ? true : false); @@ -352,7 +355,7 @@ void Setup_Video::apply() // OpenGL can currently only be changed by restarting, notify user. new OkDialog(_("Changing OpenGL"), - _("Applying change to OpenGL requires restart.")); + _("Applying change to OpenGL requires restart.")); } // FPS change @@ -450,8 +453,9 @@ void Setup_Video::action(const gcn::ActionEvent &event) { config.setValue("particleeffects", mParticleEffectsCheckBox->isSelected() ? true : false); - new OkDialog(_("Particle effect settings changed"), - _("Restart your client or change maps for the change to take effect.")); + new OkDialog(_("Particle effect settings changed."), + _("Restart your client or change maps " + "for the change to take effect.")); } else if (event.getId() == "pickupchat") { @@ -461,8 +465,7 @@ void Setup_Video::action(const gcn::ActionEvent &event) else if (event.getId() == "pickupparticle") { config.setValue("showpickupparticle", - mPickupParticleCheckBox->isSelected() - ? true : false); + mPickupParticleCheckBox->isSelected() ? true : false); } else if (event.getId() == "speech") { @@ -576,9 +579,9 @@ void Setup_Video::keyPressed(gcn::KeyEvent &event) { mFps = 10; } - else if (mFps > 200) + else if (mFps > 120) { - mFps = 200; + mFps = 120; } mFpsField->setText(toString(mFps)); mFpsSlider->setValue(mFps); diff --git a/src/gui/shortcutcontainer.cpp b/src/gui/shortcutcontainer.cpp index f149266b..901095e5 100644 --- a/src/gui/shortcutcontainer.cpp +++ b/src/gui/shortcutcontainer.cpp @@ -42,13 +42,12 @@ void ShortcutContainer::widgetResized(const gcn::Event &event) if (mGridWidth < 1) mGridWidth = 1; + setHeight((mMaxItems / mGridWidth) * mBoxHeight); + mGridHeight = getHeight() / mBoxHeight; if (mGridHeight < 1) mGridHeight = 1; - - setHeight((mMaxItems / mGridWidth + - (mMaxItems % mGridWidth > 0 ? 1 : 0)) * mBoxHeight); } int ShortcutContainer::getIndexFromGrid(int pointX, int pointY) const diff --git a/src/gui/shortcutwindow.cpp b/src/gui/shortcutwindow.cpp index c704fc44..dcc7f72e 100644 --- a/src/gui/shortcutwindow.cpp +++ b/src/gui/shortcutwindow.cpp @@ -23,6 +23,8 @@ #include "shortcutcontainer.h" #include "shortcutwindow.h" +#include "widgets/layout.h" + #include "../configuration.h" static const int SCROLL_PADDING = 0; @@ -39,29 +41,28 @@ ShortcutWindow::ShortcutWindow(const char *title, ShortcutContainer *content) mItems = content; - mInstances++; - const int border = SCROLL_PADDING * 2 + getPadding() * 2; setMinWidth(mItems->getBoxWidth() + border); setMinHeight(mItems->getBoxHeight() + border); setMaxWidth(mItems->getBoxWidth() * mItems->getMaxItems() + border); setMaxHeight(mItems->getBoxHeight() * mItems->getMaxItems() + border); - const int width = (int) config.getValue("screenwidth", 800); - const int height = (int) config.getValue("screenheight", 600); + setDefaultSize(mItems->getBoxWidth() + border, (mItems->getBoxHeight() * + mItems->getMaxItems()) + border, ImageRect::LOWER_RIGHT, + mInstances * mItems->getBoxWidth(), 0); - setDefaultSize(width - (mInstances * mItems->getBoxWidth()) - - (mInstances * border), height - (mItems->getBoxHeight() * - mItems->getMaxItems()) - border, mItems->getBoxWidth() + - border, (mItems->getBoxHeight() * mItems->getMaxItems()) + - border); + mInstances++; mScrollArea = new ScrollArea(mItems); mScrollArea->setPosition(SCROLL_PADDING, SCROLL_PADDING); mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); mScrollArea->setOpaque(false); - add(mScrollArea); + place(0, 0, mScrollArea, 5, 5).setPadding(0); + + Layout &layout = getLayout(); + layout.setRowHeight(0, Layout::AUTO_SET); + layout.setMargin(0); loadWindowState(); } @@ -71,13 +72,3 @@ ShortcutWindow::~ShortcutWindow() delete mItems; } -void ShortcutWindow::widgetResized(const gcn::Event &event) -{ - Window::widgetResized(event); - - const gcn::Rectangle &area = getChildrenArea(); - - mScrollArea->setSize( - area.width - SCROLL_PADDING, - area.height - SCROLL_PADDING); -} diff --git a/src/gui/shortcutwindow.h b/src/gui/shortcutwindow.h index 64592328..eae881ba 100644 --- a/src/gui/shortcutwindow.h +++ b/src/gui/shortcutwindow.h @@ -45,11 +45,6 @@ class ShortcutWindow : public Window */ ~ShortcutWindow(); - /** - * Called whenever the widget changes size. - */ - void widgetResized(const gcn::Event &event); - private: ShortcutWindow(); ShortcutContainer *mItems; diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp index ed374a31..39ccbb06 100644 --- a/src/gui/skill.cpp +++ b/src/gui/skill.cpp @@ -19,9 +19,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/widgets/label.hpp> - #include "button.h" +#include "label.h" #include "listbox.h" #include "scrollarea.h" #include "skill.h" @@ -102,13 +101,13 @@ public: info = &fakeSkillInfo; sprintf(tmp, "%c%s", info->modifiable? ' ' : '*', info->name.c_str()); - gcn::Label *name_label = new gcn::Label(tmp); + gcn::Label *name_label = new Label(tmp); sprintf(tmp, "Lv:%i", skill->lv); - gcn::Label *lv_label = new gcn::Label(tmp); + gcn::Label *lv_label = new Label(tmp); sprintf(tmp, "Sp:%i", skill->sp); - gcn::Label *sp_label = new gcn::Label(tmp); + gcn::Label *sp_label = new Label(tmp); set(i, 0, name_label); set(i, 1, lv_label); @@ -136,13 +135,13 @@ SkillDialog::SkillDialog(): setWindowName("Skills"); setCloseButton(true); - setDefaultSize(windowContainer->getWidth() - 260, 25, 255, 260); + setDefaultSize(255, 260, ImageRect::CENTER); setMinHeight(50 + mTableModel->getHeight()); setMinWidth(200); ScrollArea *skillScrollArea = new ScrollArea(mTable); - mPointsLabel = new gcn::Label(strprintf(_("Skill points: %d"), 0)); + mPointsLabel = new Label(strprintf(_("Skill points: %d"), 0)); mIncButton = new Button(_("Up"), _("inc"), this); mUseButton = new Button(_("Use"), _("use"), this); mUseButton->setEnabled(false); diff --git a/src/gui/skin.cpp b/src/gui/skin.cpp new file mode 100644 index 00000000..d44c54a8 --- /dev/null +++ b/src/gui/skin.cpp @@ -0,0 +1,191 @@ +/* + * Aethyra + * Copyright (C) 2009 Aethyra Development Team + * + * This file is part of Aethyra. + * + * 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 "skin.h" + +#include "../log.h" + +#include "../resources/image.h" +#include "../resources/resourcemanager.h" + +#include "../utils/dtor.h" +#include "../utils/xml.h" + +SkinLoader* skinLoader = NULL; + +Skin::Skin(ImageRect skin, Image* close, std::string name): + instances(0), + mName(name), + border(skin), + closeImage(close) +{ +} + +Skin::~Skin() +{ + // Clean up static resources + for (int i = 0; i < 9; i++) + { + delete border.grid[i]; + border.grid[i] = NULL; + } + + closeImage->decRef(); +} + +unsigned int Skin::getMinWidth() +{ + return (border.grid[0]->getWidth() + border.grid[1]->getWidth()) + + border.grid[2]->getWidth(); +} + +unsigned int Skin::getMinHeight() +{ + return (border.grid[0]->getHeight() + border.grid[3]->getHeight()) + + border.grid[6]->getHeight(); +} + +Skin* SkinLoader::load(const std::string &filename) +{ + SkinIterator skinIterator = mSkins.find(filename); + + if (mSkins.end() != skinIterator) + { + skinIterator->second->instances++; + return skinIterator->second; + } + + ResourceManager *resman = ResourceManager::getInstance(); + + logger->log("Loading Skin '%s'.", filename.c_str()); + + if (filename.empty()) + logger->error("SkinLoader::load(): Invalid File Name."); + + // TODO: + // If there is an error loading the specified file, we should try to revert + // to a 'default' skin file. Only if the 'default' skin file can't be loaded + // should we have a terminating error. + XML::Document doc(filename); + xmlNodePtr rootNode = doc.rootNode(); + + if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "skinset")) + logger->error("Widget Skinning error"); + + std::string skinSetImage; + skinSetImage = XML::getProperty(rootNode, "image", ""); + Image *dBorders = NULL; + ImageRect border; + + if (!skinSetImage.empty()) + { + logger->log("SkinLoader::load(): <skinset> defines " + "'%s' as a skin image.", skinSetImage.c_str()); + dBorders = resman->getImage("graphics/gui/" + skinSetImage); + } + else + { + logger->error("SkinLoader::load(): Skinset does not define an image!"); + } + + //iterate <widget>'s + for_each_xml_child_node(widgetNode, rootNode) + { + if (!xmlStrEqual(widgetNode->name, BAD_CAST "widget")) + continue; + + std::string widgetType; + widgetType = XML::getProperty(widgetNode, "type", "unknown"); + if (widgetType == "Window") + { + // Iterate through <part>'s + // LEEOR / TODO: + // We need to make provisions to load in a CloseButton image. For + // now it can just be hard-coded. + for_each_xml_child_node(partNode, widgetNode) + { + if (!xmlStrEqual(partNode->name, BAD_CAST "part")) + continue; + + std::string partType; + partType = XML::getProperty(partNode, "type", "unknown"); + // TOP ROW + const int xPos = XML::getProperty(partNode, "xpos", 0); + const int yPos = XML::getProperty(partNode, "ypos", 0); + const int width = XML::getProperty(partNode, "width", 1); + const int height = XML::getProperty(partNode, "height", 1); + + if (partType == "top-left-corner") + border.grid[0] = dBorders->getSubImage(xPos, yPos, width, height); + else if (partType == "top-edge") + border.grid[1] = dBorders->getSubImage(xPos, yPos, width, height); + else if (partType == "top-right-corner") + border.grid[2] = dBorders->getSubImage(xPos, yPos, width, height); + + // MIDDLE ROW + else if (partType == "left-edge") + border.grid[3] = dBorders->getSubImage(xPos, yPos, width, height); + else if (partType == "bg-quad") + border.grid[4] = dBorders->getSubImage(xPos, yPos, width, height); + else if (partType == "right-edge") + border.grid[5] = dBorders->getSubImage(xPos, yPos, width, height); + + // BOTTOM ROW + else if (partType == "bottom-left-corner") + border.grid[6] = dBorders->getSubImage(xPos, yPos, width, height); + else if (partType == "bottom-edge") + border.grid[7] = dBorders->getSubImage(xPos, yPos, width, height); + else if (partType == "bottom-right-corner") + border.grid[8] = dBorders->getSubImage(xPos, yPos, width, height); + + // Part is of an uknown type. + else + logger->log("SkinLoader::load(): Unknown Part Type '%s'", partType.c_str()); + } + } + // Widget is of an uknown type. + else + { + logger->log("SkinLoader::load(): Unknown Widget Type '%s'", widgetType.c_str()); + } + } + dBorders->decRef(); + + logger->log("Finished loading Skin."); + + // Hard-coded for now until we update the above code to look for window buttons. + Image* closeImage = resman->getImage("graphics/gui/close_button.png"); + + Skin* skin = new Skin(border, closeImage); + + mSkins[filename] = skin; + return skin; +} + +SkinLoader::SkinLoader() +{ +} + +SkinLoader::~SkinLoader() +{ + delete_all(mSkins); +} + diff --git a/src/gui/skin.h b/src/gui/skin.h new file mode 100644 index 00000000..b8a1242e --- /dev/null +++ b/src/gui/skin.h @@ -0,0 +1,101 @@ +/* + * Aethyra + * Copyright (C) 2009 Aethyra Development Team + * + * This file is part of Aethyra. + * + * 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 SKIN_H +#define SKIN_H + +#include <map> +#include <string> + +#include "../graphics.h" + +class Image; + +class Skin +{ + public: + Skin(ImageRect skin, Image* close, std::string name = ""); + ~Skin(); + + /** + * Returns the skin's name. Useful for giving a human friendly skin + * name if a dialog for skin selection for a specific window type is + * done. + */ + std::string getName() { return mName; } + + /** + * Returns the background skin. + */ + ImageRect getBorder() { return border; } + + /** + * Returns the image used by a close button for this skin. + */ + Image* getCloseImage() { return closeImage; } + + /** + * Returns the number of instances which use this skin. + */ + int getNumberOfInstances() { return instances; } + + /** + * Returns the minimum width which can be used with this skin. + */ + unsigned int getMinWidth(); + + /** + * Returns the minimum height which can be used with this skin. + */ + unsigned int getMinHeight(); + + int instances; + + private: + std::string mName; /**< Name of the skin to use */ + ImageRect border; /**< The window border and background */ + Image *closeImage; /**< Close Button Image */ +}; + +// Map containing all window skins +typedef std::map<std::string, Skin*> Skins; + +// Iterator for window skins +typedef Skins::iterator SkinIterator; + +class SkinLoader +{ + public: + SkinLoader(); + ~SkinLoader(); + + /** + * Loads a skin + */ + Skin* load(const std::string &filename); + + private: + Skins mSkins; +}; + +extern SkinLoader* skinLoader; + +#endif diff --git a/src/gui/slider.cpp b/src/gui/slider.cpp index 9bfa840f..cc381c32 100644 --- a/src/gui/slider.cpp +++ b/src/gui/slider.cpp @@ -95,6 +95,16 @@ void Slider::init() vGrip = slider->getSubImage(x, y, w, h); slider->decRef(); + + hStart->setAlpha(mAlpha); + hMid->setAlpha(mAlpha); + hEnd->setAlpha(mAlpha); + hGrip->setAlpha(mAlpha); + + vStart->setAlpha(mAlpha); + vMid->setAlpha(mAlpha); + vEnd->setAlpha(mAlpha); + vGrip->setAlpha(mAlpha); } mInstances++; diff --git a/src/gui/speechbubble.cpp b/src/gui/speechbubble.cpp index fb0d7684..de0c8406 100644 --- a/src/gui/speechbubble.cpp +++ b/src/gui/speechbubble.cpp @@ -28,15 +28,17 @@ #include "speechbubble.h" #include "textbox.h" +#include "../graphics.h" + #include "../utils/gettext.h" SpeechBubble::SpeechBubble(): - Window(_("Speech"), false, NULL, "graphics/gui/speechbubble.xml"), + Popup("Speech", NULL, "graphics/gui/speechbubble.xml"), mText("") { setContentSize(140, 46); - setShowTitle(false); - setTitleBarHeight(0); + setMinWidth(29); + setMinHeight(29); mCaption = new gcn::Label(""); mCaption->setFont(boldFont); @@ -57,8 +59,6 @@ SpeechBubble::SpeechBubble(): add(mCaption); add(mSpeechArea); - - center(); } void SpeechBubble::setCaption(const std::string &name, const gcn::Color *color) @@ -73,13 +73,15 @@ void SpeechBubble::setText(std::string text, bool showName) if ((text == mText) && (mCaption->getWidth() <= mSpeechBox->getMinWidth())) return; + graphics->setColor(guiPalette->getColor(Palette::TEXT)); + int width = mCaption->getWidth(); mSpeechBox->setTextWrapped(text, 130 > width ? 130 : width); const int fontHeight = getFont()->getHeight(); const int numRows = showName ? mSpeechBox->getNumberOfRows() + 1 : mSpeechBox->getNumberOfRows(); - int yPos = showName ? fontHeight + 3 : 3; + int yPos = showName ? fontHeight + getPadding() : getPadding(); int height = (numRows * fontHeight); if (width < mSpeechBox->getMinWidth()) @@ -87,11 +89,11 @@ void SpeechBubble::setText(std::string text, bool showName) if (numRows == 1) { - yPos = (fontHeight / 4) + 3; + yPos = (fontHeight / 4) + getPadding(); height = ((3 * fontHeight) / 2) + 1; } - setContentSize(width + fontHeight, height + 6); + setContentSize(width + fontHeight, height + getPadding()); mSpeechArea->setDimension(gcn::Rectangle(4, yPos, width + 5, height)); } diff --git a/src/gui/speechbubble.h b/src/gui/speechbubble.h index 34e00722..8bb0e5ea 100644 --- a/src/gui/speechbubble.h +++ b/src/gui/speechbubble.h @@ -23,21 +23,39 @@ #define SPEECHBUBBLE_H #include "palette.h" -#include "window.h" +#include "popup.h" class ScrollArea; class TextBox; -class SpeechBubble : public Window +class SpeechBubble : public Popup { public: + /** + * Constructor. Initializes the speech bubble. + */ SpeechBubble(); + /** + * Sets the name displayed for the speech bubble, and in what color. + */ void setCaption(const std::string &name, const gcn::Color *color = &guiPalette->getColor(Palette::TEXT)); + + /** + * Sets the text to be displayed. + */ void setText(std::string text, bool showName = true); + + /** + * Sets the location in which the speech bubble will be displayed. + */ void setLocation(int x, int y); + + /** + * Gets the number of rows the speech bubble has. + */ unsigned int getNumRows(); private: diff --git a/src/gui/status.cpp b/src/gui/status.cpp index ff0c8563..a9af2ab4 100644 --- a/src/gui/status.cpp +++ b/src/gui/status.cpp @@ -19,9 +19,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <guichan/widgets/label.hpp> - #include "button.h" +#include "label.h" #include "progressbar.h" #include "status.h" #include "windowcontainer.h" @@ -42,28 +41,27 @@ StatusWindow::StatusWindow(LocalPlayer *player): { setWindowName("Status"); setCloseButton(true); - setDefaultSize((windowContainer->getWidth() - 365) / 2, - (windowContainer->getHeight() - 255) / 2, 400, 345); + setDefaultSize(400, 345, ImageRect::CENTER); // ---------------------- // Status Part // ---------------------- - mLvlLabel = new gcn::Label(strprintf(_("Level: %d"), 0)); - mJobLvlLabel = new gcn::Label(strprintf(_("Job: %d"), 0)); - mGpLabel = new gcn::Label(strprintf(_("Money: %s"), + mLvlLabel = new Label(strprintf(_("Level: %d"), 0)); + mJobLvlLabel = new Label(strprintf(_("Job: %d"), 0)); + mGpLabel = new Label(strprintf(_("Money: %s"), Units::formatCurrency(mCurrency).c_str())); - mHpLabel = new gcn::Label(_("HP:")); + mHpLabel = new Label(_("HP:")); mHpBar = new ProgressBar(1.0f, 80, 15, 0, 171, 34); - mXpLabel = new gcn::Label(_("Exp:")); + mXpLabel = new Label(_("Exp:")); mXpBar = new ProgressBar(1.0f, 80, 15, 143, 192, 211); - mMpLabel = new gcn::Label(_("MP:")); + mMpLabel = new Label(_("MP:")); mMpBar = new ProgressBar(1.0f, 80, 15, 26, 102, 230); - mJobLabel = new gcn::Label(_("Job:")); + mJobLabel = new Label(_("Job:")); mJobBar = new ProgressBar(1.0f, 80, 15, 220, 135, 203); // ---------------------- @@ -71,41 +69,41 @@ StatusWindow::StatusWindow(LocalPlayer *player): // ---------------------- // Static Labels - gcn::Label *mStatsTitleLabel = new gcn::Label(_("Stats")); - gcn::Label *mStatsTotalLabel = new gcn::Label(_("Total")); - gcn::Label *mStatsCostLabel = new gcn::Label(_("Cost")); + gcn::Label *mStatsTitleLabel = new Label(_("Stats")); + gcn::Label *mStatsTotalLabel = new Label(_("Total")); + gcn::Label *mStatsCostLabel = new Label(_("Cost")); mStatsTotalLabel->setAlignment(gcn::Graphics::CENTER); // Derived Stats - mStatsAttackLabel = new gcn::Label(_("Attack:")); - mStatsDefenseLabel= new gcn::Label(_("Defense:")); - mStatsMagicAttackLabel = new gcn::Label(_("M.Attack:")); - mStatsMagicDefenseLabel = new gcn::Label(_("M.Defense:")); + mStatsAttackLabel = new Label(_("Attack:")); + mStatsDefenseLabel= new Label(_("Defense:")); + mStatsMagicAttackLabel = new Label(_("M.Attack:")); + mStatsMagicDefenseLabel = new Label(_("M.Defense:")); // Gettext flag for next line: xgettext:no-c-format - mStatsAccuracyLabel = new gcn::Label(_("% Accuracy:")); + mStatsAccuracyLabel = new Label(_("% Accuracy:")); // Gettext flag for next line: xgettext:no-c-format - mStatsEvadeLabel = new gcn::Label(_("% Evade:")); + mStatsEvadeLabel = new Label(_("% Evade:")); // Gettext flag for next line: xgettext:no-c-format - mStatsReflexLabel = new gcn::Label(_("% Reflex:")); + mStatsReflexLabel = new Label(_("% Reflex:")); - mStatsAttackPoints = new gcn::Label; - mStatsDefensePoints = new gcn::Label; - mStatsMagicAttackPoints = new gcn::Label; - mStatsMagicDefensePoints = new gcn::Label; - mStatsAccuracyPoints = new gcn::Label; - mStatsEvadePoints = new gcn::Label; - mStatsReflexPoints = new gcn::Label; + mStatsAttackPoints = new Label; + mStatsDefensePoints = new Label; + mStatsMagicAttackPoints = new Label; + mStatsMagicDefensePoints = new Label; + mStatsAccuracyPoints = new Label; + mStatsEvadePoints = new Label; + mStatsReflexPoints = new Label; // New labels for (int i = 0; i < 6; i++) { - mStatsLabel[i] = new gcn::Label("0"); + mStatsLabel[i] = new Label("0"); mStatsLabel[i]->setAlignment(gcn::Graphics::CENTER); - mStatsDisplayLabel[i] = new gcn::Label; - mPointsLabel[i] = new gcn::Label("0"); + mStatsDisplayLabel[i] = new Label; + mPointsLabel[i] = new Label("0"); mPointsLabel[i]->setAlignment(gcn::Graphics::CENTER); } - mRemainingStatsPointsLabel = new gcn::Label; + mRemainingStatsPointsLabel = new Label; // Set button events Id mStatsButton[0] = new Button("+", "STR", this); @@ -269,29 +267,17 @@ void StatusWindow::action(const gcn::ActionEvent &event) if (event.getId().length() == 3) { if (event.getId() == "STR") - { player_node->raiseAttribute(LocalPlayer::STR); - } if (event.getId() == "AGI") - { player_node->raiseAttribute(LocalPlayer::AGI); - } if (event.getId() == "VIT") - { player_node->raiseAttribute(LocalPlayer::VIT); - } if (event.getId() == "INT") - { player_node->raiseAttribute(LocalPlayer::INT); - } if (event.getId() == "DEX") - { player_node->raiseAttribute(LocalPlayer::DEX); - } if (event.getId() == "LUK") - { player_node->raiseAttribute(LocalPlayer::LUK); - } } } diff --git a/src/gui/storagewindow.cpp b/src/gui/storagewindow.cpp index 663ad784..8484093a 100644 --- a/src/gui/storagewindow.cpp +++ b/src/gui/storagewindow.cpp @@ -24,12 +24,11 @@ #include <guichan/font.hpp> #include <guichan/mouseinput.hpp> -#include <guichan/widgets/label.hpp> - #include "button.h" #include "inventorywindow.h" #include "item_amount.h" #include "itemcontainer.h" +#include "label.h" #include "progressbar.h" #include "scrollarea.h" #include "storagewindow.h" @@ -59,11 +58,11 @@ StorageWindow::StorageWindow(Network *network, int invSize): { setWindowName("Storage"); setResizable(true); + setCloseButton(true); // If you adjust these defaults, don't forget to adjust the trade window's. - setDefaultSize(115, 25, 375, 300); + setDefaultSize(375, 300, ImageRect::CENTER); - mCancelButton = new Button(_("Close"), "close", this); mStoreButton = new Button(_("Store"), "store", this); mRetrieveButton = new Button(_("Retrieve"), "retrieve", this); @@ -75,7 +74,7 @@ StorageWindow::StorageWindow(Network *network, int invSize): mUsedSlots = toString(player_node->getStorage()->getNumberOfSlotsUsed()); - mSlotsLabel = new gcn::Label(_("Slots: ")); + mSlotsLabel = new Label(_("Slots: ")); mSlotsBar = new ProgressBar(1.0f, 100, 20, 225, 200, 25); @@ -85,14 +84,12 @@ StorageWindow::StorageWindow(Network *network, int invSize): place(0, 0, mSlotsLabel).setPadding(3); place(1, 0, mSlotsBar, 3); place(0, 1, mInvenScroll, 4, 4); - place(0, 5, mCancelButton); place(2, 5, mStoreButton); place(3, 5, mRetrieveButton); Layout &layout = getLayout(); layout.setRowHeight(0, mStoreButton->getHeight()); - center(); loadWindowState(); } @@ -121,11 +118,7 @@ void StorageWindow::logic() void StorageWindow::action(const gcn::ActionEvent &event) { - if (event.getId() == "close") - { - close(); - } - else if (event.getId() == "store") + if (event.getId() == "store") { if (!inventoryWindow->isVisible()) return; @@ -212,4 +205,4 @@ void StorageWindow::close() { MessageOut outMsg(mNetwork); outMsg.writeInt16(CMSG_CLOSE_STORAGE); -}
\ No newline at end of file +} diff --git a/src/gui/storagewindow.h b/src/gui/storagewindow.h index 35d76ffb..c78d33a7 100644 --- a/src/gui/storagewindow.h +++ b/src/gui/storagewindow.h @@ -26,13 +26,12 @@ #include "../inventory.h" -#include "../net/network.h" - #include <guichan/actionlistener.hpp> #include <guichan/selectionlistener.hpp> class Item; class ItemContainer; +class Network; class ProgressBar; class TextBox; @@ -82,6 +81,10 @@ class StorageWindow : public Window, gcn::ActionListener, */ void removeStore(Item* item, int ammount); + /** + * Closes the Storage Window, as well as telling the server that the + * window has been closed. + */ void close(); private: @@ -90,7 +93,7 @@ class StorageWindow : public Window, gcn::ActionListener, std::string mSlots; std::string mUsedSlots; - gcn::Button *mCancelButton, *mStoreButton, *mRetrieveButton; + gcn::Button *mStoreButton, *mRetrieveButton; gcn::ScrollArea *mInvenScroll; gcn::Label *mSlotsLabel; diff --git a/src/gui/table.cpp b/src/gui/table.cpp index 5fc96dbd..ec5b0480 100644 --- a/src/gui/table.cpp +++ b/src/gui/table.cpp @@ -319,11 +319,19 @@ void GuiTable::draw(gcn::Graphics* graphics) widget->setDimension(bounds); - if (!mLinewiseMode && c == mSelectedColumn && r == mSelectedRow) + graphics->setColor(guiPalette->getColor(Palette::HIGHLIGHT, + (int)(mAlpha * 255.0f))); + + if (mLinewiseMode && r == mSelectedRow && c == 0) + { + graphics->fillRectangle(gcn::Rectangle(0, y_offset, + getWidth(), height)); + } + else if (!mLinewiseMode && + c == mSelectedColumn && r == mSelectedRow) { - graphics->setColor(guiPalette->getColor(Palette::HIGHLIGHT, - (int)(mAlpha * 127.0f))); - graphics->fillRectangle(bounds); + graphics->fillRectangle(gcn::Rectangle(x_offset, y_offset, + width, height)); } graphics->pushClipArea(bounds); @@ -334,14 +342,6 @@ void GuiTable::draw(gcn::Graphics* graphics) x_offset += width; } - if (mLinewiseMode && r == mSelectedRow) - { - graphics->setColor(guiPalette->getColor(Palette::HIGHLIGHT, - (int)(mAlpha * 127.0f))); - graphics->fillRectangle(gcn::Rectangle(0, y_offset, - x_offset, height)); - } - y_offset += height; } diff --git a/src/gui/textfield.cpp b/src/gui/textfield.cpp index 0e839b1f..5c6e4f49 100644 --- a/src/gui/textfield.cpp +++ b/src/gui/textfield.cpp @@ -21,6 +21,7 @@ #include <guichan/font.hpp> +#include "palette.h" #include "sdlinput.h" #include "textfield.h" @@ -54,8 +55,10 @@ TextField::TextField(const std::string& text): int gridy[4] = {0, 3, 28, 31}; int a = 0, x, y; - for (y = 0; y < 3; y++) { - for (x = 0; x < 3; x++) { + for (y = 0; y < 3; y++) + { + for (x = 0; x < 3; x++) + { skin.grid[a] = textbox->getSubImage( gridx[x], gridy[y], gridx[x + 1] - gridx[x] + 1, @@ -76,9 +79,7 @@ TextField::~TextField() instances--; if (instances == 0) - { for_each(skin.grid, skin.grid + 9, dtor<Image*>()); - } } void TextField::draw(gcn::Graphics *graphics) @@ -89,11 +90,11 @@ void TextField::draw(gcn::Graphics *graphics) if (isFocused()) { drawCaret(graphics, - getFont()->getWidth(mText.substr(0, mCaretPosition)) - - mXScroll); + getFont()->getWidth(mText.substr(0, mCaretPosition)) - + mXScroll); } - graphics->setColor(getForegroundColor()); + graphics->setColor(guiPalette->getColor(Palette::TEXT)); graphics->setFont(getFont()); graphics->drawText(mText, 1 - mXScroll, 1); @@ -101,9 +102,7 @@ void TextField::draw(gcn::Graphics *graphics) { mAlpha = config.getValue("guialpha", 0.8); for (int a = 0; a < 9; a++) - { skin.grid[a]->setAlpha(mAlpha); - } } } @@ -121,9 +120,8 @@ void TextField::setNumeric(bool numeric) { mNumeric = numeric; if (!numeric) - { return; - } + const char *text = mText.c_str(); for (const char *textPtr = text; *textPtr; ++textPtr) { @@ -138,18 +136,15 @@ void TextField::setNumeric(bool numeric) int TextField::getValue() const { if (!mNumeric) - { return 0; - } + int value = atoi(mText.c_str()); if (value < mMinimum) - { return mMinimum; - } + if (value > mMaximum) - { return mMaximum; - } + return value; } diff --git a/src/gui/textrenderer.h b/src/gui/textrenderer.h index 0381f766..b69e72a7 100644 --- a/src/gui/textrenderer.h +++ b/src/gui/textrenderer.h @@ -37,7 +37,7 @@ class TextRenderer */ static inline void renderText(gcn::Graphics *graphics, const std::string& text, int x, int y, gcn::Graphics::Alignment align, - const gcn::Color* color, gcn::Font *font, bool outline = false, + const gcn::Color color, gcn::Font *font, bool outline = false, bool shadow = false, int alpha = 255) { graphics->setFont(font); @@ -73,7 +73,7 @@ class TextRenderer graphics->drawText(text, x, y - 1, align); } - graphics->setColor(*color); + graphics->setColor(color); graphics->drawText(text, x, y, align); } }; diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp index 30604d6b..d7554de8 100644 --- a/src/gui/trade.cpp +++ b/src/gui/trade.cpp @@ -21,13 +21,14 @@ #include <sstream> -#include <guichan/widgets/label.hpp> +#include <guichan/font.hpp> #include "button.h" #include "chat.h" #include "inventorywindow.h" #include "item_amount.h" #include "itemcontainer.h" +#include "label.h" #include "scrollarea.h" #include "textfield.h" #include "trade.h" @@ -47,24 +48,25 @@ #include "../utils/stringutils.h" TradeWindow::TradeWindow(Network *network): - Window(_("Trade: You")), + Window("Trade"), mNetwork(network), - mMyInventory(new Inventory(INVENTORY_SIZE)), - mPartnerInventory(new Inventory(INVENTORY_SIZE)) + mMyInventory(new Inventory(INVENTORY_SIZE, 2)), + mPartnerInventory(new Inventory(INVENTORY_SIZE, 2)) { - setWindowName("Trade"); - setDefaultSize(115, 227, 342, 209); + setWindowName(_("Trade")); + setDefaultSize(342, 209, ImageRect::CENTER); setResizable(true); + setCloseButton(true); setMinWidth(342); setMinHeight(209); - mAddButton = new Button(_("Add"), "add", this); - mOkButton = new Button(_("Ok"), "ok", this); - mCancelButton = new Button(_("Cancel"), "cancel", this); - mTradeButton = new Button(_("Trade"), "trade", this); + std::string longestName = getFont()->getWidth(_("OK")) > + getFont()->getWidth(_("Trade")) ? + _("OK") : _("Trade"); - mTradeButton->setEnabled(false); + mAddButton = new Button(_("Add"), "add", this); + mOkButton = new Button(longestName, "ok", this); mMyItemContainer = new ItemContainer(mMyInventory.get(), 2); mMyItemContainer->setWidth(160); @@ -78,8 +80,8 @@ TradeWindow::TradeWindow(Network *network): mPartnerScroll = new ScrollArea(mPartnerItemContainer); - mMoneyLabel = new gcn::Label(strprintf(_("You get %s."), "")); - mMoneyLabel2 = new gcn::Label(_("You give:")); + mMoneyLabel = new Label(strprintf(_("You get %s."), "")); + mMoneyLabel2 = new Label(_("You give:")); mMoneyField = new TextField; mMoneyField->setWidth(50); @@ -91,10 +93,8 @@ TradeWindow::TradeWindow(Network *network): place(0, 0, mMoneyLabel2); place(1, 0, mMoneyField); place = getPlacer(0, 2); - place(0, 0, mAddButton); - place(1, 0, mOkButton); - place(2, 0, mTradeButton); - place(3, 0, mCancelButton); + place(6, 0, mAddButton); + place(7, 0, mOkButton); Layout &layout = getLayout(); layout.extend(0, 2, 2, 1); layout.setRowHeight(1, Layout::AUTO_SET); @@ -102,6 +102,8 @@ TradeWindow::TradeWindow(Network *network): layout.setColWidth(0, Layout::AUTO_SET); layout.setColWidth(1, Layout::AUTO_SET); + mOkButton->setCaption(_("OK")); + loadWindowState(); } @@ -109,14 +111,6 @@ TradeWindow::~TradeWindow() { } -void TradeWindow::widgetResized(const gcn::Event &event) -{ - mMyItemContainer->setWidth(mMyScroll->getWidth()); - mPartnerItemContainer->setWidth(mPartnerScroll->getWidth()); - - Window::widgetResized(event); -} - void TradeWindow::addMoney(int amount) { mMoneyLabel->setCaption(strprintf(_("You get %s."), @@ -166,7 +160,8 @@ void TradeWindow::reset() { mMyInventory->clear(); mPartnerInventory->clear(); - mTradeButton->setEnabled(false); + mOkButton->setCaption(_("OK")); + mOkButton->setActionEventId("ok"); mOkButton->setEnabled(true); mOkOther = false; mOkMe = false; @@ -175,11 +170,6 @@ void TradeWindow::reset() mMoneyField->setText(""); } -void TradeWindow::setTradeButton(bool enabled) -{ - mTradeButton->setEnabled(enabled); -} - void TradeWindow::receivedOk(bool own) { if (own) @@ -187,13 +177,8 @@ void TradeWindow::receivedOk(bool own) mOkMe = true; if (mOkOther) { - mTradeButton->setEnabled(true); - mOkButton->setEnabled(false); - } - else - { - mTradeButton->setEnabled(false); - mOkButton->setEnabled(false); + mOkButton->setCaption(_("Trade")); + mOkButton->setActionEventId("trade"); } } else @@ -201,19 +186,18 @@ void TradeWindow::receivedOk(bool own) mOkOther = true; if (mOkMe) { - mTradeButton->setEnabled(true); - mOkButton->setEnabled(false); - } - else - { - mTradeButton->setEnabled(false); - mOkButton->setEnabled(true); + mOkButton->setCaption(_("Trade")); + mOkButton->setActionEventId("trade"); } } } void TradeWindow::tradeItem(Item *item, int quantity) { + // TODO: Our newer version of eAthena doesn't register this following + // function. Detect the actual server version, and re-enable this + // for that version only. + //addItem(item->getId(), true, quantity, item->isEquipment()); MessageOut outMsg(mNetwork); outMsg.writeInt16(CMSG_TRADE_ITEM_ADD_REQUEST); outMsg.writeInt16(item->getInvIndex()); @@ -251,7 +235,8 @@ void TradeWindow::action(const gcn::ActionEvent &event) if (mMyInventory->contains(item)) { chatWindow->chatLog(_("Failed adding item. You can not " - "overlap one kind of item on the window."), BY_SERVER); + "overlap one kind of item on the window."), + BY_SERVER); return; } @@ -297,3 +282,9 @@ void TradeWindow::action(const gcn::ActionEvent &event) outMsg.writeInt16(CMSG_TRADE_OK); } } + +void TradeWindow::close() +{ + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_TRADE_CANCEL_REQUEST); +} diff --git a/src/gui/trade.h b/src/gui/trade.h index df724038..67138c24 100644 --- a/src/gui/trade.h +++ b/src/gui/trade.h @@ -56,13 +56,6 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener ~TradeWindow(); /** - * Called when resizing the window. - * - * @param event The calling event - */ - void widgetResized(const gcn::Event &event); - - /** * Add money to the trade window. */ void addMoney(int quantity); @@ -93,11 +86,6 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener void increaseQuantity(int index, bool own, int quantity); /** - * Set trade Button disabled - */ - void setTradeButton(bool enabled); - - /** * Player received ok message from server */ void receivedOk(bool own); @@ -118,6 +106,12 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener */ void action(const gcn::ActionEvent &event); + /** + * Closes the Trade Window, as well as telling the server that the + * window has been closed. + */ + void close(); + private: Network *mNetwork; @@ -130,7 +124,7 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener gcn::Label *mMoneyLabel; gcn::Label *mMoneyLabel2; - gcn::Button *mAddButton, *mOkButton, *mCancelButton, *mTradeButton; + gcn::Button *mAddButton, *mOkButton; ScrollArea *mMyScroll, *mPartnerScroll; gcn::TextField *mMoneyField; bool mOkOther, mOkMe; diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp index df0a1f80..295b752e 100644 --- a/src/gui/updatewindow.cpp +++ b/src/gui/updatewindow.cpp @@ -24,13 +24,11 @@ #include <SDL_thread.h> #include <zlib.h> -#include <guichan/widgets/label.hpp> - -// Curl should be included after Guichan to avoid Windows redefinitions #include <curl/curl.h> #include "browserbox.h" #include "button.h" +#include "label.h" #include "progressbar.h" #include "scrollarea.h" #include "updatewindow.h" @@ -109,7 +107,7 @@ UpdaterWindow::UpdaterWindow(const std::string &updateHost, mBrowserBox = new BrowserBox; mScrollArea = new ScrollArea(mBrowserBox); - mLabel = new gcn::Label(_("Connecting...")); + mLabel = new Label(_("Connecting...")); mProgressBar = new ProgressBar(0.0, 310, 20, 168, 116, 31); mCancelButton = new Button(_("Cancel"), "cancel", this); mPlayButton = new Button(_("Play"), "play", this); diff --git a/src/gui/widgets/tab.cpp b/src/gui/widgets/tab.cpp index 3a79dd91..7a2d9ee8 100644 --- a/src/gui/widgets/tab.cpp +++ b/src/gui/widgets/tab.cpp @@ -24,6 +24,8 @@ #include "tab.h" #include "tabbedarea.h" +#include "../palette.h" + #include "../../configuration.h" #include "../../graphics.h" @@ -123,13 +125,17 @@ void Tab::draw(gcn::Graphics *graphics) { mode = TAB_SELECTED; // if tab is selected, it doesnt need to highlight activity - mLabel->setForegroundColor(gcn::Color(0, 0, 0)); + mLabel->setForegroundColor(guiPalette->getColor(Palette::TEXT)); mHighlighted = false; } else if (mHighlighted) { mode = TAB_HIGHLIGHTED; - mLabel->setForegroundColor(gcn::Color(255, 0, 0)); + mLabel->setForegroundColor(guiPalette->getColor(Palette::TAB_HIGHLIGHT)); + } + else + { + mLabel->setForegroundColor(guiPalette->getColor(Palette::TEXT)); } } diff --git a/src/gui/widgets/textpreview.cpp b/src/gui/widgets/textpreview.cpp index 4fcaa4a7..01790a67 100644 --- a/src/gui/widgets/textpreview.cpp +++ b/src/gui/widgets/textpreview.cpp @@ -28,28 +28,54 @@ #include "../textrenderer.h" #include "../truetypefont.h" +#include "../../configuration.h" + +float TextPreview::mAlpha = config.getValue("guialpha", 0.8); + TextPreview::TextPreview(const std::string* text) { mText = text; + mTextAlpha = false; mFont = gui->getFont(); mTextColor = &guiPalette->getColor(Palette::TEXT); mTextBGColor = NULL; mBGColor = &guiPalette->getColor(Palette::BACKGROUND); + mOpaque = false; } void TextPreview::draw(gcn::Graphics* graphics) { - graphics->setColor(*mBGColor); - graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight())); + if (config.getValue("guialpha", 0.8) != mAlpha) + mAlpha = config.getValue("guialpha", 0.8); + + int alpha = (int) (mAlpha * 255.0f); + + if (!mTextAlpha) + alpha = 255; + + if (mOpaque) + { + graphics->setColor(gcn::Color((int) mBGColor->r, + (int) mBGColor->g, + (int) mBGColor->b, + (int)(mAlpha * 255.0f))); + graphics->fillRectangle(gcn::Rectangle(0, 0, getWidth(), getHeight())); + } - if (mTextBGColor && typeid(*mFont) == typeid(TrueTypeFont)) { + if (mTextBGColor && typeid(*mFont) == typeid(TrueTypeFont)) + { TrueTypeFont *font = static_cast<TrueTypeFont*>(mFont); - graphics->setColor(*mTextBGColor); int x = font->getWidth(*mText) + 1 + 2 * ((mOutline || mShadow) ? 1 :0); int y = font->getHeight() + 1 + 2 * ((mOutline || mShadow) ? 1 : 0); + graphics->setColor(gcn::Color((int) mTextBGColor->r, + (int) mTextBGColor->g, + (int) mTextBGColor->b, + (int)(mAlpha * 255.0f))); graphics->fillRectangle(gcn::Rectangle(1, 1, x, y)); } TextRenderer::renderText(graphics, *mText, 2, 2, gcn::Graphics::LEFT, - mTextColor, mFont, mOutline, mShadow); + gcn::Color(mTextColor->r, mTextColor->g, + mTextColor->b, alpha), + mFont, mOutline, mShadow, alpha); } diff --git a/src/gui/widgets/textpreview.h b/src/gui/widgets/textpreview.h index 1c1fa1e4..e7b7db80 100644 --- a/src/gui/widgets/textpreview.h +++ b/src/gui/widgets/textpreview.h @@ -29,7 +29,8 @@ /** * Preview widget for particle colors, etc. */ -class TextPreview : public gcn::Widget { +class TextPreview : public gcn::Widget +{ public: TextPreview(const std::string* text); @@ -44,6 +45,16 @@ class TextPreview : public gcn::Widget { } /** + * Sets the text to use the set alpha value. + * + * @param alpha whether to use alpha values for the text or not + */ + inline void useTextAlpha(bool alpha) + { + mTextAlpha = alpha; + } + + /** * Sets the color the text background is drawn in. This is only the * rectangle directly behind the text, not to full widget. * @@ -101,12 +112,29 @@ class TextPreview : public gcn::Widget { */ void draw(gcn::Graphics *graphics); + /** + * Set opacity for this widget (whether or not to show the background + * color) + * + * @param opaque Whether the widget should be opaque or not + */ + void setOpaque(bool opaque) { mOpaque = opaque; } + + /** + * Gets opacity for this widget (whether or not the background color + * is shown below the widget) + */ + bool isOpaque() { return mOpaque; } + private: gcn::Font *mFont; const std::string* mText; const gcn::Color* mTextColor; const gcn::Color* mBGColor; const gcn::Color* mTextBGColor; + static float mAlpha; + bool mTextAlpha; + bool mOpaque; bool mShadow; bool mOutline; }; diff --git a/src/gui/window.cpp b/src/gui/window.cpp index d4665427..4689c86a 100644 --- a/src/gui/window.cpp +++ b/src/gui/window.cpp @@ -26,6 +26,8 @@ #include <guichan/exception.hpp> #include "gui.h" +#include "palette.h" +#include "skin.h" #include "window.h" #include "windowcontainer.h" @@ -37,16 +39,10 @@ #include "../log.h" #include "../resources/image.h" -#include "../resources/resourcemanager.h" - -#include "../utils/xml.h" ConfigListener *Window::windowConfigListener = 0; -WindowContainer *Window::windowContainer = 0; int Window::instances = 0; int Window::mouseResize = 0; -//ImageRect Window::border; -Image *Window::closeImage = NULL; bool Window::mAlphaChanged = false; class WindowConfigListener : public ConfigListener @@ -67,25 +63,19 @@ Window::Window(const std::string& caption, bool modal, Window *parent, const std mModal(modal), mCloseButton(false), mSticky(false), - mMinWinWidth(100), mDefaultWidth(100), mMaxWinWidth(INT_MAX), - mMinWinHeight(40), mDefaultHeight(40), mMaxWinHeight(INT_MAX), - mDefaultX(100), mDefaultY(100), - mSkin(skin) + mMinWinWidth(100), + mMinWinHeight(40), + mMaxWinWidth(INT_MAX), + mMaxWinHeight(INT_MAX) { logger->log("Window::Window(\"%s\")", caption.c_str()); if (!windowContainer) - { throw GCN_EXCEPTION("Window::Window(): no windowContainer set"); - } - - // Loads the skin - loadSkin(mSkin); - - setGuiAlpha(); if (instances == 0) { + skinLoader = new SkinLoader(); windowConfigListener = new WindowConfigListener; // Send GUI alpha changed for initialization windowConfigListener->optionChanged("guialpha"); @@ -98,6 +88,11 @@ Window::Window(const std::string& caption, bool modal, Window *parent, const std setPadding(3); setTitleBarHeight(20); + // Loads the skin + mSkin = skinLoader->load(skin); + + setGuiAlpha(); + // Add this window to the window container windowContainer->add(this); @@ -116,21 +111,8 @@ Window::Window(const std::string& caption, bool modal, Window *parent, const std Window::~Window() { logger->log("Window::~Window(\"%s\")", getCaption().c_str()); - const std::string &name = mWindowName; - // Saving X, Y and Width and Height for resizables in the config - if (!name.empty() && name != "window") - { - config.setValue(name + "WinX", getX()); - config.setValue(name + "WinY", getY()); - config.setValue(name + "Visible", isVisible()); - - if (mGrip) - { - config.setValue(name + "WinWidth", getWidth()); - config.setValue(name + "WinHeight", getHeight()); - } - } + saveWindowState(); delete mLayout; @@ -145,20 +127,14 @@ Window::~Window() instances--; - // Clean up static resources - for (int i = 0; i < 9; i++) - { - delete border.grid[i]; - border.grid[i] = NULL; - } + mSkin->instances--; if (instances == 0) { + delete skinLoader; config.removeListener("guialpha", windowConfigListener); delete windowConfigListener; windowConfigListener = NULL; - - closeImage->decRef(); } } @@ -174,12 +150,12 @@ void Window::draw(gcn::Graphics *graphics) Graphics *g = static_cast<Graphics*>(graphics); - g->drawImageRect(0, 0, getWidth(), getHeight(), border); + g->drawImageRect(0, 0, getWidth(), getHeight(), mSkin->getBorder()); // Draw title if (mShowTitle) { - g->setColor(gcn::Color(0, 0, 0)); + g->setColor(guiPalette->getColor(Palette::TEXT)); g->setFont(getFont()); g->drawText(getCaption(), 7, 5, gcn::Graphics::LEFT); } @@ -187,8 +163,8 @@ void Window::draw(gcn::Graphics *graphics) // Draw Close Button if (mCloseButton) { - g->drawImage(closeImage, - getWidth() - closeImage->getWidth() - getPadding(), + g->drawImage(mSkin->getCloseImage(), + getWidth() - mSkin->getCloseImage()->getWidth() - getPadding(), getPadding() ); } @@ -196,18 +172,29 @@ void Window::draw(gcn::Graphics *graphics) // Update window alpha values if (mAlphaChanged) { - for_each(border.grid, border.grid + 9, + for_each(mSkin->getBorder().grid, mSkin->getBorder().grid + 9, std::bind2nd(std::mem_fun(&Image::setAlpha), config.getValue("guialpha", 0.8))); - closeImage->setAlpha(config.getValue("guialpha", 0.8)); + mSkin->getCloseImage()->setAlpha(config.getValue("guialpha", 0.8)); } drawChildren(graphics); } void Window::setContentSize(int width, int height) { - setSize(width + 2 * getPadding(), - height + getPadding() + getTitleBarHeight()); + width = width + 2 * getPadding(); + height = height + getPadding() + getTitleBarHeight(); + + if (getMinWidth() > width) + width = getMinWidth(); + else if (getMaxWidth() < width) + width = getMaxWidth(); + if (getMinHeight() > height) + height = getMinHeight(); + else if (getMaxHeight() < height) + height = getMaxHeight(); + + setSize(width, height); } void Window::setLocationRelativeTo(gcn::Widget *widget) @@ -222,14 +209,61 @@ void Window::setLocationRelativeTo(gcn::Widget *widget) getY() + (wy + (widget->getHeight() - getHeight()) / 2 - y)); } +void Window::setLocationRelativeTo(ImageRect::ImagePosition position, + int offsetX, int offsetY) +{ + if (position == ImageRect::UPPER_LEFT) + { + } + else if (position == ImageRect::UPPER_CENTER) + { + offsetX += (graphics->getWidth() - getWidth()) / 2; + } + else if (position == ImageRect::UPPER_RIGHT) + { + offsetX += graphics->getWidth() - getWidth(); + } + else if (position == ImageRect::LEFT) + { + offsetY += (graphics->getHeight() - getHeight()) / 2; + } + else if (position == ImageRect::CENTER) + { + offsetX += (graphics->getWidth() - getWidth()) / 2; + offsetY += (graphics->getHeight() - getHeight()) / 2; + } + else if (position == ImageRect::RIGHT) + { + offsetX += graphics->getWidth() - getWidth(); + offsetY += (graphics->getHeight() - getHeight()) / 2; + } + else if (position == ImageRect::LOWER_LEFT) + { + offsetY += graphics->getHeight() - getHeight(); + } + else if (position == ImageRect::LOWER_CENTER) + { + offsetX += (graphics->getWidth() - getWidth()) / 2; + offsetY += graphics->getHeight() - getHeight(); + } + else if (position == ImageRect::LOWER_RIGHT) + { + offsetX += graphics->getWidth() - getWidth(); + offsetY += graphics->getHeight() - getHeight(); + } + + setPosition(offsetX, offsetY); +} + void Window::setMinWidth(unsigned int width) { - mMinWinWidth = width; + mMinWinWidth = width > mSkin->getMinWidth() ? width : mSkin->getMinWidth(); } void Window::setMinHeight(unsigned int height) { - mMinWinHeight = height; + mMinWinHeight = height > mSkin->getMinHeight() ? + height : mSkin->getMinHeight(); } void Window::setMaxWidth(unsigned int width) @@ -321,14 +355,14 @@ void Window::mousePressed(gcn::MouseEvent &event) if (mCloseButton) { gcn::Rectangle closeButtonRect( - getWidth() - closeImage->getWidth() - getPadding(), + getWidth() - mSkin->getCloseImage()->getWidth() - getPadding(), getPadding(), - closeImage->getWidth(), - closeImage->getHeight()); + mSkin->getCloseImage()->getWidth(), + mSkin->getCloseImage()->getHeight()); if (closeButtonRect.isPointInRect(x, y)) { - setVisible(false); + close(); } } @@ -337,6 +371,11 @@ void Window::mousePressed(gcn::MouseEvent &event) } } +void Window::close() +{ + setVisible(false); +} + void Window::mouseReleased(gcn::MouseEvent &event) { if (mGrip && mouseResize) @@ -392,8 +431,8 @@ void Window::mouseDragged(gcn::MouseEvent &event) { int newX = std::max(0, getX()); int newY = std::max(0, getY()); - newX = std::min(windowContainer->getWidth() - getWidth(), newX); - newY = std::min(windowContainer->getHeight() - getHeight(), newY); + newX = std::min(graphics->getWidth() - getWidth(), newX); + newY = std::min(graphics->getHeight() - getHeight(), newY); setPosition(newX, newY); } @@ -438,13 +477,13 @@ void Window::mouseDragged(gcn::MouseEvent &event) newDim.height += newDim.y; newDim.y = 0; } - if (newDim.x + newDim.width > windowContainer->getWidth()) + if (newDim.x + newDim.width > graphics->getWidth()) { - newDim.width = windowContainer->getWidth() - newDim.x; + newDim.width = graphics->getWidth() - newDim.x; } - if (newDim.y + newDim.height > windowContainer->getHeight()) + if (newDim.y + newDim.height > graphics->getHeight()) { - newDim.height = windowContainer->getHeight() - newDim.y; + newDim.height = graphics->getHeight() - newDim.y; } // Update mouse offset when dragging bottom or right border @@ -473,8 +512,19 @@ void Window::loadWindowState() if (mGrip) { - setSize((int) config.getValue(name + "WinWidth", mDefaultWidth), - (int) config.getValue(name + "WinHeight", mDefaultHeight)); + int width = (int) config.getValue(name + "WinWidth", mDefaultWidth); + int height = (int) config.getValue(name + "WinHeight", mDefaultHeight); + + if (getMinWidth() > width) + width = getMinWidth(); + else if (getMaxWidth() < width) + width = getMaxWidth(); + if (getMinHeight() > height) + height = getMinHeight(); + else if (getMaxHeight() < height) + height = getMaxHeight(); + + setSize(width, height); } else { @@ -482,9 +532,44 @@ void Window::loadWindowState() } } +void Window::saveWindowState() +{ + // Saving X, Y and Width and Height for resizables in the config + if (!mWindowName.empty() && mWindowName != "window") + { + config.setValue(mWindowName + "WinX", getX()); + config.setValue(mWindowName + "WinY", getY()); + config.setValue(mWindowName + "Visible", isVisible()); + + if (mGrip) + { + if (getMinWidth() > getWidth()) + setWidth(getMinWidth()); + else if (getMaxWidth() < getWidth()) + setWidth(getMaxWidth()); + if (getMinHeight() > getHeight()) + setHeight(getMinHeight()); + else if (getMaxHeight() < getHeight()) + setHeight(getMaxHeight()); + + config.setValue(mWindowName + "WinWidth", getWidth()); + config.setValue(mWindowName + "WinHeight", getHeight()); + } + } +} + void Window::setDefaultSize(int defaultX, int defaultY, int defaultWidth, int defaultHeight) { + if (getMinWidth() > defaultWidth) + defaultWidth = getMinWidth(); + else if (getMaxWidth() < defaultWidth) + defaultWidth = getMaxWidth(); + if (getMinHeight() > defaultHeight) + defaultHeight = getMinHeight(); + else if (getMaxHeight() < defaultHeight) + defaultHeight = getMaxHeight(); + mDefaultX = defaultX; mDefaultY = defaultY; mDefaultWidth = defaultWidth; @@ -499,10 +584,63 @@ void Window::setDefaultSize() mDefaultHeight = getHeight(); } -void Window::resetToDefaultSize(bool changePosition) +void Window::setDefaultSize(int defaultWidth, int defaultHeight, + ImageRect::ImagePosition position, + int offsetX, int offsetY) +{ + int x = 0, y = 0; + + if (position == ImageRect::UPPER_LEFT) + { + } + else if (position == ImageRect::UPPER_CENTER) + { + x = (graphics->getWidth() - defaultWidth) / 2; + } + else if (position == ImageRect::UPPER_RIGHT) + { + x = graphics->getWidth() - defaultWidth; + } + else if (position == ImageRect::LEFT) + { + y = (graphics->getHeight() - defaultHeight) / 2; + } + else if (position == ImageRect::CENTER) + { + x = (graphics->getWidth() - defaultWidth) / 2; + y = (graphics->getHeight() - defaultHeight) / 2; + } + else if (position == ImageRect::RIGHT) + { + x = graphics->getWidth() - defaultWidth; + y = (graphics->getHeight() - defaultHeight) / 2; + } + else if (position == ImageRect::LOWER_LEFT) + { + y = graphics->getHeight() - defaultHeight; + } + else if (position == ImageRect::LOWER_CENTER) + { + x = (graphics->getWidth() - defaultWidth) / 2; + y = graphics->getHeight() - defaultHeight; + } + else if (position == ImageRect::LOWER_RIGHT) + { + x = graphics->getWidth() - defaultWidth; + y = graphics->getHeight() - defaultHeight; + } + + mDefaultX = x - offsetX; + mDefaultY = y - offsetY; + mDefaultWidth = defaultWidth; + mDefaultHeight = defaultHeight; +} + +void Window::resetToDefaultSize() { - if (changePosition) setPosition(mDefaultX, mDefaultY); + setPosition(mDefaultX, mDefaultY); setSize(mDefaultWidth, mDefaultHeight); + saveWindowState(); } int Window::getResizeHandles(gcn::MouseEvent &event) @@ -540,179 +678,16 @@ void Window::setGuiAlpha() for (int i = 0; i < 9; i++) { //logger->log("Window::setGuiAlpha: Border Image (%i)", i); - border.grid[i]->setAlpha(config.getValue("guialpha", 0.8)); + mSkin->getBorder().grid[i]->setAlpha(config.getValue("guialpha", 0.8)); } mAlphaChanged = false; } -void Window::loadSkin(const std::string &filename) +int Window::getGuiAlpha() { - const std::string windowId = Window::getId(); - - ResourceManager *resman = ResourceManager::getInstance(); - - logger->log("Loading Window Skin '%s'.", filename.c_str()); - logger->log("Loading Window ID '%s'.", windowId.c_str()); - - - if (filename.empty()) - logger->error("Window::loadSkin(): Invalid File Name."); - - // TODO: - // If there is an error loading the specified file, we should try to revert - // to a 'default' skin file. Only if the 'default' skin file can't be loaded - // should we have a terminating error. - XML::Document doc(filename); - xmlNodePtr rootNode = doc.rootNode(); - - if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "skinset")) - { - logger->error("Widget Skinning error"); - } - - std::string skinSetImage; - skinSetImage = XML::getProperty(rootNode, "image", ""); - Image *dBorders = NULL; - if (!skinSetImage.empty()) - { - logger->log("Window::loadSkin(): <skinset> defines '%s' as a skin image.", skinSetImage.c_str()); - dBorders = resman->getImage("graphics/gui/" + skinSetImage);//"graphics/gui/speech_bubble.png"); - } - else - { - logger->error("Window::loadSkin(): Skinset does not define an image!"); - } - - //iterate <widget>'s - for_each_xml_child_node(widgetNode, rootNode) - { - if (!xmlStrEqual(widgetNode->name, BAD_CAST "widget")) - continue; - - std::string widgetType; - widgetType = XML::getProperty(widgetNode, "type", "unknown"); - if (widgetType == "Window") - { - // Iterate through <part>'s - // LEEOR / TODO: - // We need to make provisions to load in a CloseButton image. For now it - // can just be hard-coded. - for_each_xml_child_node(partNode, widgetNode) - { - if (!xmlStrEqual(partNode->name, BAD_CAST "part")) - { - continue; - } - - std::string partType; - partType = XML::getProperty(partNode, "type", "unknown"); - // TOP ROW - if (partType == "top-left-corner") - { - const int xPos = XML::getProperty(partNode, "xpos", 0); - const int yPos = XML::getProperty(partNode, "ypos", 0); - const int width = XML::getProperty(partNode, "width", 1); - const int height = XML::getProperty(partNode, "height", 1); - - border.grid[0] = dBorders->getSubImage(xPos, yPos, width, height); - } - else if (partType == "top-edge") - { - const int xPos = XML::getProperty(partNode, "xpos", 0); - const int yPos = XML::getProperty(partNode, "ypos", 0); - const int width = XML::getProperty(partNode, "width", 1); - const int height = XML::getProperty(partNode, "height", 1); - - border.grid[1] = dBorders->getSubImage(xPos, yPos, width, height); - } - else if (partType == "top-right-corner") - { - const int xPos = XML::getProperty(partNode, "xpos", 0); - const int yPos = XML::getProperty(partNode, "ypos", 0); - const int width = XML::getProperty(partNode, "width", 1); - const int height = XML::getProperty(partNode, "height", 1); - - border.grid[2] = dBorders->getSubImage(xPos, yPos, width, height); - } - - // MIDDLE ROW - else if (partType == "left-edge") - { - const int xPos = XML::getProperty(partNode, "xpos", 0); - const int yPos = XML::getProperty(partNode, "ypos", 0); - const int width = XML::getProperty(partNode, "width", 1); - const int height = XML::getProperty(partNode, "height", 1); - - border.grid[3] = dBorders->getSubImage(xPos, yPos, width, height); - } - else if (partType == "bg-quad") - { - const int xPos = XML::getProperty(partNode, "xpos", 0); - const int yPos = XML::getProperty(partNode, "ypos", 0); - const int width = XML::getProperty(partNode, "width", 1); - const int height = XML::getProperty(partNode, "height", 1); - - border.grid[4] = dBorders->getSubImage(xPos, yPos, width, height); - } - else if (partType == "right-edge") - { - const int xPos = XML::getProperty(partNode, "xpos", 0); - const int yPos = XML::getProperty(partNode, "ypos", 0); - const int width = XML::getProperty(partNode, "width", 1); - const int height = XML::getProperty(partNode, "height", 1); - - border.grid[5] = dBorders->getSubImage(xPos, yPos, width, height); - } - - // BOTTOM ROW - else if (partType == "bottom-left-corner") - { - const int xPos = XML::getProperty(partNode, "xpos", 0); - const int yPos = XML::getProperty(partNode, "ypos", 0); - const int width = XML::getProperty(partNode, "width", 1); - const int height = XML::getProperty(partNode, "height", 1); - - border.grid[6] = dBorders->getSubImage(xPos, yPos, width, height); - } - else if (partType == "bottom-edge") - { - const int xPos = XML::getProperty(partNode, "xpos", 0); - const int yPos = XML::getProperty(partNode, "ypos", 0); - const int width = XML::getProperty(partNode, "width", 1); - const int height = XML::getProperty(partNode, "height", 1); - - border.grid[7] = dBorders->getSubImage(xPos, yPos, width, height); - } - else if (partType == "bottom-right-corner") - { - const int xPos = XML::getProperty(partNode, "xpos", 0); - const int yPos = XML::getProperty(partNode, "ypos", 0); - const int width = XML::getProperty(partNode, "width", 1); - const int height = XML::getProperty(partNode, "height", 1); - - border.grid[8] = dBorders->getSubImage(xPos, yPos, width, height); - } - - // Part is of an uknown type. - else - { - logger->log("Window::loadSkin(): Unknown Part Type '%s'", partType.c_str()); - } - } - } - // Widget is of an uknown type. - else - { - logger->log("Window::loadSkin(): Unknown Widget Type '%s'", widgetType.c_str()); - } - } - dBorders->decRef(); - - logger->log("Finished loading Window Skin."); - - // Hard-coded for now until we update the above code to look for window buttons. - closeImage = resman->getImage("graphics/gui/close_button.png"); + float alpha = config.getValue("guialpha", 0.8); + return (int) (alpha * 255.0f); } Layout &Window::getLayout() diff --git a/src/gui/window.h b/src/gui/window.h index 95fe2174..7f15e262 100644 --- a/src/gui/window.h +++ b/src/gui/window.h @@ -31,11 +31,11 @@ class ConfigListener; class ContainerPlacer; -class Image; -class ImageRect; class Layout; class LayoutCell; class ResizeGrip; +class Skin; +class SkinLoader; class WindowContainer; /** @@ -61,7 +61,7 @@ class Window : public gcn::Window, gcn::WidgetListener * @param skin The location where the window's skin XML can be found. */ Window(const std::string &caption = "Window", bool modal = false, - Window *parent = NULL, const std::string &skin = "graphics/gui/gui.xml"); + Window *parent = NULL, const std::string &skin = "graphics/gui/gui.xml"); /** * Destructor. Deletes all the added widgets. @@ -89,6 +89,12 @@ class Window : public gcn::Window, gcn::WidgetListener void setLocationRelativeTo(gcn::Widget *widget); /** + * Sets the location relative to the given enumerated position. + */ + void setLocationRelativeTo(ImageRect::ImagePosition position, + int offsetX = 0, int offsetY = 0); + + /** * Sets whether or not the window can be resized. */ void setResizable(bool resize); @@ -151,8 +157,7 @@ class Window : public gcn::Window, gcn::WidgetListener /** * Sets flag to show a title or not. */ - void setShowTitle(bool flag) - { mShowTitle = flag; } + void setShowTitle(bool flag) { mShowTitle = flag; } /** * Sets whether the window is sticky. A sticky window will not have @@ -233,6 +238,12 @@ class Window : public gcn::Window, gcn::WidgetListener void loadWindowState(); /** + * Saves the window state so that when the window is reloaded, it'll + * maintain its previous state and location. + */ + void saveWindowState(); + + /** * Set the default win pos and size. * (which can be different of the actual ones.) */ @@ -245,10 +256,20 @@ class Window : public gcn::Window, gcn::WidgetListener void setDefaultSize(); /** + * Set the default win pos and size. + * (which can be different of the actual ones.) + * This version of setDefaultSize sets the window's position based + * on a relative enumerated position, rather than a coordinate position. + */ + void setDefaultSize(int defaultWidth, int defaultHeight, + ImageRect::ImagePosition position, + int offsetx = 0, int offsetY = 0); + + /** * Reset the win pos and size to default. Don't forget to set defaults * first. */ - void resetToDefaultSize(bool changePosition = true); + virtual void resetToDefaultSize(); /** * Gets the layout handler for this window. @@ -266,11 +287,6 @@ class Window : public gcn::Window, gcn::WidgetListener void reflowLayout(int w = 0, int h = 0); /** - * Loads a window skin - */ - void loadSkin(const std::string &filename); - - /** * Adds a widget to the window and sets it at given cell. */ LayoutCell &place(int x, int y, gcn::Widget *, int w = 1, int h = 1); @@ -285,9 +301,17 @@ class Window : public gcn::Window, gcn::WidgetListener */ void center(); - protected: - /** The window container windows add themselves to. */ - static WindowContainer *windowContainer; + /** + * Overrideable functionality for when the window is to close. This + * allows for class implementations to clean up or do certain actions + * on window close they couldn't do otherwise. + */ + virtual void close(); + + /** + * Gets the alpha value used by the window, in a GUIChan usable format. + */ + int getGuiAlpha(); private: enum ResizeHandles @@ -326,7 +350,6 @@ class Window : public gcn::Window, gcn::WidgetListener int mDefaultY; /**< Default window Y position */ int mDefaultWidth; /**< Default window width */ int mDefaultHeight; /**< Default window height */ - std::string mSkin; /**< Name of the skin to use */ /** * The config listener that listens to changes relevant to all windows. @@ -335,8 +358,8 @@ class Window : public gcn::Window, gcn::WidgetListener static int mouseResize; /**< Active resize handles */ static int instances; /**< Number of Window instances */ - ImageRect border; /**< The window border and background */ - static Image *closeImage; /**< Close Button Image */ + + Skin* mSkin; /**< Skin in use by this window */ /** * The width of the resize border. Is independent of the actual window diff --git a/src/gui/windowcontainer.cpp b/src/gui/windowcontainer.cpp index 2846b1c1..eda739b9 100644 --- a/src/gui/windowcontainer.cpp +++ b/src/gui/windowcontainer.cpp @@ -23,6 +23,8 @@ #include "../utils/dtor.h" +WindowContainer *windowContainer = NULL; + void WindowContainer::logic() { delete_all(mDeathList); diff --git a/src/gui/windowcontainer.h b/src/gui/windowcontainer.h index 62704d1b..bc918184 100644 --- a/src/gui/windowcontainer.h +++ b/src/gui/windowcontainer.h @@ -45,6 +45,11 @@ class WindowContainer : public gcn::Container */ void scheduleDelete(gcn::Widget *widget); + /** + * Get the number of widget instances + */ + int getNumberOfInstances() { return mDeathList.size(); } + private: /** * List of widgets that are scheduled to be deleted. @@ -54,4 +59,6 @@ class WindowContainer : public gcn::Container Widgets mDeathList; }; +extern WindowContainer* windowContainer; + #endif |