summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/box.cpp42
-rw-r--r--src/gui/box.h58
-rw-r--r--src/gui/browserbox.cpp148
-rw-r--r--src/gui/browserbox.h2
-rw-r--r--src/gui/buy.cpp111
-rw-r--r--src/gui/buy.h8
-rw-r--r--src/gui/buysell.cpp10
-rw-r--r--src/gui/char_select.cpp120
-rw-r--r--src/gui/char_select.h7
-rw-r--r--src/gui/char_server.cpp8
-rw-r--r--src/gui/chat.cpp215
-rw-r--r--src/gui/chat.h21
-rw-r--r--src/gui/confirm_dialog.cpp5
-rw-r--r--src/gui/connection.cpp6
-rw-r--r--src/gui/equipmentwindow.cpp4
-rw-r--r--src/gui/gui.cpp16
-rw-r--r--src/gui/gui.h3
-rw-r--r--src/gui/hbox.cpp39
-rw-r--r--src/gui/hbox.h33
-rw-r--r--src/gui/help.cpp6
-rw-r--r--src/gui/inttextbox.cpp21
-rw-r--r--src/gui/inttextbox.h4
-rw-r--r--src/gui/inventorywindow.cpp51
-rw-r--r--src/gui/item_amount.cpp89
-rw-r--r--src/gui/itemcontainer.cpp1
-rw-r--r--src/gui/itemshortcutcontainer.cpp1
-rw-r--r--src/gui/login.cpp77
-rw-r--r--src/gui/menuwindow.cpp18
-rw-r--r--src/gui/minimap.cpp4
-rw-r--r--src/gui/npc_text.cpp6
-rw-r--r--src/gui/npclistdialog.cpp8
-rw-r--r--src/gui/ok_dialog.cpp4
-rw-r--r--src/gui/popupmenu.cpp31
-rw-r--r--src/gui/radiobutton.cpp19
-rw-r--r--src/gui/radiobutton.h6
-rw-r--r--src/gui/register.cpp51
-rw-r--r--src/gui/sdlinput.cpp429
-rw-r--r--src/gui/sdlinput.h188
-rw-r--r--src/gui/sell.cpp116
-rw-r--r--src/gui/sell.h5
-rw-r--r--src/gui/setup.cpp18
-rw-r--r--src/gui/setup_audio.cpp8
-rw-r--r--src/gui/setup_joystick.cpp18
-rw-r--r--src/gui/setup_keyboard.cpp12
-rw-r--r--src/gui/setup_players.cpp60
-rw-r--r--src/gui/setup_video.cpp55
-rw-r--r--src/gui/skill.cpp35
-rw-r--r--src/gui/status.cpp88
-rw-r--r--src/gui/textfield.cpp102
-rw-r--r--src/gui/textfield.h5
-rw-r--r--src/gui/trade.cpp47
-rw-r--r--src/gui/truetypefont.cpp9
-rw-r--r--src/gui/truetypefont.h75
-rw-r--r--src/gui/updatewindow.cpp16
-rw-r--r--src/gui/vbox.cpp43
-rw-r--r--src/gui/vbox.h33
-rw-r--r--src/gui/viewport.cpp2
-rw-r--r--src/gui/widgets/layout.cpp327
-rw-r--r--src/gui/widgets/layout.h320
-rw-r--r--src/gui/window.cpp85
-rw-r--r--src/gui/window.h73
61 files changed, 2231 insertions, 1191 deletions
diff --git a/src/gui/box.cpp b/src/gui/box.cpp
deleted file mode 100644
index 59d8c135..00000000
--- a/src/gui/box.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * The Mana World
- * Copyright 2004 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * The Mana World 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.
- *
- * The Mana World 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 The Mana World; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "box.h"
-
-Box::Box():
- padding(0)
-{
- setOpaque(false);
-}
-
-Box::~Box()
-{
-}
-
-unsigned int Box::getPadding()
-{
- return padding;
-}
-
-void Box::setPadding(unsigned int p)
-{
- padding = p;
-}
diff --git a/src/gui/box.h b/src/gui/box.h
deleted file mode 100644
index 46654b48..00000000
--- a/src/gui/box.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * The Mana World
- * Copyright 2004 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * The Mana World 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.
- *
- * The Mana World 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 The Mana World; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#ifndef BOX_H
-#define BOX_H
-
-#include <guichan/widgets/container.hpp>
-
-#include "../guichanfwd.h"
-
-class Box : public gcn::Container
-{
- public:
- /**
- * Returns padding.
- */
- unsigned int getPadding();
-
- /**
- * Sets padding between widgets.
- */
- void setPadding(unsigned int);
-
- protected:
- Box();
- virtual ~Box();
-
- /**
- * Spacing between client widgets.
- */
- unsigned int padding;
-
- virtual void draw(gcn::Graphics *) = 0;
-
- typedef std::list<gcn::Widget*> Widgets;
- typedef Widgets::iterator WidgetIterator;
-};
-
-#endif
diff --git a/src/gui/browserbox.cpp b/src/gui/browserbox.cpp
index 3e446928..03540d31 100644
--- a/src/gui/browserbox.cpp
+++ b/src/gui/browserbox.cpp
@@ -21,11 +21,8 @@
#include <algorithm>
-#include <guichan/graphics.hpp>
-#include <guichan/imagefont.hpp>
-#include <guichan/mouseinput.hpp>
-
#include "browserbox.h"
+
#include "linkhandler.h"
#include "truetypefont.h"
@@ -143,7 +140,7 @@ void BrowserBox::addRow(const std::string &row)
if (mMode == AUTO_WRAP)
{
- unsigned int j, y = 0;
+ unsigned int y = 0;
unsigned int nextChar;
const char *hyphen = "~";
int hyphenWidth = font->getWidth(hyphen);
@@ -152,7 +149,7 @@ void BrowserBox::addRow(const std::string &row)
for (TextRowIterator i = mTextRows.begin(); i != mTextRows.end(); i++)
{
std::string row = *i;
- for (j = 0; j < row.size(); j++)
+ for (unsigned int j = 0; j < row.size(); j++)
{
std::string character = row.substr(j, 1);
x += font->getWidth(character);
@@ -266,7 +263,6 @@ BrowserBox::draw(gcn::Graphics *graphics)
}
}
- unsigned int j;
int x = 0, y = 0;
int wrappedLines = 0;
TrueTypeFont *font = static_cast<TrueTypeFont*>(getFont());
@@ -277,17 +273,45 @@ BrowserBox::draw(gcn::Graphics *graphics)
int selColor = BLACK;
int prevColor = selColor;
std::string row = *(i);
+ bool wrapped = false;
x = 0;
- for (j = 0; j < row.size(); j++)
+ // Check for separator lines
+ if (row.find("---", 0) == 0)
+ {
+ for (x = 0; x < getWidth(); x++)
+ {
+ font->drawString(graphics, "-", x, y);
+ x += font->getWidth("-") - 2;
+ }
+ y += font->getHeight();
+ continue;
+ }
+
+ // TODO: Check if we must take texture size limits into account here
+ // TODO: Check if some of the O(n) calls can be removed
+ for (std::string::size_type start = 0, end = std::string::npos;
+ start != std::string::npos;
+ start = end, end = std::string::npos)
{
- if ( (mUseLinksAndUserColors && (j + 3) <= row.size()) ||
- (!mUseLinksAndUserColors && (j == 0)) )
+ // Wrapped line continuation shall be indented
+ if (wrapped)
+ {
+ y += font->getHeight();
+ x = 15;
+ }
+
+ // "Tokenize" the string at control sequences
+ if (mUseLinksAndUserColors)
+ end = row.find("##", start + 1);
+
+ if (mUseLinksAndUserColors ||
+ (!mUseLinksAndUserColors && (start == 0)))
{
// Check for color change in format "##x", x = [L,P,0..9]
- if ((row.at(j) == '#') && (row.at(j + 1) == '#'))
+ if (row.find("##", start) == start && row.size() > start + 2)
{
- switch (row.at(j + 2))
+ switch (row.at(start + 2))
{
case 'L': // Link color
prevColor = selColor;
@@ -337,72 +361,64 @@ BrowserBox::draw(gcn::Graphics *graphics)
prevColor = selColor;
selColor = BLACK;
}
- j += 3;
-
- if (j == row.size())
- {
- break;
- }
+ start += 3;
}
graphics->setColor(gcn::Color(selColor));
}
- // Check for line separators in format "---"
- if (row == "---")
- {
- for (x = 0; x < getWidth(); x++)
- {
- font->drawString(graphics, "-", x, y);
- x += font->getWidth("-") - 2;
- }
- break;
- }
- // Draw each char
- else
- {
- std::string character = row.substr(j, 1);
- font->drawString(graphics, character, x, y);
- x += font->getWidth(character.c_str());
+ std::string::size_type len =
+ end == std::string::npos ? end : end - start;
+ std::string part = row.substr(start, len);
- // Auto wrap mode
- if (mMode == AUTO_WRAP)
+ // Auto wrap mode
+ if (mMode == AUTO_WRAP &&
+ (x + font->getWidth(part.c_str()) + 10) > getWidth())
+ {
+ bool forced = false;
+ char const *hyphen = "~";
+ int hyphenWidth = font->getWidth(hyphen);
+
+ /* FIXME: This code layout makes it easy to crash remote
+ clients by talking garbage. Forged long utf-8 characters
+ will cause either a buffer underflow in substr or an
+ infinite loop in the main loop. */
+ do
{
- unsigned int nextChar = j + 1;
- const char *hyphen = "~";
- int hyphenWidth = font->getWidth(hyphen);
+ if (!forced)
+ end = row.rfind(" ", end);
- // Wraping between words (at blank spaces)
- if ((nextChar < row.size()) && (row.at(nextChar) == ' '))
+ // Check if we have to (stupidly) force-wrap
+ if (end == std::string::npos || end <= start)
{
- int nextSpacePos = row.find(" ", (nextChar + 1));
- if (nextSpacePos <= 0)
- {
- nextSpacePos = row.size() - 1;
- }
- int nextWordWidth = font->getWidth(
- row.substr(nextChar,
- (nextSpacePos - nextChar)));
-
- if ((x + nextWordWidth + 10) > getWidth())
- {
- x = 15; // Ident in new line
- y += font->getHeight();
- wrappedLines++;
- j++;
- }
+ forced = true;
+ end = row.size();
+ x += hyphenWidth * 2; // Account for the wrap-notifier
+ continue;
}
- // Wrapping looong lines (brutal force)
- else if ((x + 2 * hyphenWidth) > getWidth())
- {
- font->drawString(graphics, hyphen,
- getWidth() - hyphenWidth, y);
- x = 15; // Ident in new line
- y += font->getHeight();
- wrappedLines++;
- }
+ // Skip to the start of the current character
+ while ((row[end] & 192) == 128)
+ end--;
+ end--; // And then to the last byte of the previous one
+
+ part = row.substr(start, end - start + 1);
+ } while ((x + font->getWidth(part.c_str()) + 10) > getWidth());
+
+ if (forced)
+ {
+ x -= hyphenWidth; // Remove the wrap-notifier accounting
+ font->drawString(graphics, hyphen,
+ getWidth() - hyphenWidth, y);
+ end++; // Skip to the next character
}
+ else
+ end += 2; // Skip to after the space
+
+ wrapped = true;
+ wrappedLines++;
}
+ font->drawString(graphics, part, x, y);
+ x += font->getWidth(part.c_str());
}
y += font->getHeight();
setHeight((mTextRows.size() + wrappedLines) * font->getHeight());
diff --git a/src/gui/browserbox.h b/src/gui/browserbox.h
index 465ff497..cb4c23ed 100644
--- a/src/gui/browserbox.h
+++ b/src/gui/browserbox.h
@@ -25,8 +25,8 @@
#include <iosfwd>
#include <vector>
-#include <guichan/widget.hpp>
#include <guichan/mouselistener.hpp>
+#include <guichan/widget.hpp>
#include "../guichanfwd.h"
#include "../main.h"
diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp
index 714f52db..4d028ab3 100644
--- a/src/gui/buy.cpp
+++ b/src/gui/buy.cpp
@@ -29,15 +29,18 @@
#include "shoplistbox.h"
#include "slider.h"
+#include "widgets/layout.h"
+
#include "../npc.h"
#include "../net/messageout.h"
#include "../net/protocol.h"
-#include "../utils/tostring.h"
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
BuyDialog::BuyDialog(Network *network):
- Window("Buy"), mNetwork(network),
+ Window(_("Buy")), mNetwork(network),
mMoney(0), mAmountItems(0), mMaxItems(0)
{
setWindowName("Buy");
@@ -52,17 +55,16 @@ BuyDialog::BuyDialog(Network *network):
mScrollArea = new ScrollArea(mShopItemList);
mSlider = new Slider(1.0);
mQuantityLabel = new gcn::Label("0");
- mMoneyLabel = new gcn::Label("Price : 0 GP / 0 GP");
+ mMoneyLabel = new gcn::Label(strprintf(_("Price: %d GP / Total: %d GP"), 0, 0));
mIncreaseButton = new Button("+", "+", this);
mDecreaseButton = new Button("-", "-", this);
- mBuyButton = new Button("Buy", "buy", this);
- mQuitButton = new Button("Quit", "quit", this);
- mItemDescLabel = new gcn::Label("Description:");
- mItemEffectLabel = new gcn::Label("Effect:");
+ 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"), ""));
mIncreaseButton->setSize(20, 20);
mDecreaseButton->setSize(20, 20);
- mQuantityLabel->setWidth(60);
mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
mIncreaseButton->setEnabled(false);
@@ -70,22 +72,22 @@ BuyDialog::BuyDialog(Network *network):
mBuyButton->setEnabled(false);
mSlider->setEnabled(false);
- mShopItemList->setActionEventId("item");
mSlider->setActionEventId("slider");
-
- mShopItemList->addSelectionListener(this);
mSlider->addActionListener(this);
+ mShopItemList->addSelectionListener(this);
- add(mScrollArea);
- add(mSlider);
- add(mQuantityLabel);
- add(mBuyButton);
- add(mQuitButton);
- add(mIncreaseButton);
- add(mDecreaseButton);
- add(mMoneyLabel);
- add(mItemDescLabel);
- add(mItemEffectLabel);
+ 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);
+ place(0, 5, mDecreaseButton);
+ place(1, 5, mIncreaseButton);
+ place(3, 5, mBuyButton);
+ place(4, 5, mQuitButton);
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, Layout::AUTO_SET);
loadWindowState();
setLocationRelativeTo(getParent());
@@ -159,7 +161,7 @@ void BuyDialog::action(const gcn::ActionEvent &event)
}
// 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 _obivous_ way in C++?
+ // there a better way to ensure this fails in an _obvious_ way in C++?
else if (event.getId() == "buy" && mAmountItems > 0 &&
mAmountItems <= mMaxItems)
{
@@ -191,53 +193,7 @@ void BuyDialog::valueChanged(const gcn::SelectionEvent &event)
mSlider->gcn::Slider::setScale(1, mMaxItems);
}
-void BuyDialog::widgetResized(const gcn::Event &event)
-{
- Window::widgetResized(event);
-
- const gcn::Rectangle &area = getChildrenArea();
- const int width = area.width;
- const int height = area.height;
-
- mDecreaseButton->setPosition(8, height - 8 - mDecreaseButton->getHeight());
- mIncreaseButton->setPosition(
- mDecreaseButton->getX() + mDecreaseButton->getWidth() + 5,
- mDecreaseButton->getY());
-
- mQuitButton->setPosition(
- width - 8 - mQuitButton->getWidth(),
- height - 8 - mQuitButton->getHeight());
- mBuyButton->setPosition(
- mQuitButton->getX() - 5 - mBuyButton->getWidth(),
- mQuitButton->getY());
-
- mItemDescLabel->setDimension(gcn::Rectangle(8,
- mBuyButton->getY() - 5 - mItemDescLabel->getHeight(),
- width - 16,
- mItemDescLabel->getHeight()));
- mItemEffectLabel->setDimension(gcn::Rectangle(8,
- mItemDescLabel->getY() - 5 - mItemEffectLabel->getHeight(),
- width - 16,
- mItemEffectLabel->getHeight()));
- mMoneyLabel->setDimension(gcn::Rectangle(8,
- mItemEffectLabel->getY() - 5 - mMoneyLabel->getHeight(),
- width - 16,
- mMoneyLabel->getHeight()));
-
- mQuantityLabel->setPosition(
- width - mQuantityLabel->getWidth() - 8,
- mMoneyLabel->getY() - 5 - mQuantityLabel->getHeight());
- mSlider->setDimension(gcn::Rectangle(8,
- mQuantityLabel->getY(),
- mQuantityLabel->getX() - 8 - 8,
- 10));
-
- mScrollArea->setDimension(gcn::Rectangle(8, 8, width - 16,
- mSlider->getY() - 5 - 8));
-}
-
-void
-BuyDialog::updateButtonsAndLabels()
+void BuyDialog::updateButtonsAndLabels()
{
const int selectedItem = mShopItemList->getSelected();
int price = 0;
@@ -246,8 +202,10 @@ BuyDialog::updateButtonsAndLabels()
{
const ItemInfo &info = mShopItems->at(selectedItem)->getInfo();
- mItemDescLabel->setCaption("Description: " + info.getDescription());
- mItemEffectLabel->setCaption("Effect: " + info.getEffect());
+ mItemDescLabel->setCaption
+ (strprintf(_("Description: %s"), info.getDescription().c_str()));
+ mItemEffectLabel->setCaption
+ (strprintf(_("Effect: %s"), info.getEffect().c_str()));
int itemPrice = mShopItems->at(selectedItem)->getPrice();
@@ -263,8 +221,8 @@ BuyDialog::updateButtonsAndLabels()
}
else
{
- mItemDescLabel->setCaption("Description:");
- mItemEffectLabel->setCaption("Effect:");
+ mItemDescLabel->setCaption(strprintf(_("Description: %s"), ""));
+ mItemEffectLabel->setCaption(strprintf(_("Effect: %s"), ""));
mMaxItems = 0;
mAmountItems = 0;
}
@@ -276,8 +234,7 @@ BuyDialog::updateButtonsAndLabels()
mSlider->setEnabled(mMaxItems > 1);
// Update quantity and money labels
- mQuantityLabel->setCaption(
- toString(mAmountItems) + " / " + toString(mMaxItems));
- mMoneyLabel->setCaption("Price: " + toString(price) + " GP / "
- + toString(mMoney - price) + " GP" );
+ mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems));
+ mMoneyLabel->setCaption
+ (strprintf(_("Price: %d GP / Total: %d GP"), price, mMoney - price));
}
diff --git a/src/gui/buy.h b/src/gui/buy.h
index 0915385a..329d35ec 100644
--- a/src/gui/buy.h
+++ b/src/gui/buy.h
@@ -93,13 +93,7 @@ class BuyDialog : public Window, public gcn::ActionListener,
/**
* Updates the state of buttons and labels.
*/
- void
- updateButtonsAndLabels();
-
- /**
- * Called whenever the widget changes size.
- */
- void widgetResized(const gcn::Event &event);
+ void updateButtonsAndLabels();
private:
Network *mNetwork;
diff --git a/src/gui/buysell.cpp b/src/gui/buysell.cpp
index 42380882..a8223ca4 100644
--- a/src/gui/buysell.cpp
+++ b/src/gui/buysell.cpp
@@ -25,18 +25,20 @@
#include "../npc.h"
+#include "../utils/gettext.h"
+
BuySellDialog::BuySellDialog():
- Window("Shop")
+ Window(_("Shop"))
{
Button *buyButton = 0;
- const char *buttonNames[] = {
- "Buy", "Sell", "Cancel", 0
+ static const char *buttonNames[] = {
+ N_("Buy"), N_("Sell"), N_("Cancel"), 0
};
int x = 10, y = 10;
for (const char **curBtn = buttonNames; *curBtn; curBtn++)
{
- Button *btn = new Button(*curBtn, *curBtn, this);
+ Button *btn = new Button(gettext(*curBtn), *curBtn, this);
if (!buyButton) buyButton = btn; // For focus request
btn->setPosition(x, y);
add(btn);
diff --git a/src/gui/char_select.cpp b/src/gui/char_select.cpp
index d951f12e..643a598f 100644
--- a/src/gui/char_select.cpp
+++ b/src/gui/char_select.cpp
@@ -31,6 +31,8 @@
#include "playerbox.h"
#include "textfield.h"
+#include "widgets/layout.h"
+
#include "../game.h"
#include "../localplayer.h"
#include "../main.h"
@@ -38,7 +40,8 @@
#include "../net/charserverhandler.h"
#include "../net/messageout.h"
-#include "../utils/tostring.h"
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
#include "../utils/trim.h"
// Defined in main.cpp, used here for setting the char create dialog
@@ -57,8 +60,8 @@ class CharDeleteConfirm : public ConfirmDialog
};
CharDeleteConfirm::CharDeleteConfirm(CharSelectDialog *m):
- ConfirmDialog("Confirm", "Are you sure you want to delete this character?",
- m),
+ ConfirmDialog(_("Confirm Character Delete"),
+ _("Are you sure you want to delete this character?"), m),
master(m)
{
}
@@ -74,55 +77,42 @@ void CharDeleteConfirm::action(const gcn::ActionEvent &event)
CharSelectDialog::CharSelectDialog(Network *network,
LockedArray<LocalPlayer*> *charInfo,
- unsigned char gender):
- Window("Select Character"), mNetwork(network),
+ Gender gender):
+ Window(_("Select Character")), mNetwork(network),
mCharInfo(charInfo), mGender(gender), mCharSelected(false)
{
- mSelectButton = new Button("Ok", "ok", this);
- mCancelButton = new Button("Cancel", "cancel", this);
- mNewCharButton = new Button("New", "new", this);
- mDelCharButton = new Button("Delete", "delete", this);
- mPreviousButton = new Button("Previous", "previous", this);
- mNextButton = new Button("Next", "next", this);
-
- mNameLabel = new gcn::Label("Name");
- mLevelLabel = new gcn::Label("Level");
- mJobLevelLabel = new gcn::Label("Job Level");
- mMoneyLabel = new gcn::Label("Money");
- mPlayerBox = new PlayerBox();
-
- int w = 195;
- int h = 220;
- setContentSize(w, h);
- mPlayerBox->setDimension(gcn::Rectangle(5, 5, w - 10, 90));
- mNameLabel->setDimension(gcn::Rectangle(10, 100, 128, 16));
- mLevelLabel->setDimension(gcn::Rectangle(10, 116, 128, 16));
- mJobLevelLabel->setDimension(gcn::Rectangle(10, 132, 128, 16));
- mMoneyLabel->setDimension(gcn::Rectangle(10, 148, 128, 16));
- mPreviousButton->setPosition(5, 170);
- mNextButton->setPosition(mPreviousButton->getWidth() + 10, 170);
- mNewCharButton->setPosition(5, h - 5 - mNewCharButton->getHeight());
- mDelCharButton->setPosition(
- 5 + mNewCharButton->getWidth() + 5,
- mNewCharButton->getY());
- mCancelButton->setPosition(
- w - 5 - mCancelButton->getWidth(),
- mNewCharButton->getY());
- mSelectButton->setPosition(
- mCancelButton->getX() - 5 - mSelectButton->getWidth(),
- mNewCharButton->getY());
-
- add(mPlayerBox);
- add(mSelectButton);
- add(mCancelButton);
- add(mNewCharButton);
- add(mDelCharButton);
- add(mPreviousButton);
- add(mNextButton);
- add(mNameLabel);
- add(mLevelLabel);
- add(mJobLevelLabel);
- add(mMoneyLabel);
+ mSelectButton = new Button(_("Ok"), "ok", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+ mNewCharButton = new Button(_("New"), "new", this);
+ mDelCharButton = new Button(_("Delete"), "delete", this);
+ mPreviousButton = new Button(_("Previous"), "previous", this);
+ mNextButton = new Button(_("Next"), "next", this);
+
+ 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: %d"), 0));
+
+ // Control that shows the Player
+ mPlayerBox = new PlayerBox;
+ mPlayerBox->setWidth(74);
+
+ ContainerPlacer place;
+ place = getPlacer(0, 0);
+ place(0, 0, mPlayerBox, 1, 6).setPadding(3);
+ place(1, 0, mNameLabel, 3);
+ place(1, 1, mLevelLabel, 3);
+ place(1, 2, mJobLevelLabel, 3);
+ place(1, 3, mMoneyLabel, 3);
+ place(1, 4, mPreviousButton);
+ place(2, 4, mNextButton);
+ place(1, 5, mNewCharButton);
+ place(2, 5, mDelCharButton);
+ place.getCell().matchColWidth(1, 2);
+ place = getPlacer(0, 2);
+ place(0, 0, mSelectButton);
+ place(1, 0, mCancelButton);
+ reflowLayout(265, 0);
setLocationRelativeTo(getParent());
setVisible(true);
@@ -178,10 +168,10 @@ void CharSelectDialog::updatePlayerInfo()
if (pi)
{
- mNameLabel->setCaption(pi->getName());
- mLevelLabel->setCaption("Lvl: " + toString(pi->mLevel));
- mJobLevelLabel->setCaption("Job Lvl: " + toString(pi->mJobLevel));
- mMoneyLabel->setCaption("Gold: " + toString(pi->mGp));
+ mNameLabel->setCaption(strprintf(_("Name: %s"), pi->getName().c_str()));
+ mLevelLabel->setCaption(strprintf(_("Level: %d"), pi->mLevel));
+ mJobLevelLabel->setCaption(strprintf(_("Job Level: %d"), pi->mJobLevel));
+ mMoneyLabel->setCaption(strprintf(_("Gold: %d"), pi->mGp));
if (!mCharSelected)
{
mNewCharButton->setEnabled(false);
@@ -190,10 +180,10 @@ void CharSelectDialog::updatePlayerInfo()
}
}
else {
- mNameLabel->setCaption("Name");
- mLevelLabel->setCaption("Level");
- mJobLevelLabel->setCaption("Job Level");
- mMoneyLabel->setCaption("Money");
+ mNameLabel->setCaption(strprintf(_("Name: %s"), ""));
+ mLevelLabel->setCaption(strprintf(_("Level: %d"), 0));
+ mJobLevelLabel->setCaption(strprintf(_("Job Level: %d"), 0));
+ mMoneyLabel->setCaption(strprintf(_("Money: %d"), 0));
mNewCharButton->setEnabled(true);
mDelCharButton->setEnabled(false);
mSelectButton->setEnabled(false);
@@ -249,23 +239,23 @@ bool CharSelectDialog::selectByName(const std::string &name)
}
CharCreateDialog::CharCreateDialog(Window *parent, int slot, Network *network,
- unsigned char gender):
- Window("Create Character", true, parent), mNetwork(network), mSlot(slot)
+ Gender gender):
+ Window(_("Create Character"), true, parent), mNetwork(network), mSlot(slot)
{
mPlayer = new Player(0, 0, NULL);
mPlayer->setGender(gender);
mPlayer->setHairStyle(rand() % Being::getHairStylesNr(), rand() % Being::getHairColorsNr());
mNameField = new TextField("");
- mNameLabel = new gcn::Label("Name:");
+ mNameLabel = new gcn::Label(_("Name:"));
mNextHairColorButton = new Button(">", "nextcolor", this);
mPrevHairColorButton = new Button("<", "prevcolor", this);
- mHairColorLabel = new gcn::Label("Hair Color:");
+ mHairColorLabel = new gcn::Label(_("Hair Color:"));
mNextHairStyleButton = new Button(">", "nextstyle", this);
mPrevHairStyleButton = new Button("<", "prevstyle", this);
- mHairStyleLabel = new gcn::Label("Hair Style:");
- mCreateButton = new Button("Create", "create", this);
- mCancelButton = new Button("Cancel", "cancel", this);
+ mHairStyleLabel = new gcn::Label(_("Hair Style:"));
+ mCreateButton = new Button(_("Create"), "create", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
mPlayerBox = new PlayerBox(mPlayer);
mNameField->setActionEventId("create");
diff --git a/src/gui/char_select.h b/src/gui/char_select.h
index 0890bea9..22c247b6 100644
--- a/src/gui/char_select.h
+++ b/src/gui/char_select.h
@@ -26,6 +26,7 @@
#include "../guichanfwd.h"
#include "../lockedarray.h"
+#include "../being.h"
#include <guichan/actionlistener.hpp>
@@ -48,7 +49,7 @@ class CharSelectDialog : public Window, public gcn::ActionListener
*/
CharSelectDialog(Network *network,
LockedArray<LocalPlayer*> *charInfo,
- unsigned char gender);
+ Gender gender);
void action(const gcn::ActionEvent &event);
@@ -76,7 +77,7 @@ class CharSelectDialog : public Window, public gcn::ActionListener
PlayerBox *mPlayerBox;
- unsigned char mGender;
+ Gender mGender;
bool mCharSelected;
/**
@@ -102,7 +103,7 @@ class CharCreateDialog : public Window, public gcn::ActionListener
* Constructor.
*/
CharCreateDialog(Window *parent, int slot, Network *network,
- unsigned char gender);
+ Gender gender);
/**
* Destructor.
diff --git a/src/gui/char_server.cpp b/src/gui/char_server.cpp
index ce068ad1..3d3309fb 100644
--- a/src/gui/char_server.cpp
+++ b/src/gui/char_server.cpp
@@ -31,6 +31,8 @@
#include "../net/network.h" // TODO this is just for iptostring, move that?
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
#include "../utils/tostring.h"
extern SERVER_INFO **server_info;
@@ -47,15 +49,15 @@ class ServerListModel : public gcn::ListModel {
};
ServerSelectDialog::ServerSelectDialog(LoginData *loginData, int nextState):
- Window("Select Server"),
+ Window(_("Select Server")),
mLoginData(loginData),
mNextState(nextState)
{
mServerListModel = new ServerListModel();
mServerList = new ListBox(mServerListModel);
ScrollArea *mScrollArea = new ScrollArea(mServerList);
- mOkButton = new Button("OK", "ok", this);
- Button *mCancelButton = new Button("Cancel", "cancel", this);
+ mOkButton = new Button(_("OK"), "ok", this);
+ Button *mCancelButton = new Button(_("Cancel"), "cancel", this);
setContentSize(200, 100);
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
index edde42d0..d61ec021 100644
--- a/src/gui/chat.cpp
+++ b/src/gui/chat.cpp
@@ -23,13 +23,13 @@
#include <sstream>
#include <guichan/focushandler.hpp>
-#include <guichan/key.hpp>
#include "chat.h"
#include "browserbox.h"
#include "chatinput.h"
#include "scrollarea.h"
+#include "sdlinput.h"
#include "windowcontainer.h"
#include "../configuration.h"
@@ -39,6 +39,8 @@
#include "../net/messageout.h"
#include "../net/protocol.h"
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
#include "../utils/trim.h"
ChatWindow::ChatWindow(Network *network):
@@ -91,8 +93,7 @@ void ChatWindow::widgetResized(const gcn::Event &event)
mChatInput->getHeight() - 5);
}
-void
-ChatWindow::chatLog(std::string line, int own)
+void ChatWindow::chatLog(std::string line, int own)
{
// Trim whitespace
trim(line);
@@ -117,11 +118,14 @@ ChatWindow::chatLog(std::string line, int own)
std::string lineColor = "##0"; // Equiv. to BrowserBox::BLACK
switch (own) {
case BY_GM:
- if (tmp.nick.empty())
- tmp.nick = std::string("Global announcement: ");
- else
- tmp.nick = std::string("Global announcement from " + tmp.nick
- + std::string(": "));
+ if (tmp.nick.empty()) {
+ tmp.nick = _("Global announcement:");
+ tmp.nick += " ";
+ } else {
+ tmp.nick = strprintf(_("Global announcement from %s:"),
+ tmp.nick.c_str());
+ tmp.nick += " ";
+ }
lineColor = "##1"; // Equiv. to BrowserBox::RED
break;
case BY_PLAYER:
@@ -133,12 +137,14 @@ ChatWindow::chatLog(std::string line, int own)
lineColor = "##0"; // Equiv. to BrowserBox::BLACK
break;
case BY_SERVER:
- tmp.nick = "Server: ";
+ tmp.nick = _("Server:");
+ tmp.nick += " ";
tmp.text = line;
lineColor = "##7"; // Equiv. to BrowserBox::PINK
break;
case ACT_WHISPER:
- tmp.nick += CAT_WHISPER;
+ tmp.nick = strprintf(_("%s whispers:"), tmp.nick.c_str());
+ tmp.nick += " ";
lineColor = "##3"; // Equiv. to BrowserBox::BLUE
break;
case ACT_IS:
@@ -182,14 +188,12 @@ ChatWindow::chatLog(std::string line, int own)
}
}
-void
-ChatWindow::chatLog(CHATSKILL act)
+void ChatWindow::chatLog(CHATSKILL act)
{
chatLog(const_msg(act), BY_SERVER);
}
-void
-ChatWindow::action(const gcn::ActionEvent &event)
+void ChatWindow::action(const gcn::ActionEvent &event)
{
if (event.getId() == "chatinput")
{
@@ -222,8 +226,7 @@ ChatWindow::action(const gcn::ActionEvent &event)
}
}
-void
-ChatWindow::requestChatFocus()
+void ChatWindow::requestChatFocus()
{
// Make sure chatWindow is visible
if (!isVisible())
@@ -243,19 +246,18 @@ ChatWindow::requestChatFocus()
mChatInput->requestFocus();
}
-bool
-ChatWindow::isInputFocused()
+bool ChatWindow::isInputFocused()
{
return mChatInput->isFocused();
}
-void
-ChatWindow::whisper(const std::string &nick, std::string msg, int prefixlen)
+void ChatWindow::whisper(const std::string &nick, std::string msg,
+ int prefixlen)
{
std::string recvnick = "";
msg.erase(0, prefixlen + 1);
- if (msg.substr(0,1) == "\"")
+ if (msg.substr(0, 1) == "\"")
{
const std::string::size_type pos = msg.find('"', 1);
if (pos != std::string::npos) {
@@ -278,11 +280,12 @@ ChatWindow::whisper(const std::string &nick, std::string msg, int prefixlen)
outMsg.writeString(recvnick, 24);
outMsg.writeString(msg, msg.length());
- chatLog("Whispering to " + recvnick + " : " + msg, BY_PLAYER);
+ chatLog(strprintf(_("Whispering to %s: %s"),
+ recvnick.c_str(), msg.c_str()),
+ BY_PLAYER);
}
-void
-ChatWindow::chatSend(const std::string &nick, std::string msg)
+void ChatWindow::chatSend(const std::string &nick, std::string msg)
{
/* Some messages are managed client side, while others
* require server handling by proper packet. Probably
@@ -350,81 +353,82 @@ ChatWindow::chatSend(const std::string &nick, std::string msg)
whisper(nick, msg, IS_SHORT_WHISPER_LENGTH);
else
{
- chatLog("Unknown command", BY_SERVER);
+ chatLog(_("Unknown command"), BY_SERVER);
}
}
-std::string
-ChatWindow::const_msg(CHATSKILL act)
+std::string ChatWindow::const_msg(CHATSKILL act)
{
std::string msg;
if (act.success == SKILL_FAILED && act.skill == SKILL_BASIC) {
switch (act.bskill) {
- case BSKILL_TRADE :
- msg = "Trade failed!";
+ case BSKILL_TRADE:
+ msg = _("Trade failed!");
break;
- case BSKILL_EMOTE :
- msg = "Emote failed!";
+ case BSKILL_EMOTE:
+ msg = _("Emote failed!");
break;
- case BSKILL_SIT :
- msg = "Sit failed!";
+ case BSKILL_SIT:
+ msg = _("Sit failed!");
break;
- case BSKILL_CREATECHAT :
- msg = "Chat creating failed!";
+ case BSKILL_CREATECHAT:
+ msg = _("Chat creating failed!");
break;
- case BSKILL_JOINPARTY :
- msg = "Could not join party!";
+ case BSKILL_JOINPARTY:
+ msg = _("Could not join party!");
break;
- case BSKILL_SHOUT :
- msg = "Cannot shout!";
+ case BSKILL_SHOUT:
+ msg = _("Cannot shout!");
break;
}
+ msg += " ";
+
switch (act.reason) {
- case RFAIL_SKILLDEP :
- msg += " You have not yet reached a high enough lvl!";
+ case RFAIL_SKILLDEP:
+ msg += _("You have not yet reached a high enough lvl!");
break;
- case RFAIL_INSUFHP :
- msg += " Insufficient HP!";
+ case RFAIL_INSUFHP:
+ msg += _("Insufficient HP!");
break;
- case RFAIL_INSUFSP :
- msg += " Insufficient SP!";
+ case RFAIL_INSUFSP:
+ msg += _("Insufficient SP!");
break;
- case RFAIL_NOMEMO :
- msg += " You have no memos!";
+ case RFAIL_NOMEMO:
+ msg += _("You have no memos!");
break;
- case RFAIL_SKILLDELAY :
- msg += " You cannot do that right now!";
+ case RFAIL_SKILLDELAY:
+ msg += _("You cannot do that right now!");
break;
- case RFAIL_ZENY :
- msg += " Seems you need more Zeny... ;-)";
+ case RFAIL_ZENY:
+ msg += _("Seems you need more Zeny... ;-)");
break;
- case RFAIL_WEAPON :
- msg += " You cannot use this skill with that kind of weapon!";
+ case RFAIL_WEAPON:
+ msg += _("You cannot use this skill with that kind of weapon!");
break;
- case RFAIL_REDGEM :
- msg += " You need another red gem!";
+ case RFAIL_REDGEM:
+ msg += _("You need another red gem!");
break;
- case RFAIL_BLUEGEM :
- msg += " You need another blue gem!";
+ case RFAIL_BLUEGEM:
+ msg += _("You need another blue gem!");
break;
- case RFAIL_OVERWEIGHT :
- msg += " You're carrying to much to do this!";
+ case RFAIL_OVERWEIGHT:
+ msg += _("You're carrying to much to do this!");
break;
- default :
- msg += " Huh? What's that?";
+ default:
+ msg += _("Huh? What's that?");
break;
}
} else {
- switch(act.skill) {
+ switch (act.skill) {
case SKILL_WARP :
- msg = "Warp failed...";
+ msg = _("Warp failed...");
break;
case SKILL_STEAL :
- msg = "Could not steal anything...";
+ msg = _("Could not steal anything...");
break;
case SKILL_ENVENOM :
- msg = "Poison had no effect...";
+ msg = _("Poison had no effect...");
break;
}
}
@@ -432,8 +436,7 @@ ChatWindow::const_msg(CHATSKILL act)
return msg;
}
-void
-ChatWindow::scroll(int amount)
+void ChatWindow::scroll(int amount)
{
if (!isVisible())
return;
@@ -445,10 +448,9 @@ ChatWindow::scroll(int amount)
mTextOutput->showPart(scr);
}
-void
-ChatWindow::keyPressed(gcn::KeyEvent &event)
+void ChatWindow::keyPressed(gcn::KeyEvent &event)
{
- if (event.getKey().getValue() == gcn::Key::DOWN &&
+ if (event.getKey().getValue() == Key::DOWN &&
mCurHist != mHistory.end())
{
// Move forward through the history
@@ -461,7 +463,7 @@ ChatWindow::keyPressed(gcn::KeyEvent &event)
mCurHist = prevHist;
}
}
- else if (event.getKey().getValue() == gcn::Key::UP &&
+ else if (event.getKey().getValue() == Key::UP &&
mCurHist != mHistory.begin() && mHistory.size() > 0)
{
// Move backward through the history
@@ -471,15 +473,13 @@ ChatWindow::keyPressed(gcn::KeyEvent &event)
}
}
-void
-ChatWindow::setInputText(std::string input_str)
+void ChatWindow::setInputText(std::string input_str)
{
mChatInput->setText(input_str + " ");
requestChatFocus();
}
-void
-ChatWindow::setVisible(bool isVisible)
+void ChatWindow::setVisible(bool isVisible)
{
Window::setVisible(isVisible);
@@ -493,67 +493,68 @@ ChatWindow::setVisible(bool isVisible)
void ChatWindow::help(const std::string &msg1, const std::string &msg2)
{
- chatLog("-- Help --", BY_SERVER);
+ chatLog(_("-- Help --"), BY_SERVER);
if (msg1 == "")
{
- chatLog("/announce: Global announcement (GM only)", BY_SERVER);
- chatLog("/clear: Clears this window", BY_SERVER);
- chatLog("/help: Display this help.", BY_SERVER);
- chatLog("/where: Display map name", BY_SERVER);
- chatLog("/whisper <nick> <message>: Sends a private <message>"
- " to <nick>", BY_SERVER);
- chatLog("/w <nick> <message>: Short form for /whisper", BY_SERVER);
- chatLog("/who: Display number of online users", BY_SERVER);
- chatLog("For more information, type /help <command>", BY_SERVER);
+ chatLog(_("/announce: Global announcement (GM only)"), BY_SERVER);
+ chatLog(_("/clear: Clears this window"), BY_SERVER);
+ chatLog(_("/help: Display this help"), BY_SERVER);
+ chatLog(_("/where: Display map name"), BY_SERVER);
+ chatLog(_("/whisper <nick> <message>: Sends a private <message>"
+ " to <nick>"), BY_SERVER);
+ chatLog(_("/w <nick> <message>: Short form for /whisper"), BY_SERVER);
+ chatLog(_("/who: Display number of online users"), BY_SERVER);
+ chatLog(_("For more information, type /help <command>"), BY_SERVER);
return;
}
if (msg1 == "announce")
{
- chatLog("Command: /announce <msg>", BY_SERVER);
- chatLog("*** only available to a GM ***", BY_SERVER);
- chatLog("This command sends the message <msg> to "
- "all players currently online.", BY_SERVER);
+ chatLog(_("Command: /announce <msg>"), BY_SERVER);
+ chatLog(_("*** only available to a GM ***"), BY_SERVER);
+ chatLog(_("This command sends the message <msg> to "
+ "all players currently online."), BY_SERVER);
return;
}
if (msg1 == "clear")
{
- chatLog("Command: /clear", BY_SERVER);
- chatLog("This command clears the chat log of previous chat.",
+ chatLog(_("Command: /clear"), BY_SERVER);
+ chatLog(_("This command clears the chat log of previous chat."),
BY_SERVER);
return;
}
if (msg1 == "help")
{
- chatLog("Command: /help", BY_SERVER);
- chatLog("This command displays a list of all commands available.",
+ chatLog(_("Command: /help"), BY_SERVER);
+ chatLog(_("This command displays a list of all commands available."),
BY_SERVER);
- chatLog("Command: /help <command>", BY_SERVER);
- chatLog("This command displays help on <command>.", BY_SERVER);
+ chatLog(_("Command: /help <command>"), BY_SERVER);
+ chatLog(_("This command displays help on <command>."), BY_SERVER);
return;
}
if (msg1 == "where")
{
- chatLog("Command: /where", BY_SERVER);
- chatLog("This command displays the name of the current map.",
+ chatLog(_("Command: /where"), BY_SERVER);
+ chatLog(_("This command displays the name of the current map."),
BY_SERVER);
return;
}
if (msg1 == "whisper" || msg1 == "w")
{
- chatLog("Command: /whisper <nick> <msg>", BY_SERVER);
- chatLog("Command: /w <nick> <msg>", BY_SERVER);
- chatLog("This command sends the message <msg> to <nick>.", BY_SERVER);
- chatLog("If the <nick> has spaces in it, enclose it in "
- "double quotes (\").", BY_SERVER);
+ chatLog(_("Command: /whisper <nick> <msg>"), BY_SERVER);
+ chatLog(_("Command: /w <nick> <msg>"), BY_SERVER);
+ chatLog(_("This command sends the message <msg> to <nick>."),
+ BY_SERVER);
+ chatLog(_("If the <nick> has spaces in it, enclose it in "
+ "double quotes (\")."), BY_SERVER);
return;
}
if (msg1 == "who")
{
- chatLog("Command: /who", BY_SERVER);
- chatLog("This command displays the number of players currently "
- "online.", BY_SERVER);
+ chatLog(_("Command: /who"), BY_SERVER);
+ chatLog(_("This command displays the number of players currently "
+ "online."), BY_SERVER);
return;
}
- chatLog("Unknown command.", BY_SERVER);
- chatLog("Type /help for a list of commands.", BY_SERVER);
+ chatLog(_("Unknown command."), BY_SERVER);
+ chatLog(_("Type /help for a list of commands."), BY_SERVER);
}
diff --git a/src/gui/chat.h b/src/gui/chat.h
index 09c3712b..dc0d002d 100644
--- a/src/gui/chat.h
+++ b/src/gui/chat.h
@@ -183,20 +183,16 @@ class ChatWindow : public Window, public gcn::ActionListener,
* // for simple message by a user /- message
* chatlog.chat_send("Zaeiru", "Hello to all users on the screen!");
*/
- void
- chatSend(const std::string &nick, std::string msg);
+ void chatSend(const std::string &nick, std::string msg);
/** Called when key is pressed */
- void
- keyPressed(gcn::KeyEvent &event);
+ void keyPressed(gcn::KeyEvent &event);
/** Called to set current text */
- void
- setInputText(std::string input_str);
+ void setInputText(std::string input_str);
/** Override to reset mTmpVisible */
- void
- setVisible(bool visible);
+ void setVisible(bool visible);
/**
* Scrolls the chat window
@@ -205,8 +201,7 @@ class ChatWindow : public Window, public gcn::ActionListener,
* up, positive numbers scroll down. The absolute amount indicates the
* amount of 1/8ths of chat window real estate that should be scrolled.
*/
- void
- scroll(int amount);
+ void scroll(int amount);
/**
* help implements the /help command
@@ -214,15 +209,13 @@ class ChatWindow : public Window, public gcn::ActionListener,
* @param msg1 is the command that the player needs help on
* @param msg2 is the sub-command relating to the command
*/
- void
- help(const std::string &msg1, const std::string &msg2);
+ void help(const std::string &msg1, const std::string &msg2);
private:
Network *mNetwork;
bool mTmpVisible;
- void
- whisper(const std::string &nick, std::string msg, int prefixlen);
+ void whisper(const std::string &nick, std::string msg, int prefixlen);
/** One item in the chat log */
struct CHATLOG
diff --git a/src/gui/confirm_dialog.cpp b/src/gui/confirm_dialog.cpp
index 9ef94f62..5f2b9cb2 100644
--- a/src/gui/confirm_dialog.cpp
+++ b/src/gui/confirm_dialog.cpp
@@ -25,14 +25,15 @@
#include "button.h"
+#include "../utils/gettext.h"
ConfirmDialog::ConfirmDialog(const std::string &title, const std::string &msg,
Window *parent):
Window(title, true, parent)
{
gcn::Label *textLabel = new gcn::Label(msg);
- gcn::Button *yesButton = new Button("Yes", "yes", this);
- gcn::Button *noButton = new Button("No", "no", this);
+ gcn::Button *yesButton = new Button(_("Yes"), "yes", this);
+ gcn::Button *noButton = new Button(_("No"), "no", this);
int w = textLabel->getWidth() + 20;
int inWidth = yesButton->getWidth() + noButton->getWidth() + 5;
diff --git a/src/gui/connection.cpp b/src/gui/connection.cpp
index 8ad3b436..0f43ff14 100644
--- a/src/gui/connection.cpp
+++ b/src/gui/connection.cpp
@@ -30,6 +30,8 @@
#include "../main.h"
+#include "../utils/gettext.h"
+
namespace {
struct ConnectionActionListener : public gcn::ActionListener
{
@@ -42,9 +44,9 @@ ConnectionDialog::ConnectionDialog():
{
setContentSize(200, 100);
- Button *cancelButton = new Button("Cancel", "cancelButton", &listener);
+ 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 gcn::Label(_("Connecting..."));
cancelButton->setPosition(5, 100 - 5 - cancelButton->getHeight());
mProgressBar->setPosition(5, cancelButton->getY() - 25);
diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp
index 762ca8e8..f3a143be 100644
--- a/src/gui/equipmentwindow.cpp
+++ b/src/gui/equipmentwindow.cpp
@@ -31,10 +31,12 @@
#include "../resources/iteminfo.h"
#include "../resources/resourcemanager.h"
+#include "../utils/gettext.h"
#include "../utils/tostring.h"
EquipmentWindow::EquipmentWindow(Equipment *equipment):
- Window("Equipment"), mEquipment(equipment)
+ Window(_("Equipment")),
+ mEquipment(equipment)
{
setWindowName("Equipment");
setCloseButton(true);
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index a65cb0fb..87bab0ea 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -24,12 +24,9 @@
#include <guichan/exception.hpp>
#include <guichan/image.hpp>
#include <guichan/imagefont.hpp>
-#include <SDL/SDL_ttf.h>
-
-// Should stay here because of Guichan being sensitive to headers order
-#include <guichan/sdl/sdlinput.hpp>
#include "focushandler.h"
+#include "sdlinput.h"
#include "truetypefont.h"
#include "viewport.h"
#include "window.h"
@@ -48,7 +45,7 @@
// Guichan stuff
Gui *gui;
Viewport *viewport; /**< Viewport on the map. */
-gcn::SDLInput *guiInput; /**< GUI input. */
+SDLInput *guiInput;
// Fonts used in showing hits
gcn::Font *hitRedFont;
@@ -91,7 +88,7 @@ Gui::Gui(Graphics *graphics):
gcn::Image::setImageLoader(&imageLoader);
// Set input
- guiInput = new gcn::SDLInput();
+ guiInput = new SDLInput;
setInput(guiInput);
// Set focus handler
@@ -106,9 +103,12 @@ Gui::Gui(Graphics *graphics):
Window::setWindowContainer(guiTop);
setTop(guiTop);
- // Set global font (based on ISO-8859-15)
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ // Set global font
+ std::string path = resman->getPath("fonts/dejavusans.ttf");
try {
- mGuiFont = new TrueTypeFont("data/fonts/dejavusans.ttf", 12);
+ mGuiFont = new TrueTypeFont(path, 11);
}
catch (gcn::Exception e)
{
diff --git a/src/gui/gui.h b/src/gui/gui.h
index 15d5d99c..7d390df9 100644
--- a/src/gui/gui.h
+++ b/src/gui/gui.h
@@ -29,6 +29,7 @@
class GuiConfigListener;
class Graphics;
class ImageSet;
+class SDLInput;
class Viewport;
/**
@@ -115,7 +116,7 @@ class Gui : public gcn::Gui
extern Gui *gui; /**< The GUI system */
extern Viewport *viewport; /**< The viewport */
-extern gcn::SDLInput *guiInput; /**< GUI input */
+extern SDLInput *guiInput; /**< GUI input */
/**
* Fonts used in showing hits
diff --git a/src/gui/hbox.cpp b/src/gui/hbox.cpp
deleted file mode 100644
index 020e85c6..00000000
--- a/src/gui/hbox.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * The Mana World
- * Copyright 2004 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * The Mana World 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.
- *
- * The Mana World 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 The Mana World; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "hbox.h"
-
-void HBox::draw(gcn::Graphics *graphics)
-{
- int widgetCount = mWidgets.size();
- int childHeight = getHeight();
- if (widgetCount == 0)
- return;
- int childWidth = getWidth() / widgetCount;
-
- int i = 0;
- for (WidgetIterator w = mWidgets.begin(); w != mWidgets.end(); w++) {
- (*w)->setPosition(childWidth * i - padding, 0);
- (*w)->setSize(childWidth, childHeight);
- i++;
- }
- gcn::Container::draw(graphics);
-}
diff --git a/src/gui/hbox.h b/src/gui/hbox.h
deleted file mode 100644
index 4b241383..00000000
--- a/src/gui/hbox.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * The Mana World
- * Copyright 2004 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * The Mana World 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.
- *
- * The Mana World 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 The Mana World; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef HBOX_H
-#define HBOX_H
-
-#include "box.h"
-
-class HBox : public Box
-{
- public:
- void draw(gcn::Graphics *);
-};
-
-#endif
diff --git a/src/gui/help.cpp b/src/gui/help.cpp
index 290679b9..a52119b8 100644
--- a/src/gui/help.cpp
+++ b/src/gui/help.cpp
@@ -27,8 +27,10 @@
#include "../resources/resourcemanager.h"
+#include "../utils/gettext.h"
+
HelpWindow::HelpWindow():
- Window("Help")
+ Window(_("Help"))
{
setContentSize(455, 350);
setWindowName("Help");
@@ -36,7 +38,7 @@ HelpWindow::HelpWindow():
mBrowserBox = new BrowserBox();
mBrowserBox->setOpaque(false);
mScrollArea = new ScrollArea(mBrowserBox);
- Button *okButton = new Button("Close", "close", this);
+ Button *okButton = new Button(_("Close"), "close", this);
mScrollArea->setDimension(gcn::Rectangle(
5, 5, 445, 335 - okButton->getHeight()));
diff --git a/src/gui/inttextbox.cpp b/src/gui/inttextbox.cpp
index 4825fbf5..a995f084 100644
--- a/src/gui/inttextbox.cpp
+++ b/src/gui/inttextbox.cpp
@@ -21,7 +21,7 @@
#include "inttextbox.h"
-#include <guichan/key.hpp>
+#include "sdlinput.h"
#include "../utils/tostring.h"
@@ -35,17 +35,20 @@ IntTextBox::keyPressed(gcn::KeyEvent &event)
{
const gcn::Key &key = event.getKey();
- if (key.isNumber() || key.getValue() == gcn::Key::BACKSPACE
- || key.getValue() == gcn::Key::DELETE)
+ if (key.getValue() == Key::BACKSPACE ||
+ key.getValue() == Key::DELETE)
{
- gcn::TextBox::keyPressed(event);
+ setText(std::string());
+ event.consume();
}
- std::stringstream s(gcn::TextBox::getText());
+ if (!key.isNumber()) return;
+ TextField::keyPressed(event);
+
+ std::istringstream s(getText());
int i;
s >> i;
- if (gcn::TextBox::getText() != "")
- setInt(i);
+ setInt(i);
}
void IntTextBox::setRange(int min, int max)
@@ -56,9 +59,7 @@ void IntTextBox::setRange(int min, int max)
int IntTextBox::getInt()
{
- if (gcn::TextBox::getText() == "")
- return 0;
- return mValue;
+ return getText().empty() ? mMin : mValue;
}
void IntTextBox::setInt(int i)
diff --git a/src/gui/inttextbox.h b/src/gui/inttextbox.h
index 8fc8e404..8dad0c39 100644
--- a/src/gui/inttextbox.h
+++ b/src/gui/inttextbox.h
@@ -22,12 +22,12 @@
#ifndef INTTEXTBOX_H
#define INTTEXTBOX_H
-#include "textbox.h"
+#include "textfield.h"
/**
* TextBox which only accepts numbers as input.
*/
-class IntTextBox : public TextBox
+class IntTextBox : public TextField
{
public:
/**
diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp
index 0e1c5291..ac368aa7 100644
--- a/src/gui/inventorywindow.cpp
+++ b/src/gui/inventorywindow.cpp
@@ -39,10 +39,11 @@
#include "../resources/iteminfo.h"
-#include "../utils/tostring.h"
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
InventoryWindow::InventoryWindow():
- Window("Inventory")
+ Window(_("Inventory"))
{
setWindowName("Inventory");
setResizable(true);
@@ -52,8 +53,8 @@ InventoryWindow::InventoryWindow():
// If you adjust these defaults, don't forget to adjust the trade window's.
setDefaultSize(115, 25, 322, 200);
- mUseButton = new Button("Use", "use", this);
- mDropButton = new Button("Drop", "drop", this);
+ mUseButton = new Button(_("Use"), "use", this);
+ mDropButton = new Button(_("Drop"), "drop", this);
mItems = new ItemContainer(player_node->getInventory());
mItems->addSelectionListener(this);
@@ -95,15 +96,14 @@ void InventoryWindow::logic()
updateButtons();
// Update weight information
- mWeightLabel->setCaption(
- "Weight: " + toString(player_node->mTotalWeight) +
- "/" + toString(player_node->mMaxWeight));
+ mWeightLabel->setCaption(strprintf(_("Weight: %d / %d"),
+ player_node->mTotalWeight,
+ player_node->mMaxWeight));
// Update number of items in inventory
- mInvenSlotLabel->setCaption(
- "Slots used: "
- + toString(player_node->getInventory()->getNumberOfSlotsUsed())
- + "/" + toString(player_node->getInventory()->getInventorySize()));
+ mInvenSlotLabel->setCaption(strprintf(_("Slots used: %d / %d"),
+ player_node->getInventory()->getNumberOfSlotsUsed(),
+ player_node->getInventory()->getInventorySize()));
}
void InventoryWindow::action(const gcn::ActionEvent &event)
@@ -145,20 +145,20 @@ void InventoryWindow::valueChanged(const gcn::SelectionEvent &event)
// Update name, effect and description
if (!item)
{
- mItemNameLabel->setCaption("Name:");
- mItemEffectLabel->setCaption("Effect:");
- mItemDescriptionLabel->setCaption("Description:");
+ mItemNameLabel->setCaption(strprintf(_("Name: %s"), ""));
+ mItemEffectLabel->setCaption(strprintf(_("Effect: %s"), ""));
+ mItemDescriptionLabel->setCaption(strprintf(_("Description: %s"), ""));
}
else
{
const ItemInfo& itemInfo = item->getInfo();
- std::string SomeText;
- SomeText = "Name: " + itemInfo.getName();
- mItemNameLabel->setCaption(SomeText);
- SomeText = "Effect: " + itemInfo.getEffect();
- mItemEffectLabel->setCaption(SomeText);
- SomeText = "Description: " + itemInfo.getDescription();
- mItemDescriptionLabel->setCaption(SomeText);
+ mItemNameLabel->setCaption(
+ strprintf(_("Name: %s"), itemInfo.getName().c_str()));
+ mItemEffectLabel->setCaption(
+ strprintf(_("Effect: %s"), itemInfo.getEffect().c_str()));
+ mItemDescriptionLabel->setCaption(
+ strprintf(_("Description: %s"),
+ itemInfo.getDescription().c_str()));
}
}
@@ -170,7 +170,8 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event)
{
Item *item = mItems->getSelectedItem();
- if (!item) return;
+ if (!item)
+ return;
/* Convert relative to the window coordinates to absolute screen
* coordinates.
@@ -221,14 +222,14 @@ void InventoryWindow::updateButtons()
if (selectedItem && selectedItem->isEquipment())
{
if (selectedItem->isEquipped()) {
- mUseButton->setCaption("Unequip");
+ mUseButton->setCaption(_("Unequip"));
}
else {
- mUseButton->setCaption("Equip");
+ mUseButton->setCaption(_("Equip"));
}
}
else {
- mUseButton->setCaption("Use");
+ mUseButton->setCaption(_("Use"));
}
mUseButton->setEnabled(selectedItem != 0);
diff --git a/src/gui/item_amount.cpp b/src/gui/item_amount.cpp
index 2e8941e8..17c3243a 100644
--- a/src/gui/item_amount.cpp
+++ b/src/gui/item_amount.cpp
@@ -26,64 +26,64 @@
#include "slider.h"
#include "trade.h"
+#include "widgets/layout.h"
+
#include "../item.h"
#include "../localplayer.h"
+#include "../utils/gettext.h"
+
ItemAmountWindow::ItemAmountWindow(int usage, Window *parent, Item *item):
- Window("Select amount of items to drop.", true, parent),
+ Window("", true, parent),
mItem(item)
{
- // New labels
+ const int maxRange = mItem->getQuantity();
+
+ // Integer field
mItemAmountTextBox = new IntTextBox(1);
+ mItemAmountTextBox->setRange(1, maxRange);
+ mItemAmountTextBox->setWidth(30);
+ mItemAmountTextBox->setActionEventId("Dummy");
+ mItemAmountTextBox->addActionListener(this);
+
+ // Slider
+ mItemAmountSlide = new Slider(1.0, maxRange);
+ mItemAmountSlide->setHeight(10);
+ mItemAmountSlide->setActionEventId("Slide");
+ mItemAmountSlide->addActionListener(this);
- // New buttons
+ // Buttons
Button *minusButton = new Button("-", "Minus", this);
+ minusButton->setSize(20, 20);
Button *plusButton = new Button("+", "Plus", this);
- Button *okButton = new Button("Okay", "Drop", this);
- Button *cancelButton = new Button("Cancel", "Cancel", this);
- mItemAmountSlide = new Slider(1.0, mItem->getQuantity());
-
- mItemAmountTextBox->setRange(1, mItem->getQuantity());
- mItemAmountSlide->setDimension(gcn::Rectangle(5, 120, 180, 10));
-
- // Set button events Id
- mItemAmountSlide->setActionEventId("Slide");
-
- // Set position
- mItemAmountTextBox->setPosition(35, 10);
- mItemAmountTextBox->setSize(24, 16);
- plusButton->setPosition(60, 5);
- minusButton->setPosition(10, 5);
- mItemAmountSlide->setPosition(10, 35);
- okButton->setPosition(10, 50);
- cancelButton->setPosition(60, 50);
-
- // Assemble
- add(mItemAmountTextBox);
- add(plusButton);
- add(minusButton);
- add(mItemAmountSlide);
- add(okButton);
- add(cancelButton);
-
- mItemAmountSlide->addActionListener(this);
+ plusButton->setSize(20, 20);
+ Button *okButton = new Button(_("Ok"), "Drop", this);
+ Button *cancelButton = new Button(_("Cancel"), "Cancel", this);
+
+ // Set positions
+ place(0, 0, minusButton);
+ place(1, 0, mItemAmountTextBox).setPadding(2);
+ place(2, 0, plusButton);
+ place(0, 1, mItemAmountSlide, 6);
+ place(4, 2, okButton);
+ place(5, 2, cancelButton);
+ reflowLayout(250, 0);
resetAmount();
switch (usage) {
case AMOUNT_TRADE_ADD:
- setCaption("Select amount of items to trade.");
+ setCaption(_("Select amount of items to trade."));
okButton->setActionEventId("AddTrade");
break;
case AMOUNT_ITEM_DROP:
- setCaption("Select amount of items to drop.");
+ setCaption(_("Select amount of items to drop."));
okButton->setActionEventId("Drop");
break;
default:
break;
}
- setContentSize(200, 80);
setLocationRelativeTo(getParentWindow());
setVisible(true);
}
@@ -101,16 +101,6 @@ void ItemAmountWindow::action(const gcn::ActionEvent &event)
{
scheduleDelete();
}
- else if (event.getId() == "Drop")
- {
- player_node->dropItem(mItem, mItemAmountTextBox->getInt());
- scheduleDelete();
- }
- else if (event.getId() == "AddTrade")
- {
- tradeWindow->tradeItem(mItem, mItemAmountTextBox->getInt());
- scheduleDelete();
- }
else if (event.getId() == "Plus")
{
amount++;
@@ -123,7 +113,16 @@ void ItemAmountWindow::action(const gcn::ActionEvent &event)
{
amount = static_cast<int>(mItemAmountSlide->getValue());
}
+ else if (event.getId() == "Drop")
+ {
+ player_node->dropItem(mItem, mItemAmountTextBox->getInt());
+ scheduleDelete();
+ }
+ else if (event.getId() == "AddTrade")
+ {
+ tradeWindow->tradeItem(mItem, mItemAmountTextBox->getInt());
+ scheduleDelete();
+ }
mItemAmountTextBox->setInt(amount);
mItemAmountSlide->setValue(amount);
}
-
diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp
index 9115b1fb..65f8132a 100644
--- a/src/gui/itemcontainer.cpp
+++ b/src/gui/itemcontainer.cpp
@@ -115,6 +115,7 @@ void ItemContainer::draw(gcn::Graphics *graphics)
}
// Draw item caption
+ graphics->setColor(gcn::Color(0, 0, 0));
graphics->drawText(
(item->isEquipped() ? "Eq." : toString(item->getQuantity())),
itemX + gridWidth / 2,
diff --git a/src/gui/itemshortcutcontainer.cpp b/src/gui/itemshortcutcontainer.cpp
index 2ea5d584..ac62dbd6 100644
--- a/src/gui/itemshortcutcontainer.cpp
+++ b/src/gui/itemshortcutcontainer.cpp
@@ -75,6 +75,7 @@ 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++)
diff --git a/src/gui/login.cpp b/src/gui/login.cpp
index 06a5f9f0..db81c683 100644
--- a/src/gui/login.cpp
+++ b/src/gui/login.cpp
@@ -34,46 +34,23 @@
#include "passwordfield.h"
#include "textfield.h"
+#include "widgets/layout.h"
+
+#include "../utils/gettext.h"
+
LoginDialog::LoginDialog(LoginData *loginData):
- Window("Login"), mLoginData(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 *userLabel = new gcn::Label(_("Name:"));
+ gcn::Label *passLabel = new gcn::Label(_("Password:"));
+ gcn::Label *serverLabel = new gcn::Label(_("Server:"));
mUserField = new TextField(mLoginData->username);
mPassField = new PasswordField(mLoginData->password);
mServerField = new TextField(mLoginData->hostname);
- mKeepCheck = new CheckBox("Keep", mLoginData->remember);
- mOkButton = new Button("OK", "ok", this);
- mCancelButton = new Button("Cancel", "cancel", this);
- mRegisterButton = new Button("Register", "register", this);
-
- const int width = 220;
- const int height = 100;
-
- setContentSize(width, height);
-
- userLabel->setPosition(5, 5);
- passLabel->setPosition(5, 14 + userLabel->getHeight());
- serverLabel->setPosition(
- 5, 23 + userLabel->getHeight() + passLabel->getHeight());
- mUserField->setPosition(65, 5);
- mPassField->setPosition(65, 14 + userLabel->getHeight());
- mServerField->setPosition(
- 65, 23 + userLabel->getHeight() + passLabel->getHeight());
- mUserField->setWidth(width - 70);
- mPassField->setWidth(width - 70);
- mServerField->setWidth(width - 70);
- mKeepCheck->setPosition(4, 77);
- mCancelButton->setPosition(
- width - mCancelButton->getWidth() - 5,
- height - mCancelButton->getHeight() - 5);
- mOkButton->setPosition(
- mCancelButton->getX() - mOkButton->getWidth() - 5,
- height - mOkButton->getHeight() - 5);
- mRegisterButton->setPosition(
- mKeepCheck->getX() + mKeepCheck->getWidth() + 10,
- height - mRegisterButton->getHeight() - 5);
+ mKeepCheck = new CheckBox(_("Remember Username"), mLoginData->remember);
+ mOkButton = new Button(_("Ok"), "ok", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+ mRegisterButton = new Button(_("Register"), "register", this);
mUserField->setActionEventId("ok");
mPassField->setActionEventId("ok");
@@ -87,16 +64,17 @@ LoginDialog::LoginDialog(LoginData *loginData):
mServerField->addActionListener(this);
mKeepCheck->addActionListener(this);
- add(userLabel);
- add(passLabel);
- add(serverLabel);
- add(mUserField);
- add(mPassField);
- add(mServerField);
- add(mKeepCheck);
- add(mOkButton);
- add(mCancelButton);
- add(mRegisterButton);
+ place(0, 0, userLabel);
+ place(0, 1, passLabel);
+ place(0, 2, serverLabel);
+ place(1, 0, mUserField, 3).setPadding(2);
+ place(1, 1, mPassField, 3).setPadding(2);
+ place(1, 2, mServerField, 3).setPadding(2);
+ place(0, 3, mKeepCheck, 4);
+ place(0, 4, mRegisterButton).setHAlign(LayoutCell::LEFT);
+ place(2, 4, mOkButton);
+ place(3, 4, mCancelButton);
+ reflowLayout(250, 0);
setLocationRelativeTo(getParent());
setVisible(true);
@@ -114,8 +92,7 @@ LoginDialog::~LoginDialog()
{
}
-void
-LoginDialog::action(const gcn::ActionEvent &event)
+void LoginDialog::action(const gcn::ActionEvent &event)
{
if (event.getId() == "ok" && canSubmit())
{
@@ -145,14 +122,12 @@ LoginDialog::action(const gcn::ActionEvent &event)
}
}
-void
-LoginDialog::keyPressed(gcn::KeyEvent &keyEvent)
+void LoginDialog::keyPressed(gcn::KeyEvent &keyEvent)
{
mOkButton->setEnabled(canSubmit());
}
-bool
-LoginDialog::canSubmit()
+bool LoginDialog::canSubmit()
{
return !mUserField->getText().empty() &&
!mPassField->getText().empty() &&
diff --git a/src/gui/menuwindow.cpp b/src/gui/menuwindow.cpp
index 3c3e4ab8..0893cb1c 100644
--- a/src/gui/menuwindow.cpp
+++ b/src/gui/menuwindow.cpp
@@ -28,6 +28,8 @@
#include "button.h"
#include "windowcontainer.h"
+#include "../utils/gettext.h"
+
extern Window *setupWindow;
extern Window *inventoryWindow;
extern Window *equipmentWindow;
@@ -54,21 +56,21 @@ MenuWindow::MenuWindow():
setTitleBarHeight(0);
// Buttons
- const char *buttonNames[] =
+ static const char *buttonNames[] =
{
- "Status",
- "Equipment",
- "Inventory",
- "Skills",
- "Shortcut",
- "Setup",
+ N_("Status"),
+ N_("Equipment"),
+ N_("Inventory"),
+ N_("Skills"),
+ N_("Shortcut"),
+ N_("Setup"),
0
};
int x = 0, h = 0;
for (const char **curBtn = buttonNames; *curBtn; curBtn++)
{
- gcn::Button *btn = new Button(*curBtn, *curBtn, &listener);
+ gcn::Button *btn = new Button(gettext(*curBtn), *curBtn, &listener);
btn->setPosition(x, 0);
add(btn);
x += btn->getWidth() + 3;
diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp
index 231c749f..55132d6d 100644
--- a/src/gui/minimap.cpp
+++ b/src/gui/minimap.cpp
@@ -28,8 +28,10 @@
#include "../resources/image.h"
+#include "../utils/gettext.h"
+
Minimap::Minimap():
- Window("Map"),
+ Window(_("MiniMap")),
mMapImage(NULL)
{
setWindowName("MiniMap");
diff --git a/src/gui/npc_text.cpp b/src/gui/npc_text.cpp
index 34c9cce1..c9ace303 100644
--- a/src/gui/npc_text.cpp
+++ b/src/gui/npc_text.cpp
@@ -29,8 +29,10 @@
#include "../npc.h"
+#include "../utils/gettext.h"
+
NpcTextDialog::NpcTextDialog():
- Window("NPC")
+ Window(_("NPC"))
{
setResizable(true);
@@ -41,7 +43,7 @@ NpcTextDialog::NpcTextDialog():
mTextBox->setEditable(false);
scrollArea = new ScrollArea(mTextBox);
- okButton = new Button("OK", "ok", this);
+ okButton = new Button(_("OK"), "ok", this);
setContentSize(260, 175);
scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
diff --git a/src/gui/npclistdialog.cpp b/src/gui/npclistdialog.cpp
index cdd38312..bff6994d 100644
--- a/src/gui/npclistdialog.cpp
+++ b/src/gui/npclistdialog.cpp
@@ -29,8 +29,10 @@
#include "../npc.h"
+#include "../utils/gettext.h"
+
NpcListDialog::NpcListDialog():
- Window("NPC")
+ Window(_("NPC"))
{
setResizable(true);
@@ -39,8 +41,8 @@ NpcListDialog::NpcListDialog():
mItemList = new ListBox(this);
scrollArea = new ScrollArea(mItemList);
- okButton = new Button("OK", "ok", this);
- cancelButton = new Button("Cancel", "cancel", this);
+ okButton = new Button(_("OK"), "ok", this);
+ cancelButton = new Button(_("Cancel"), "cancel", this);
setContentSize(260, 175);
scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
diff --git a/src/gui/ok_dialog.cpp b/src/gui/ok_dialog.cpp
index d43c8e69..9db3cd7b 100644
--- a/src/gui/ok_dialog.cpp
+++ b/src/gui/ok_dialog.cpp
@@ -24,6 +24,8 @@
#include "button.h"
#include "scrollarea.h"
+#include "../utils/gettext.h"
+
OkDialog::OkDialog(const std::string &title, const std::string &msg,
Window *parent):
Window(title, true, parent)
@@ -32,7 +34,7 @@ OkDialog::OkDialog(const std::string &title, const std::string &msg,
textBox->setEditable(false);
gcn::ScrollArea *scrollArea = new ScrollArea(textBox);
- gcn::Button *okButton = new Button("Ok", "ok", this);
+ gcn::Button *okButton = new Button(_("Ok"), "ok", this);
setContentSize(260, 175);
scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp
index 07719d2c..1f5b3556 100644
--- a/src/gui/popupmenu.cpp
+++ b/src/gui/popupmenu.cpp
@@ -42,6 +42,9 @@
#include "../resources/iteminfo.h"
#include "../resources/itemdb.h"
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
+
extern std::string tradePartnerName;
PopupMenu::PopupMenu():
@@ -52,7 +55,7 @@ PopupMenu::PopupMenu():
{
setResizable(false);
setTitleBarHeight(0);
- mShowTitle = false;
+ setShowTitle(false);
mBrowserBox = new BrowserBox();
mBrowserBox->setPosition(4, 4);
@@ -74,8 +77,10 @@ void PopupMenu::showPopup(int x, int y, Being *being)
// Players can be traded with. Later also attack, follow and
// add as buddy will be options in this menu.
const std::string &name = being->getName();
- mBrowserBox->addRow("@@trade|Trade With " + name + "@@");
- mBrowserBox->addRow("@@attack|Attack " + name + "@@");
+ mBrowserBox->addRow(
+ strprintf(_("@@trade|Trade With %s@@"), name.c_str()));
+ mBrowserBox->addRow(
+ strprintf(_("@@attack|Attack %s@@"), name.c_str()));
mBrowserBox->addRow("##3---");
@@ -106,7 +111,7 @@ void PopupMenu::showPopup(int x, int y, Being *being)
case Being::NPC:
// NPCs can be talked to (single option, candidate for removal
// unless more options would be added)
- mBrowserBox->addRow("@@talk|Talk To NPC@@");
+ mBrowserBox->addRow(_("@@talk|Talk To NPC@@"));
break;
default:
@@ -116,7 +121,7 @@ void PopupMenu::showPopup(int x, int y, Being *being)
//browserBox->addRow("@@look|Look To@@");
mBrowserBox->addRow("##3---");
- mBrowserBox->addRow("@@cancel|Cancel@@");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
showPopup(x, y);
}
@@ -128,11 +133,11 @@ void PopupMenu::showPopup(int x, int y, FloorItem *floorItem)
// Floor item can be picked up (single option, candidate for removal)
std::string name = ItemDB::get(mFloorItem->getItemId()).getName();
- mBrowserBox->addRow("@@pickup|Pick Up " + name + "@@");
+ mBrowserBox->addRow(strprintf(_("@@pickup|Pick Up %s@@"), name.c_str()));
//browserBox->addRow("@@look|Look To@@");
mBrowserBox->addRow("##3---");
- mBrowserBox->addRow("@@cancel|Cancel@@");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
showPopup(x, y);
}
@@ -275,17 +280,17 @@ void PopupMenu::showPopup(int x, int y, Item *item)
if (item->isEquipment())
{
if (item->isEquipped())
- mBrowserBox->addRow("@@use|Unequip@@");
+ mBrowserBox->addRow(_("@@use|Unequip@@"));
else
- mBrowserBox->addRow("@@use|Equip@@");
+ mBrowserBox->addRow(_("@@use|Equip@@"));
}
else
- mBrowserBox->addRow("@@use|Use@@");
+ mBrowserBox->addRow(_("@@use|Use@@"));
- mBrowserBox->addRow("@@drop|Drop@@");
- mBrowserBox->addRow("@@description|Description@@");
+ mBrowserBox->addRow(_("@@drop|Drop@@"));
+ mBrowserBox->addRow(_("@@description|Description@@"));
mBrowserBox->addRow("##3---");
- mBrowserBox->addRow("@@cancel|Cancel@@");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
showPopup(x, y);
}
diff --git a/src/gui/radiobutton.cpp b/src/gui/radiobutton.cpp
index 5f929e62..619ec84f 100644
--- a/src/gui/radiobutton.cpp
+++ b/src/gui/radiobutton.cpp
@@ -81,3 +81,22 @@ void RadioButton::drawBox(gcn::Graphics* graphics)
static_cast<Graphics*>(graphics)->drawImage(box, 2, 2);
}
}
+
+void RadioButton::draw(gcn::Graphics* graphics)
+{
+
+ graphics->pushClipArea(gcn::Rectangle(1,
+ 1,
+ getWidth() - 1,
+ getHeight() - 1));
+
+ drawBox(graphics);
+
+ graphics->popClipArea();
+
+ graphics->setFont(getFont());
+ graphics->setColor(getForegroundColor());
+
+ int h = getHeight() + getHeight() / 2;
+ graphics->drawText(getCaption(), h - 2, 0);
+}
diff --git a/src/gui/radiobutton.h b/src/gui/radiobutton.h
index 6506444f..09f703dc 100644
--- a/src/gui/radiobutton.h
+++ b/src/gui/radiobutton.h
@@ -48,6 +48,12 @@ class RadioButton : public gcn::RadioButton {
*/
void drawBox(gcn::Graphics* graphics);
+ /**
+ * Implementation of the draw methods.
+ * Thus, avoiding the rhomb around the radio button.
+ */
+ void draw(gcn::Graphics* graphics);
+
private:
static int instances;
static Image *radioNormal;
diff --git a/src/gui/register.cpp b/src/gui/register.cpp
index 2a97a3e5..ce36efa2 100644
--- a/src/gui/register.cpp
+++ b/src/gui/register.cpp
@@ -39,6 +39,9 @@
#include "textfield.h"
#include "ok_dialog.h"
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
+
void
WrongDataNoticeListener::setTarget(gcn::TextField *textField)
{
@@ -59,18 +62,18 @@ RegisterDialog::RegisterDialog(LoginData *loginData):
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 *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:"));
mUserField = new TextField(loginData->username);
mPasswordField = new PasswordField(loginData->password);
mConfirmField = new PasswordField();
mServerField = new TextField(loginData->hostname);
- mMaleButton = new RadioButton("Male", "sex", true);
- mFemaleButton = new RadioButton("Female", "sex", false);
- mRegisterButton = new Button("Register", "register", this);
- mCancelButton = new Button("Cancel", "cancel", this);
+ mMaleButton = new RadioButton(_("Male"), "sex", true);
+ mFemaleButton = new RadioButton(_("Female"), "sex", false);
+ mRegisterButton = new Button(_("Register"), "register", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
const int width = 220;
const int height = 150;
@@ -163,45 +166,45 @@ RegisterDialog::action(const gcn::ActionEvent &event)
const std::string user = mUserField->getText();
logger->log("RegisterDialog::register Username is %s", user.c_str());
- std::stringstream errorMsg;
+ std::string errorMsg;
int error = 0;
if (user.length() < LEN_MIN_USERNAME)
{
// Name too short
- errorMsg << "The username needs to be at least "
- << LEN_MIN_USERNAME
- << " characters long.";
+ errorMsg = strprintf
+ (_("The username needs to be at least %d characters long."),
+ LEN_MIN_USERNAME);
error = 1;
}
else if (user.length() > LEN_MAX_USERNAME - 1 )
{
// Name too long
- errorMsg << "The username needs to be less than "
- << LEN_MAX_USERNAME
- << " characters long.";
+ errorMsg = strprintf
+ (_("The username needs to be less than %d characters long."),
+ LEN_MAX_USERNAME);
error = 1;
}
else if (mPasswordField->getText().length() < LEN_MIN_PASSWORD)
{
// Pass too short
- errorMsg << "The password needs to be at least "
- << LEN_MIN_PASSWORD
- << " characters long.";
+ errorMsg = strprintf
+ (_("The password needs to be at least %d characters long."),
+ LEN_MIN_PASSWORD);
error = 2;
}
else if (mPasswordField->getText().length() > LEN_MAX_PASSWORD - 1 )
{
// Pass too long
- errorMsg << "The password needs to be less than "
- << LEN_MAX_PASSWORD
- << " characters long.";
+ errorMsg = strprintf
+ (_("The password needs to be less than %d characters long."),
+ LEN_MAX_PASSWORD);
error = 2;
}
else if (mPasswordField->getText() != mConfirmField->getText())
{
// Password does not match with the confirmation one
- errorMsg << "Passwords do not match.";
+ errorMsg = _("Passwords do not match.");
error = 2;
}
@@ -220,8 +223,8 @@ RegisterDialog::action(const gcn::ActionEvent &event)
mWrongDataNoticeListener->setTarget(this->mPasswordField);
}
- OkDialog *mWrongRegisterNotice = new OkDialog("Error",
- errorMsg.str());
+ OkDialog *mWrongRegisterNotice =
+ new OkDialog(_("Error"), errorMsg);
mWrongRegisterNotice->addActionListener(mWrongDataNoticeListener);
}
else
diff --git a/src/gui/sdlinput.cpp b/src/gui/sdlinput.cpp
new file mode 100644
index 00000000..ee94b2c6
--- /dev/null
+++ b/src/gui/sdlinput.cpp
@@ -0,0 +1,429 @@
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004, 2005, 2006, 2007 Olof Naessén and Per Larsson
+ * Copyright 2007 The Mana World Development Team
+ *
+ * Js_./
+ * Per Larsson a.k.a finalman _RqZ{a<^_aa
+ * Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
+ * _Qhm`] _f "'c 1!5m
+ * Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[
+ * .)j(] .d_/ '-( P . S
+ * License: (BSD) <Td/Z <fP"5(\"??"\a. .L
+ * Redistribution and use in source and _dV>ws?a-?' ._/L #'
+ * binary forms, with or without )4d[#7r, . ' )d`)[
+ * modification, are permitted provided _Q-5'5W..j/?' -?!\)cam'
+ * that the following conditions are met: j<<WP+k/);. _W=j f
+ * 1. Redistributions of source code must .$%w\/]Q . ."' . mj$
+ * retain the above copyright notice, ]E.pYY(Q]>. a J@\
+ * this list of conditions and the j(]1u<sE"L,. . ./^ ]{a
+ * following disclaimer. 4'_uomm\. )L);-4 (3=
+ * 2. Redistributions in binary form must )_]X{Z('a_"a7'<a"a, ]"[
+ * reproduce the above copyright notice, #}<]m7`Za??4,P-"'7. ).m
+ * this list of conditions and the ]d2e)Q(<Q( ?94 b- LQ/
+ * following disclaimer in the <B!</]C)d_, '(<' .f. =C+m
+ * documentation and/or other materials .Z!=J ]e []('-4f _ ) -.)m]'
+ * provided with the distribution. .w[5]' _[ /.)_-"+? _/ <W"
+ * 3. Neither the name of Guichan nor the :$we` _! + _/ . j?
+ * names of its contributors may be used =3)= _f (_yQmWW$#( "
+ * to endorse or promote products derived - W, sQQQQmZQ#Wwa]..
+ * from this software without specific (js, \[QQW$QWW#?!V"".
+ * prior written permission. ]y:.<\.. .
+ * -]n w/ ' [.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT )/ )/ !
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY < (; sac , '
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, ]^ .- %
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF c < r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR aga< <La
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 5% )P'-3L
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR _bQf` y`..)a
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ,J?4P'.P"_(\?d'.,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES _Pa,)!f/<[]/ ?"
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT _2-..:. .r+_,.. .
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ?a.<%"' " -'.a_ _,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ^
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sdlinput.h"
+
+#include <guichan/exception.hpp>
+
+SDLInput::SDLInput()
+{
+ mMouseInWindow = true;
+ mMouseDown = false;
+}
+
+bool SDLInput::isKeyQueueEmpty()
+{
+ return mKeyInputQueue.empty();
+}
+
+gcn::KeyInput SDLInput::dequeueKeyInput()
+{
+ gcn::KeyInput keyInput;
+
+ if (mKeyInputQueue.empty())
+ {
+ throw GCN_EXCEPTION("The queue is empty.");
+ }
+
+ keyInput = mKeyInputQueue.front();
+ mKeyInputQueue.pop();
+
+ return keyInput;
+}
+
+bool SDLInput::isMouseQueueEmpty()
+{
+ return mMouseInputQueue.empty();
+}
+
+gcn::MouseInput SDLInput::dequeueMouseInput()
+{
+ gcn::MouseInput mouseInput;
+
+ if (mMouseInputQueue.empty())
+ {
+ throw GCN_EXCEPTION("The queue is empty.");
+ }
+
+ mouseInput = mMouseInputQueue.front();
+ mMouseInputQueue.pop();
+
+ return mouseInput;
+}
+
+void SDLInput::pushInput(SDL_Event event)
+{
+ gcn::KeyInput keyInput;
+ gcn::MouseInput mouseInput;
+
+ switch (event.type)
+ {
+ case SDL_KEYDOWN:
+ keyInput.setKey(gcn::Key(convertKeyCharacter(event)));
+ keyInput.setType(gcn::KeyInput::PRESSED);
+ keyInput.setShiftPressed(event.key.keysym.mod & KMOD_SHIFT);
+ keyInput.setControlPressed(event.key.keysym.mod & KMOD_CTRL);
+ keyInput.setAltPressed(event.key.keysym.mod & KMOD_ALT);
+ keyInput.setMetaPressed(event.key.keysym.mod & KMOD_META);
+ keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP0
+ && event.key.keysym.sym <= SDLK_KP_EQUALS);
+
+ mKeyInputQueue.push(keyInput);
+ break;
+
+ case SDL_KEYUP:
+ keyInput.setKey(gcn::Key(convertKeyCharacter(event)));
+ keyInput.setType(gcn::KeyInput::RELEASED);
+ keyInput.setShiftPressed(event.key.keysym.mod & KMOD_SHIFT);
+ keyInput.setControlPressed(event.key.keysym.mod & KMOD_CTRL);
+ keyInput.setAltPressed(event.key.keysym.mod & KMOD_ALT);
+ keyInput.setMetaPressed(event.key.keysym.mod & KMOD_META);
+ keyInput.setNumericPad(event.key.keysym.sym >= SDLK_KP0
+ && event.key.keysym.sym <= SDLK_KP_EQUALS);
+
+ mKeyInputQueue.push(keyInput);
+ break;
+
+ case SDL_MOUSEBUTTONDOWN:
+ mMouseDown = true;
+ mouseInput.setX(event.button.x);
+ mouseInput.setY(event.button.y);
+ mouseInput.setButton(convertMouseButton(event.button.button));
+
+ if (event.button.button == SDL_BUTTON_WHEELDOWN)
+ {
+ mouseInput.setType(gcn::MouseInput::WHEEL_MOVED_DOWN);
+ }
+ else if (event.button.button == SDL_BUTTON_WHEELUP)
+ {
+ mouseInput.setType(gcn::MouseInput::WHEEL_MOVED_UP);
+ }
+ else
+ {
+ mouseInput.setType(gcn::MouseInput::PRESSED);
+ }
+ mouseInput.setTimeStamp(SDL_GetTicks());
+ mMouseInputQueue.push(mouseInput);
+ break;
+
+ case SDL_MOUSEBUTTONUP:
+ mMouseDown = false;
+ mouseInput.setX(event.button.x);
+ mouseInput.setY(event.button.y);
+ mouseInput.setButton(convertMouseButton(event.button.button));
+ mouseInput.setType(gcn::MouseInput::RELEASED);
+ mouseInput.setTimeStamp(SDL_GetTicks());
+ mMouseInputQueue.push(mouseInput);
+ break;
+
+ case SDL_MOUSEMOTION:
+ mouseInput.setX(event.button.x);
+ mouseInput.setY(event.button.y);
+ mouseInput.setButton(gcn::MouseInput::EMPTY);
+ mouseInput.setType(gcn::MouseInput::MOVED);
+ mouseInput.setTimeStamp(SDL_GetTicks());
+ mMouseInputQueue.push(mouseInput);
+ break;
+
+ case SDL_ACTIVEEVENT:
+ /*
+ * This occurs when the mouse leaves the window and the Gui-chan
+ * application loses its mousefocus.
+ */
+ if ((event.active.state & SDL_APPMOUSEFOCUS)
+ && !event.active.gain)
+ {
+ mMouseInWindow = false;
+
+ if (!mMouseDown)
+ {
+ mouseInput.setX(-1);
+ mouseInput.setY(-1);
+ mouseInput.setButton(gcn::MouseInput::EMPTY);
+ mouseInput.setType(gcn::MouseInput::MOVED);
+ mMouseInputQueue.push(mouseInput);
+ }
+ }
+
+ if ((event.active.state & SDL_APPMOUSEFOCUS)
+ && event.active.gain)
+ {
+ mMouseInWindow = true;
+ }
+ break;
+
+ } // end switch
+}
+
+int SDLInput::convertMouseButton(int button)
+{
+ switch (button)
+ {
+ case SDL_BUTTON_LEFT:
+ return gcn::MouseInput::LEFT;
+ case SDL_BUTTON_RIGHT:
+ return gcn::MouseInput::RIGHT;
+ case SDL_BUTTON_MIDDLE:
+ return gcn::MouseInput::MIDDLE;
+ default:
+ // We have an unknown mouse type which is ignored.
+ return button;
+ }
+}
+
+int SDLInput::convertKeyCharacter(SDL_Event event)
+{
+ SDL_keysym keysym = event.key.keysym;
+
+ int value = keysym.unicode;
+
+ switch (keysym.sym)
+ {
+ case SDLK_TAB:
+ value = Key::TAB;
+ break;
+ case SDLK_LALT:
+ value = Key::LEFT_ALT;
+ break;
+ case SDLK_RALT:
+ value = Key::RIGHT_ALT;
+ break;
+ case SDLK_LSHIFT:
+ value = Key::LEFT_SHIFT;
+ break;
+ case SDLK_RSHIFT:
+ value = Key::RIGHT_SHIFT;
+ break;
+ case SDLK_LCTRL:
+ value = Key::LEFT_CONTROL;
+ break;
+ case SDLK_RCTRL:
+ value = Key::RIGHT_CONTROL;
+ break;
+ case SDLK_BACKSPACE:
+ value = Key::BACKSPACE;
+ break;
+ case SDLK_PAUSE:
+ value = Key::PAUSE;
+ break;
+ case SDLK_SPACE:
+ // Special characters like ~ (tilde) ends up
+ // with the keysym.sym SDLK_SPACE which
+ // without this check would be lost. The check
+ // is only valid on key down events in SDL.
+ if (event.type == SDL_KEYUP || keysym.unicode == ' ')
+ {
+ value = Key::SPACE;
+ }
+ break;
+ case SDLK_ESCAPE:
+ value = Key::ESCAPE;
+ break;
+ case SDLK_DELETE:
+ value = Key::DELETE;
+ break;
+ case SDLK_INSERT:
+ value = Key::INSERT;
+ break;
+ case SDLK_HOME:
+ value = Key::HOME;
+ break;
+ case SDLK_END:
+ value = Key::END;
+ break;
+ case SDLK_PAGEUP:
+ value = Key::PAGE_UP;
+ break;
+ case SDLK_PRINT:
+ value = Key::PRINT_SCREEN;
+ break;
+ case SDLK_PAGEDOWN:
+ value = Key::PAGE_DOWN;
+ break;
+ case SDLK_F1:
+ value = Key::F1;
+ break;
+ case SDLK_F2:
+ value = Key::F2;
+ break;
+ case SDLK_F3:
+ value = Key::F3;
+ break;
+ case SDLK_F4:
+ value = Key::F4;
+ break;
+ case SDLK_F5:
+ value = Key::F5;
+ break;
+ case SDLK_F6:
+ value = Key::F6;
+ break;
+ case SDLK_F7:
+ value = Key::F7;
+ break;
+ case SDLK_F8:
+ value = Key::F8;
+ break;
+ case SDLK_F9:
+ value = Key::F9;
+ break;
+ case SDLK_F10:
+ value = Key::F10;
+ break;
+ case SDLK_F11:
+ value = Key::F11;
+ break;
+ case SDLK_F12:
+ value = Key::F12;
+ break;
+ case SDLK_F13:
+ value = Key::F13;
+ break;
+ case SDLK_F14:
+ value = Key::F14;
+ break;
+ case SDLK_F15:
+ value = Key::F15;
+ break;
+ case SDLK_NUMLOCK:
+ value = Key::NUM_LOCK;
+ break;
+ case SDLK_CAPSLOCK:
+ value = Key::CAPS_LOCK;
+ break;
+ case SDLK_SCROLLOCK:
+ value = Key::SCROLL_LOCK;
+ break;
+ case SDLK_RMETA:
+ value = Key::RIGHT_META;
+ break;
+ case SDLK_LMETA:
+ value = Key::LEFT_META;
+ break;
+ case SDLK_LSUPER:
+ value = Key::LEFT_SUPER;
+ break;
+ case SDLK_RSUPER:
+ value = Key::RIGHT_SUPER;
+ break;
+ case SDLK_MODE:
+ value = Key::ALT_GR;
+ break;
+ case SDLK_UP:
+ value = Key::UP;
+ break;
+ case SDLK_DOWN:
+ value = Key::DOWN;
+ break;
+ case SDLK_LEFT:
+ value = Key::LEFT;
+ break;
+ case SDLK_RIGHT:
+ value = Key::RIGHT;
+ break;
+ case SDLK_RETURN:
+ value = Key::ENTER;
+ break;
+ case SDLK_KP_ENTER:
+ value = Key::ENTER;
+ break;
+
+ default:
+ break;
+ }
+
+ if (!(keysym.mod & KMOD_NUM))
+ {
+ switch (keysym.sym)
+ {
+ case SDLK_KP0:
+ value = Key::INSERT;
+ break;
+ case SDLK_KP1:
+ value = Key::END;
+ break;
+ case SDLK_KP2:
+ value = Key::DOWN;
+ break;
+ case SDLK_KP3:
+ value = Key::PAGE_DOWN;
+ break;
+ case SDLK_KP4:
+ value = Key::LEFT;
+ break;
+ case SDLK_KP5:
+ value = 0;
+ break;
+ case SDLK_KP6:
+ value = Key::RIGHT;
+ break;
+ case SDLK_KP7:
+ value = Key::HOME;
+ break;
+ case SDLK_KP8:
+ value = Key::UP;
+ break;
+ case SDLK_KP9:
+ value = Key::PAGE_UP;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return value;
+}
diff --git a/src/gui/sdlinput.h b/src/gui/sdlinput.h
new file mode 100644
index 00000000..72d949e1
--- /dev/null
+++ b/src/gui/sdlinput.h
@@ -0,0 +1,188 @@
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004, 2005, 2006, 2007 Olof Naessén and Per Larsson
+ * Copyright 2007 The Mana World Development Team
+ *
+ * Js_./
+ * Per Larsson a.k.a finalman _RqZ{a<^_aa
+ * Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
+ * _Qhm`] _f "'c 1!5m
+ * Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[
+ * .)j(] .d_/ '-( P . S
+ * License: (BSD) <Td/Z <fP"5(\"??"\a. .L
+ * Redistribution and use in source and _dV>ws?a-?' ._/L #'
+ * binary forms, with or without )4d[#7r, . ' )d`)[
+ * modification, are permitted provided _Q-5'5W..j/?' -?!\)cam'
+ * that the following conditions are met: j<<WP+k/);. _W=j f
+ * 1. Redistributions of source code must .$%w\/]Q . ."' . mj$
+ * retain the above copyright notice, ]E.pYY(Q]>. a J@\
+ * this list of conditions and the j(]1u<sE"L,. . ./^ ]{a
+ * following disclaimer. 4'_uomm\. )L);-4 (3=
+ * 2. Redistributions in binary form must )_]X{Z('a_"a7'<a"a, ]"[
+ * reproduce the above copyright notice, #}<]m7`Za??4,P-"'7. ).m
+ * this list of conditions and the ]d2e)Q(<Q( ?94 b- LQ/
+ * following disclaimer in the <B!</]C)d_, '(<' .f. =C+m
+ * documentation and/or other materials .Z!=J ]e []('-4f _ ) -.)m]'
+ * provided with the distribution. .w[5]' _[ /.)_-"+? _/ <W"
+ * 3. Neither the name of Guichan nor the :$we` _! + _/ . j?
+ * names of its contributors may be used =3)= _f (_yQmWW$#( "
+ * to endorse or promote products derived - W, sQQQQmZQ#Wwa]..
+ * from this software without specific (js, \[QQW$QWW#?!V"".
+ * prior written permission. ]y:.<\.. .
+ * -]n w/ ' [.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT )/ )/ !
+ * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY < (; sac , '
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, ]^ .- %
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF c < r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR aga< <La
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 5% )P'-3L
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR _bQf` y`..)a
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ,J?4P'.P"_(\?d'.,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES _Pa,)!f/<[]/ ?"
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT _2-..:. .r+_,.. .
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ?a.<%"' " -'.a_ _,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ^
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _TMW_SDLINPUT_
+#define _TMW_SDLINPUT_
+
+#include <queue>
+
+#include <SDL/SDL.h>
+
+#include <guichan/input.hpp>
+#include <guichan/keyinput.hpp>
+#include <guichan/mouseinput.hpp>
+#include <guichan/platform.hpp>
+
+namespace Key
+{
+ enum
+ {
+ SPACE = ' ',
+ TAB = '\t',
+ ENTER = '\n',
+ // Negative values, to avoid conflicts with higher character codes.
+ LEFT_ALT = -1000,
+ RIGHT_ALT,
+ LEFT_SHIFT,
+ RIGHT_SHIFT,
+ LEFT_CONTROL,
+ RIGHT_CONTROL,
+ LEFT_META,
+ RIGHT_META,
+ LEFT_SUPER,
+ RIGHT_SUPER,
+ INSERT,
+ HOME,
+ PAGE_UP,
+ DELETE,
+ END,
+ PAGE_DOWN,
+ ESCAPE,
+ CAPS_LOCK,
+ BACKSPACE,
+ F1,
+ F2,
+ F3,
+ F4,
+ F5,
+ F6,
+ F7,
+ F8,
+ F9,
+ F10,
+ F11,
+ F12,
+ F13,
+ F14,
+ F15,
+ PRINT_SCREEN,
+ SCROLL_LOCK,
+ PAUSE,
+ NUM_LOCK,
+ ALT_GR,
+ LEFT,
+ RIGHT,
+ UP,
+ DOWN
+ };
+}
+
+/**
+ * SDL implementation of Input.
+ */
+class SDLInput : public gcn::Input
+{
+public:
+
+ /**
+ * Constructor.
+ */
+ SDLInput();
+
+ /**
+ * Pushes an SDL event. It should be called at least once per frame to
+ * update input with user input.
+ *
+ * @param event an event from SDL.
+ */
+ virtual void pushInput(SDL_Event event);
+
+ /**
+ * Polls all input. It exists for input driver compatibility. If you
+ * only use SDL and plan sticking with SDL you can safely ignore this
+ * function as it in the SDL case does nothing.
+ */
+ virtual void _pollInput() { }
+
+
+ // Inherited from Input
+
+ virtual bool isKeyQueueEmpty();
+
+ virtual gcn::KeyInput dequeueKeyInput();
+
+ virtual bool isMouseQueueEmpty();
+
+ virtual gcn::MouseInput dequeueMouseInput();
+
+protected:
+ /**
+ * Converts a mouse button from SDL to a Guichan mouse button
+ * representation.
+ *
+ * @param button an SDL mouse button.
+ * @return a Guichan mouse button.
+ */
+ int convertMouseButton(int button);
+
+ /**
+ * Converts an SDL event key to a key value.
+ *
+ * @param event an SDL event with a key to convert.
+ * @return a key value.
+ * @see Key
+ */
+ int convertKeyCharacter(SDL_Event event);
+
+ std::queue<gcn::KeyInput> mKeyInputQueue;
+ std::queue<gcn::MouseInput> mMouseInputQueue;
+
+ bool mMouseDown;
+ bool mMouseInWindow;
+};
+
+#endif
diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp
index 6df1cbf6..f7f66345 100644
--- a/src/gui/sell.cpp
+++ b/src/gui/sell.cpp
@@ -31,6 +31,8 @@
#include "shop.h"
#include "slider.h"
+#include "widgets/layout.h"
+
#include "../item.h"
#include "../npc.h"
@@ -39,10 +41,11 @@
#include "../net/messageout.h"
#include "../net/protocol.h"
-#include "../utils/tostring.h"
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
SellDialog::SellDialog(Network *network):
- Window("Sell"),
+ Window(_("Sell")),
mNetwork(network),
mMaxItems(0), mAmountItems(0)
{
@@ -58,17 +61,17 @@ SellDialog::SellDialog(Network *network):
mScrollArea = new ScrollArea(mShopItemList);
mSlider = new Slider(1.0);
mQuantityLabel = new gcn::Label("0");
- mMoneyLabel = new gcn::Label("Money: 0 GP / Total: 0 GP");
+ mMoneyLabel = new gcn::Label(
+ strprintf(_("Price: %d GP / Total: %d GP"), 0, 0));
mIncreaseButton = new Button("+", "+", this);
mDecreaseButton = new Button("-", "-", this);
- mSellButton = new Button("Sell", "sell", this);
- mQuitButton = new Button("Quit", "quit", this);
- mItemDescLabel = new gcn::Label("Description:");
- mItemEffectLabel = new gcn::Label("Effect:");
+ 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"), ""));
mIncreaseButton->setSize(20, 20);
mDecreaseButton->setSize(20, 20);
- mQuantityLabel->setWidth(60);
mScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
mIncreaseButton->setEnabled(false);
@@ -77,23 +80,22 @@ SellDialog::SellDialog(Network *network):
mSlider->setEnabled(false);
mShopItemList->setPriceCheck(false);
- mShopItemList->setActionEventId("item");
- mSlider->setActionEventId("slider");
-
- mShopItemList->addActionListener(this);
mShopItemList->addSelectionListener(this);
+ mSlider->setActionEventId("slider");
mSlider->addActionListener(this);
- add(mScrollArea);
- add(mSlider);
- add(mQuantityLabel);
- add(mMoneyLabel);
- add(mItemEffectLabel);
- add(mItemDescLabel);
- add(mIncreaseButton);
- add(mDecreaseButton);
- add(mSellButton);
- add(mQuitButton);
+ 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);
+ place(0, 5, mDecreaseButton);
+ place(1, 5, mIncreaseButton);
+ place(3, 5, mSellButton);
+ place(4, 5, mQuitButton);
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, Layout::AUTO_SET);
loadWindowState();
setLocationRelativeTo(getParent());
@@ -210,65 +212,25 @@ void SellDialog::valueChanged(const gcn::SelectionEvent &event)
mSlider->gcn::Slider::setScale(1, mMaxItems);
}
-void SellDialog::widgetResized(const gcn::Event &event)
-{
- Window::widgetResized(event);
-
- gcn::Rectangle area = getChildrenArea();
- int width = area.width;
- int height = area.height;
-
- mDecreaseButton->setPosition(8, height - 8 - mDecreaseButton->getHeight());
- mIncreaseButton->setPosition(
- mDecreaseButton->getX() + mDecreaseButton->getWidth() + 5,
- mDecreaseButton->getY());
-
- mQuitButton->setPosition(
- width - 8 - mQuitButton->getWidth(),
- height - 8 - mQuitButton->getHeight());
- mSellButton->setPosition(
- mQuitButton->getX() - 5 - mSellButton->getWidth(),
- mQuitButton->getY());
-
- mItemDescLabel->setDimension(gcn::Rectangle(8,
- mSellButton->getY() - 5 - mItemDescLabel->getHeight(),
- width - 16,
- mItemDescLabel->getHeight()));
- mItemEffectLabel->setDimension(gcn::Rectangle(8,
- mItemDescLabel->getY() - 5 - mItemEffectLabel->getHeight(),
- width - 16,
- mItemEffectLabel->getHeight()));
- mMoneyLabel->setDimension(gcn::Rectangle(8,
- mItemEffectLabel->getY() - 5 - mMoneyLabel->getHeight(),
- width - 16,
- mMoneyLabel->getHeight()));
-
- mQuantityLabel->setPosition(
- width - mQuantityLabel->getWidth() - 8,
- mMoneyLabel->getY() - 5 - mQuantityLabel->getHeight());
- mSlider->setDimension(gcn::Rectangle(8,
- mQuantityLabel->getY(),
- mQuantityLabel->getX() - 8 - 8,
- 10));
-
- mScrollArea->setDimension(gcn::Rectangle(8, 8, width - 16,
- mSlider->getY() - 5 - 8));
-}
-
void SellDialog::setMoney(int amount)
{
mPlayerMoney = amount;
mShopItemList->setPlayersMoney(amount);
}
-void
-SellDialog::updateButtonsAndLabels()
+void SellDialog::updateButtonsAndLabels()
{
int selectedItem = mShopItemList->getSelected();
int income = 0;
if (selectedItem > -1)
{
+ const ItemInfo &info = mShopItems->at(selectedItem)->getInfo();
+ mItemDescLabel->setCaption
+ (strprintf(_("Description: %s"), info.getDescription().c_str()));
+ mItemEffectLabel->setCaption
+ (strprintf(_("Effect: %s"), info.getEffect().c_str()));
+
mMaxItems = mShopItems->at(selectedItem)->getQuantity();
if (mAmountItems > mMaxItems)
{
@@ -276,17 +238,13 @@ SellDialog::updateButtonsAndLabels()
}
income = mAmountItems * mShopItems->at(selectedItem)->getPrice();
-
- const ItemInfo &info = mShopItems->at(selectedItem)->getInfo();
- mItemDescLabel->setCaption("Description: " + info.getDescription());
- mItemEffectLabel->setCaption("Effect: " + info.getEffect());
}
else
{
+ mItemDescLabel->setCaption(strprintf(_("Description: %s"), ""));
+ mItemEffectLabel->setCaption(strprintf(_("Effect: %s"), ""));
mMaxItems = 0;
mAmountItems = 0;
- mItemDescLabel->setCaption("Description:");
- mItemEffectLabel->setCaption("Effect:");
}
// Update Buttons and slider
@@ -296,8 +254,8 @@ SellDialog::updateButtonsAndLabels()
mSlider->setEnabled(mMaxItems > 1);
// Update the quantity and money labels
- mQuantityLabel->setCaption(
- toString(mAmountItems) + " / " + toString(mMaxItems));
- mMoneyLabel->setCaption("Money: " + toString(income) + " GP / Total: "
- + toString(mPlayerMoney + income) + " GP");
+ mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems));
+ mMoneyLabel->setCaption
+ (strprintf(_("Price: %d GP / Total: %d GP"),
+ income, mPlayerMoney + income));
}
diff --git a/src/gui/sell.h b/src/gui/sell.h
index 48961efc..0bf8b5a6 100644
--- a/src/gui/sell.h
+++ b/src/gui/sell.h
@@ -77,11 +77,6 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener
void valueChanged(const gcn::SelectionEvent &event);
/**
- * Called whenever the widget changes size.
- */
- void widgetResized(const gcn::Event &event);
-
- /**
* Gives Player's Money amount
*/
void setMoney(int amount);
diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp
index 2da9d1b5..067d8d64 100644
--- a/src/gui/setup.cpp
+++ b/src/gui/setup.cpp
@@ -32,6 +32,8 @@
#include "tabbedcontainer.h"
#include "../utils/dtor.h"
+#include "../utils/gettext.h"
+
#include <iostream>
extern Window *statusWindow;
@@ -52,12 +54,12 @@ Setup::Setup():
int height = 265;
setContentSize(width, height);
- const char *buttonNames[] = {
- "Apply", "Cancel", "Reset Windows", 0
+ static const char *buttonNames[] = {
+ N_("Apply"), N_("Cancel"), N_("Reset Windows"), 0
};
int x = width;
for (const char **curBtn = buttonNames; *curBtn; ++curBtn) {
- Button *btn = new Button(*curBtn, *curBtn, this);
+ Button *btn = new Button(gettext(*curBtn), *curBtn, this);
x -= btn->getWidth() + 5;
btn->setPosition(x, height - btn->getHeight() - 5);
add(btn);
@@ -74,23 +76,23 @@ Setup::Setup():
SetupTab *tab;
tab = new Setup_Video();
- panel->addTab(tab, "Video");
+ panel->addTab(tab, _("Video"));
mTabs.push_back(tab);
tab = new Setup_Audio();
- panel->addTab(tab, "Audio");
+ panel->addTab(tab, _("Audio"));
mTabs.push_back(tab);
tab = new Setup_Joystick();
- panel->addTab(tab, "Joystick");
+ panel->addTab(tab, _("Joystick"));
mTabs.push_back(tab);
tab = new Setup_Keyboard();
- panel->addTab(tab, "Keyboard");
+ panel->addTab(tab, _("Keyboard"));
mTabs.push_back(tab);
tab = new Setup_Players();
- panel->addTab(tab, "Players");
+ panel->addTab(tab, _("Players"));
mTabs.push_back(tab);
add(panel);
diff --git a/src/gui/setup_audio.cpp b/src/gui/setup_audio.cpp
index a027e133..c595edc9 100644
--- a/src/gui/setup_audio.cpp
+++ b/src/gui/setup_audio.cpp
@@ -31,18 +31,20 @@
#include "../log.h"
#include "../sound.h"
+#include "../utils/gettext.h"
+
Setup_Audio::Setup_Audio():
mMusicVolume((int)config.getValue("musicVolume", 60)),
mSfxVolume((int)config.getValue("sfxVolume", 100)),
mSoundEnabled(config.getValue("sound", 0)),
- mSoundCheckBox(new CheckBox("Sound", mSoundEnabled)),
+ mSoundCheckBox(new CheckBox(_("Sound"), mSoundEnabled)),
mSfxSlider(new Slider(0, 128)),
mMusicSlider(new Slider(0, 128))
{
setOpaque(false);
- gcn::Label *sfxLabel = new gcn::Label("Sfx volume");
- gcn::Label *musicLabel = new gcn::Label("Music volume");
+ gcn::Label *sfxLabel = new gcn::Label(_("Sfx volume"));
+ gcn::Label *musicLabel = new gcn::Label(_("Music volume"));
mSfxSlider->setActionEventId("sfx");
mMusicSlider->setActionEventId("music");
diff --git a/src/gui/setup_joystick.cpp b/src/gui/setup_joystick.cpp
index c59068f7..a718f87e 100644
--- a/src/gui/setup_joystick.cpp
+++ b/src/gui/setup_joystick.cpp
@@ -28,12 +28,14 @@
#include "../configuration.h"
#include "../joystick.h"
+#include "../utils/gettext.h"
+
extern Joystick *joystick;
Setup_Joystick::Setup_Joystick():
- mCalibrateLabel(new gcn::Label("Press the button to start calibration")),
- mCalibrateButton(new Button("Calibrate", "calibrate", this)),
- mJoystickEnabled(new CheckBox("Enable joystick"))
+ mCalibrateLabel(new gcn::Label(_("Press the button to start calibration"))),
+ mCalibrateButton(new Button(_("Calibrate"), "calibrate", this)),
+ mJoystickEnabled(new CheckBox(_("Enable joystick")))
{
setOpaque(false);
mJoystickEnabled->setPosition(10, 10);
@@ -63,13 +65,13 @@ void Setup_Joystick::action(const gcn::ActionEvent &event)
else
{
if (joystick->isCalibrating()) {
- mCalibrateButton->setCaption("Calibrate");
- mCalibrateLabel->setCaption(
- "Press the button to start calibration");
+ mCalibrateButton->setCaption(_("Calibrate"));
+ mCalibrateLabel->setCaption
+ (_("Press the button to start calibration"));
joystick->finishCalibration();
} else {
- mCalibrateButton->setCaption("Stop");
- mCalibrateLabel->setCaption("Rotate the stick");
+ mCalibrateButton->setCaption(_("Stop"));
+ mCalibrateLabel->setCaption(_("Rotate the stick"));
joystick->startCalibration();
}
}
diff --git a/src/gui/setup_keyboard.cpp b/src/gui/setup_keyboard.cpp
index c6247487..de3c0ce1 100644
--- a/src/gui/setup_keyboard.cpp
+++ b/src/gui/setup_keyboard.cpp
@@ -32,6 +32,7 @@
#include "../configuration.h"
#include "../keyboardconfig.h"
+#include "../utils/gettext.h"
#include "../utils/tostring.h"
#include <SDL_keyboard.h>
@@ -84,13 +85,13 @@ Setup_Keyboard::Setup_Keyboard():
scrollArea->setDimension(gcn::Rectangle(10, 10, 200, 140));
add(scrollArea);
- mAssignKeyButton = new Button("Assign", "assign", this);
+ mAssignKeyButton = new Button(_("Assign"), "assign", this);
mAssignKeyButton->setPosition(165, 155);
mAssignKeyButton->addActionListener(this);
mAssignKeyButton->setEnabled(false);
add(mAssignKeyButton);
- mMakeDefaultButton = new Button("Default", "makeDefault", this);
+ mMakeDefaultButton = new Button(_("Default"), "makeDefault", this);
mMakeDefaultButton->setPosition(10, 155);
mMakeDefaultButton->addActionListener(this);
add(mMakeDefaultButton);
@@ -111,8 +112,9 @@ void Setup_Keyboard::apply()
if (keyboard.hasConflicts())
{
- new OkDialog("Key Conflict(s) Detected.",
- "Resolve them, or gameplay may result in strange behaviour.");
+ new OkDialog(_("Key Conflict(s) Detected."),
+ _("Resolve them, or gameplay may result in strange "
+ "behaviour."));
}
keyboard.setEnabled(true);
keyboard.store();
@@ -170,7 +172,7 @@ void Setup_Keyboard::newKeyCallback(int index)
void Setup_Keyboard::refreshKeys()
{
- for(int i = 0; i < keyboard.KEY_TOTAL; i++)
+ for (int i = 0; i < keyboard.KEY_TOTAL; i++)
{
refreshAssignedKey(i);
}
diff --git a/src/gui/setup_players.cpp b/src/gui/setup_players.cpp
index c556a82d..122f54e1 100644
--- a/src/gui/setup_players.cpp
+++ b/src/gui/setup_players.cpp
@@ -30,6 +30,8 @@
#include "../log.h"
#include "../sound.h"
+#include "../utils/gettext.h"
+
#include <guichan/widgets/dropdown.hpp>
#include <guichan/widgets/label.hpp>
@@ -47,10 +49,16 @@
#define WIDGET_AT(row, column) (((row) * COLUMNS_NR) + column)
-static std::string table_titles[COLUMNS_NR] = {"name", "relation"};
+static const char *table_titles[COLUMNS_NR] = {
+ N_("Name"),
+ N_("Relation")
+};
-static const std::string RELATION_NAMES[PlayerRelation::RELATIONS_NR] = {
- "neutral", "friend", "disregarded", "ignored"
+static const char *RELATION_NAMES[PlayerRelation::RELATIONS_NR] = {
+ N_("Neutral"),
+ N_("Friend"),
+ N_("Disregarded"),
+ N_("Ignored")
};
class PlayerRelationListModel : public gcn::ListModel
@@ -67,7 +75,7 @@ public:
{
if (i >= getNumberOfElements() || i < 0)
return "";
- return RELATION_NAMES[i];
+ return gettext(RELATION_NAMES[i]);
}
};
@@ -136,7 +144,8 @@ public:
virtual void updateModelInRow(int row)
{
- gcn::DropDown *choicebox = dynamic_cast<gcn::DropDown *>(getElementAt(row, RELATION_CHOICE_COLUMN));
+ gcn::DropDown *choicebox = dynamic_cast<gcn::DropDown *>(
+ getElementAt(row, RELATION_CHOICE_COLUMN));
player_relations.setRelation(getPlayerAt(row),
static_cast<PlayerRelation::relation>(choicebox->getSelected()));
}
@@ -202,21 +211,27 @@ Setup_Players::Setup_Players():
mPlayerTable(new GuiTable(mPlayerTableModel)),
mPlayerTitleTable(new GuiTable(mPlayerTableTitleModel)),
mPlayerScrollArea(new ScrollArea(mPlayerTable)),
- mPersistIgnores(new CheckBox("save player list", player_relations.getPersistIgnores())),
- mDefaultTrading(new CheckBox("allow trading", player_relations.getDefault() & PlayerRelation::TRADE)),
- mDefaultWhisper(new CheckBox("allow whispers", player_relations.getDefault() & PlayerRelation::WHISPER)),
- mDeleteButton(new Button("Delete", ACTION_DELETE, this)),
+ mPersistIgnores(new CheckBox(_("Save player list"),
+ player_relations.getPersistIgnores())),
+ mDefaultTrading(new CheckBox(_("Allow trading"),
+ player_relations.getDefault() & PlayerRelation::TRADE)),
+ mDefaultWhisper(new CheckBox(_("Allow whispers"),
+ player_relations.getDefault() & PlayerRelation::WHISPER)),
+ mDeleteButton(new Button(_("Delete"), ACTION_DELETE, this)),
mIgnoreActionChoicesBox(new gcn::DropDown(new IgnoreChoicesListModel()))
{
setOpaque(false);
int table_width = NAME_COLUMN_WIDTH + RELATION_CHOICE_COLUMN_WIDTH;
mPlayerTableTitleModel->fixColumnWidth(NAME_COLUMN, NAME_COLUMN_WIDTH);
- mPlayerTableTitleModel->fixColumnWidth(RELATION_CHOICE_COLUMN, RELATION_CHOICE_COLUMN_WIDTH);
+ mPlayerTableTitleModel->fixColumnWidth(RELATION_CHOICE_COLUMN,
+ RELATION_CHOICE_COLUMN_WIDTH);
mPlayerTitleTable->setDimension(gcn::Rectangle(10, 10, table_width, 10));
mPlayerTitleTable->setBackgroundColor(gcn::Color(0xbf, 0xbf, 0xbf));
- for (int i = 0; i < COLUMNS_NR; i++)
- mPlayerTableTitleModel->set(0, i, new gcn::Label(table_titles[i]));
+ for (int i = 0; i < COLUMNS_NR; i++) {
+ mPlayerTableTitleModel->set(0, i,
+ new gcn::Label(gettext(table_titles[i])));
+ }
mPlayerTitleTable->setLinewiseSelection(true);
mPlayerScrollArea->setDimension(gcn::Rectangle(10, 25, table_width + COLUMNS_NR, 90));
@@ -227,7 +242,7 @@ Setup_Players::Setup_Players():
mDeleteButton->setPosition(10, 118);
- gcn::Label *ignore_action_label = new gcn::Label("When ignoring:");
+ gcn::Label *ignore_action_label = new gcn::Label(_("When ignoring:"));
ignore_action_label->setPosition(80, 118);
mIgnoreActionChoicesBox->setDimension(gcn::Rectangle(80, 132, 120, 12));
@@ -269,9 +284,9 @@ Setup_Players::~Setup_Players()
void Setup_Players::reset()
{
- // We now have to search through the list of ignore choices to find the current
- // selection. We could use an index into the table of config options in
- // player_relations instead of strategies to sidestep this.
+ // We now have to search through the list of ignore choices to find the
+ // current selection. We could use an index into the table of config
+ // options in player_relations instead of strategies to sidestep this.
int selection = 0;
for (unsigned int i = 0; i < player_relations.getPlayerIgnoreStrategies()->size(); ++i)
if ((*player_relations.getPlayerIgnoreStrategies())[i] ==
@@ -303,9 +318,10 @@ void Setup_Players::cancel()
void Setup_Players::action(const gcn::ActionEvent &event)
{
if (event.getId() == ACTION_TABLE) {
- // temporarily eliminate ourselves: we are fully aware of this change, so there is no
- // need for asynchronous updates. (In fact, thouse might destroy the widet that
- // triggered them, which would be rather embarrassing.)
+ // temporarily eliminate ourselves: we are fully aware of this change,
+ // so there is no need for asynchronous updates. (In fact, thouse
+ // might destroy the widet that triggered them, which would be rather
+ // embarrassing.)
player_relations.removeListener(this);
int row = mPlayerTable->getSelectedRow();
@@ -336,6 +352,8 @@ void Setup_Players::action(const gcn::ActionEvent &event)
void Setup_Players::updatedPlayer(const std::string &name)
{
mPlayerTableModel->playerRelationsUpdated();
- mDefaultTrading->setSelected(player_relations.getDefault() & PlayerRelation::TRADE);
- mDefaultWhisper->setSelected(player_relations.getDefault() & PlayerRelation::WHISPER);
+ mDefaultTrading->setSelected(
+ player_relations.getDefault() & PlayerRelation::TRADE);
+ mDefaultWhisper->setSelected(
+ player_relations.getDefault() & PlayerRelation::WHISPER);
}
diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp
index 23d2d9c2..cc39caed 100644
--- a/src/gui/setup_video.cpp
+++ b/src/gui/setup_video.cpp
@@ -43,6 +43,7 @@
#include "../main.h"
#include "../particle.h"
+#include "../utils/gettext.h"
#include "../utils/tostring.h"
extern Graphics *graphics;
@@ -108,11 +109,11 @@ Setup_Video::Setup_Video():
mFps((int) config.getValue("fpslimit", 0)),
mModeListModel(new ModeListModel),
mModeList(new ListBox(mModeListModel)),
- mFsCheckBox(new CheckBox("Full screen", mFullScreenEnabled)),
- mOpenGLCheckBox(new CheckBox("OpenGL", mOpenGLEnabled)),
- mCustomCursorCheckBox(new CheckBox("Custom cursor", mCustomCursorEnabled)),
+ mFsCheckBox(new CheckBox(_("Full screen"), mFullScreenEnabled)),
+ mOpenGLCheckBox(new CheckBox(_("OpenGL"), mOpenGLEnabled)),
+ mCustomCursorCheckBox(new CheckBox(_("Custom cursor"), mCustomCursorEnabled)),
mAlphaSlider(new Slider(0.2, 1.0)),
- mFpsCheckBox(new CheckBox("FPS Limit: ")),
+ mFpsCheckBox(new CheckBox(_("FPS Limit:"))),
mFpsSlider(new Slider(10, 200)),
mFpsField(new TextField),
mOriginalScrollLaziness((int) config.getValue("ScrollLaziness", 16)),
@@ -131,7 +132,7 @@ Setup_Video::Setup_Video():
setOpaque(false);
ScrollArea *scrollArea = new ScrollArea(mModeList);
- gcn::Label *alphaLabel = new gcn::Label("Gui opacity");
+ gcn::Label *alphaLabel = new gcn::Label(_("Gui opacity"));
mModeList->setEnabled(false);
#ifndef USE_OPENGL
@@ -188,7 +189,7 @@ Setup_Video::Setup_Video():
mParticleDetailField->addKeyListener(this);
mScrollRadiusSlider->setDimension(gcn::Rectangle(10, 120, 75, 10));
- gcn::Label *scrollRadiusLabel = new gcn::Label("Scroll radius");
+ gcn::Label *scrollRadiusLabel = new gcn::Label(_("Scroll radius"));
scrollRadiusLabel->setPosition(90, 120);
mScrollRadiusField->setPosition(mFpsField->getX(), 120);
mScrollRadiusField->setWidth(30);
@@ -196,7 +197,7 @@ Setup_Video::Setup_Video():
mScrollRadiusSlider->setValue(mOriginalScrollRadius);
mScrollLazinessSlider->setDimension(gcn::Rectangle(10, 140, 75, 10));
- gcn::Label *scrollLazinessLabel = new gcn::Label("Scroll laziness");
+ gcn::Label *scrollLazinessLabel = new gcn::Label(_("Scroll laziness"));
scrollLazinessLabel->setPosition(90, 140);
mScrollLazinessField->setPosition(mFpsField->getX(), 140);
mScrollLazinessField->setWidth(30);
@@ -204,42 +205,42 @@ Setup_Video::Setup_Video():
mScrollLazinessSlider->setValue(mOriginalScrollLaziness);
mOverlayDetailSlider->setDimension(gcn::Rectangle(10, 160, 75, 10));
- gcn::Label *overlayDetailLabel = new gcn::Label("Ambient FX");
+ gcn::Label *overlayDetailLabel = new gcn::Label(_("Ambient FX"));
overlayDetailLabel->setPosition(90, 160);
mOverlayDetailField->setPosition(180, 160);
mOverlayDetailField->setWidth(30);
switch (mOverlayDetail)
{
case 0:
- mOverlayDetailField->setCaption("off");
+ mOverlayDetailField->setCaption(_("off"));
break;
case 1:
- mOverlayDetailField->setCaption("low");
+ mOverlayDetailField->setCaption(_("low"));
break;
case 2:
- mOverlayDetailField->setCaption("high");
+ mOverlayDetailField->setCaption(_("high"));
break;
}
mOverlayDetailSlider->setValue(mOverlayDetail);
mParticleDetailSlider->setDimension(gcn::Rectangle(10, 180, 75, 10));
- gcn::Label *particleDetailLabel = new gcn::Label("Particle Detail");
+ gcn::Label *particleDetailLabel = new gcn::Label(_("Particle Detail"));
particleDetailLabel->setPosition(90, 180);
mParticleDetailField->setPosition(180, 180);
mParticleDetailField->setWidth(60);
switch (mParticleDetail)
{
case 0:
- mParticleDetailField->setCaption("low");
+ mParticleDetailField->setCaption(_("low"));
break;
case 1:
- mParticleDetailField->setCaption("medium");
+ mParticleDetailField->setCaption(_("medium"));
break;
case 2:
- mParticleDetailField->setCaption("high");
+ mParticleDetailField->setCaption(_("high"));
break;
case 3:
- mParticleDetailField->setCaption("max");
+ mParticleDetailField->setCaption(_("max"));
break;
}
mParticleDetailSlider->setValue(mParticleDetail);
@@ -305,8 +306,8 @@ void Setup_Video::apply()
}
#if defined(WIN32) || defined(__APPLE__)
} else {
- new OkDialog("Switching to full screen",
- "Restart needed for changes to take effect.");
+ new OkDialog(_("Switching to full screen"),
+ _("Restart needed for changes to take effect."));
}
#endif
config.setValue("screen", fullscreen ? 1 : 0);
@@ -318,8 +319,8 @@ void Setup_Video::apply()
config.setValue("opengl", mOpenGLCheckBox->isSelected() ? 1 : 0);
// OpenGL can currently only be changed by restarting, notify user.
- new OkDialog("Changing OpenGL",
- "Applying change to OpenGL requires restart.");
+ new OkDialog(_("Changing OpenGL"),
+ _("Applying change to OpenGL requires restart."));
}
// FPS change
@@ -408,13 +409,13 @@ void Setup_Video::action(const gcn::ActionEvent &event)
switch (val)
{
case 0:
- mOverlayDetailField->setCaption("off");
+ mOverlayDetailField->setCaption(_("off"));
break;
case 1:
- mOverlayDetailField->setCaption("low");
+ mOverlayDetailField->setCaption(_("low"));
break;
case 2:
- mOverlayDetailField->setCaption("high");
+ mOverlayDetailField->setCaption(_("high"));
break;
}
config.setValue("OverlayDetail", val);
@@ -425,16 +426,16 @@ void Setup_Video::action(const gcn::ActionEvent &event)
switch (val)
{
case 0:
- mParticleDetailField->setCaption("low");
+ mParticleDetailField->setCaption(_("low"));
break;
case 1:
- mParticleDetailField->setCaption("medium");
+ mParticleDetailField->setCaption(_("medium"));
break;
case 2:
- mParticleDetailField->setCaption("high");
+ mParticleDetailField->setCaption(_("high"));
break;
case 3:
- mParticleDetailField->setCaption("max");
+ mParticleDetailField->setCaption(_("max"));
break;
}
config.setValue("particleEmitterSkip", 3 - val);
diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp
index 82108f84..8b8c58cd 100644
--- a/src/gui/skill.cpp
+++ b/src/gui/skill.cpp
@@ -29,12 +29,14 @@
#include "windowcontainer.h"
#include "../localplayer.h"
+#include "../log.h"
#include "../utils/dtor.h"
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
#include "../utils/xml.h"
-#include "../log.h"
-#define SKILLS_FILE "skills.xml"
+static const char *SKILLS_FILE = "skills.xml";
struct SkillInfo {
std::string name;
@@ -73,7 +75,10 @@ public:
virtual void update()
{
- static const SkillInfo fakeSkillInfo = { "Mystery Skill", false };
+ static const SkillInfo fakeSkillInfo = {
+ _("Mystery Skill"),
+ false
+ };
mEntriesNr = mDialog->getSkills().size();
resize();
@@ -90,13 +95,13 @@ public:
info = &fakeSkillInfo;
sprintf(tmp, "%c%s", info->modifiable? ' ' : '*', info->name.c_str());
- gcn::Label *name_label = new gcn::Label(std::string(tmp));
+ gcn::Label *name_label = new gcn::Label(tmp);
sprintf(tmp, "Lv:%i", skill->lv);
- gcn::Label *lv_label = new gcn::Label(std::string(tmp));
+ gcn::Label *lv_label = new gcn::Label(tmp);
sprintf(tmp, "Sp:%i", skill->sp);
- gcn::Label *sp_label = new gcn::Label(std::string(tmp));
+ gcn::Label *sp_label = new gcn::Label(tmp);
set(i, 0, name_label);
set(i, 1, lv_label);
@@ -111,7 +116,7 @@ private:
SkillDialog::SkillDialog():
- Window("Skills")
+ Window(_("Skills"))
{
initSkillinfo();
mTableModel = new SkillGuiTableModel(this);
@@ -124,9 +129,9 @@ SkillDialog::SkillDialog():
// mSkillListBox = new ListBox(this);
ScrollArea *skillScrollArea = new ScrollArea(&mTable);
- mPointsLabel = new gcn::Label("Skill Points:");
- mIncButton = new Button("Up", "inc", this);
- mUseButton = new Button("Use", "use", this);
+ mPointsLabel = new gcn::Label(strprintf(_("Skill points: %d"), 0));
+ mIncButton = new Button(_("Up"), "inc", this);
+ mUseButton = new Button(_("Use"), "use", this);
mUseButton->setEnabled(false);
// mSkillListBox->setActionEventId("skill");
@@ -180,11 +185,8 @@ void SkillDialog::action(const gcn::ActionEvent &event)
void SkillDialog::update()
{
- if (mPointsLabel != NULL) {
- char tmp[128];
- sprintf(tmp, "Skill points: %i", player_node->mSkillPoint);
- mPointsLabel->setCaption(tmp);
- }
+ mPointsLabel->setCaption(strprintf(_("Skill points: %d"),
+ player_node->mSkillPoint));
int selectedSkill = mTable.getSelectedRow();
@@ -254,8 +256,7 @@ static void initSkillinfo()
if (!root || !xmlStrEqual(root->name, BAD_CAST "skills"))
{
- logger->log("Error loading skills file: "
- SKILLS_FILE);
+ logger->log("Error loading skills file: %s", SKILLS_FILE);
skill_db.resize(2, emptySkillInfo);
skill_db[1].name = "Basic";
skill_db[1].modifiable = true;
diff --git a/src/gui/status.cpp b/src/gui/status.cpp
index 1a257ae8..a5bb77c3 100644
--- a/src/gui/status.cpp
+++ b/src/gui/status.cpp
@@ -29,6 +29,8 @@
#include "../localplayer.h"
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
#include "../utils/tostring.h"
StatusWindow::StatusWindow(LocalPlayer *player):
@@ -46,25 +48,25 @@ StatusWindow::StatusWindow(LocalPlayer *player):
// Status Part
// ----------------------
- mLvlLabel = new gcn::Label("Level:");
- mGpLabel = new gcn::Label("Money:");
- mJobLvlLabel = new gcn::Label("Job:");
+ mLvlLabel = new gcn::Label(strprintf(_("Level: %d"), 0));
+ mGpLabel = new gcn::Label(strprintf(_("Job: %d"), 0));
+ mJobLvlLabel = new gcn::Label(strprintf(_("Money: %d GP"), 0));
mHpLabel = new gcn::Label("HP:");
mHpBar = new ProgressBar(1.0f, 80, 15, 0, 171, 34);
- mHpValueLabel = new gcn::Label("");
+ mHpValueLabel = new gcn::Label;
mXpLabel = new gcn::Label("Exp:");
mXpBar = new ProgressBar(1.0f, 80, 15, 143, 192, 211);
- mXpValueLabel = new gcn::Label("");
+ mXpValueLabel = new gcn::Label;
mMpLabel = new gcn::Label("MP:");
mMpBar = new ProgressBar(1.0f, 80, 15, 26, 102, 230);
- mMpValueLabel = new gcn::Label("");
+ mMpValueLabel = new gcn::Label;
mJobXpLabel = new gcn::Label("Job:");
mJobXpBar = new ProgressBar(1.0f, 80, 15, 220, 135, 203);
- mJobValueLabel = new gcn::Label("");
+ mJobValueLabel = new gcn::Label;
int y = 3;
int x = 5;
@@ -122,34 +124,34 @@ 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 gcn::Label(_("Stats"));
+ gcn::Label *mStatsTotalLabel = new gcn::Label(_("Total"));
+ gcn::Label *mStatsCostLabel = new gcn::Label(_("Cost"));
// Derived Stats
- mStatsAttackLabel = new gcn::Label("Attack:");
- mStatsDefenseLabel= new gcn::Label("Defense:");
- mStatsMagicAttackLabel = new gcn::Label("M.Attack:");
- mStatsMagicDefenseLabel = new gcn::Label("M.Defense:");
- mStatsAccuracyLabel = new gcn::Label("% Accuracy:");
- mStatsEvadeLabel = new gcn::Label("% Evade:");
- mStatsReflexLabel = new gcn::Label("% Reflex:");
-
- mStatsAttackPoints = new gcn::Label("");
- mStatsDefensePoints = new gcn::Label("");
- mStatsMagicAttackPoints = new gcn::Label("");
- mStatsMagicDefensePoints = new gcn::Label("");
- mStatsAccuracyPoints = new gcn::Label("% Accuracy:");
- mStatsEvadePoints = new gcn::Label("% Evade:");
- mStatsReflexPoints = new gcn::Label("% Reflex:");
+ mStatsAttackLabel = new gcn::Label(_("Attack:"));
+ mStatsDefenseLabel= new gcn::Label(_("Defense:"));
+ mStatsMagicAttackLabel = new gcn::Label(_("M.Attack:"));
+ mStatsMagicDefenseLabel = new gcn::Label(_("M.Defense:"));
+ mStatsAccuracyLabel = new gcn::Label(_("% Accuracy:"));
+ mStatsEvadeLabel = new gcn::Label(_("% Evade:"));
+ mStatsReflexLabel = new gcn::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;
// New labels
for (int i = 0; i < 6; i++) {
- mStatsLabel[i] = new gcn::Label();
- mStatsDisplayLabel[i] = new gcn::Label();
+ mStatsLabel[i] = new gcn::Label;
+ mStatsDisplayLabel[i] = new gcn::Label;
mPointsLabel[i] = new gcn::Label("0");
}
- mRemainingStatsPointsLabel = new gcn::Label();
+ mRemainingStatsPointsLabel = new gcn::Label;
// Set button events Id
mStatsButton[0] = new Button("+", "STR", this);
@@ -227,13 +229,13 @@ void StatusWindow::update()
{
// Status Part
// -----------
- mLvlLabel->setCaption("Level: " + toString(mPlayer->mLevel));
+ mLvlLabel->setCaption(strprintf(_("Level: %d"), mPlayer->mLevel));
mLvlLabel->adjustSize();
- mJobLvlLabel->setCaption("Job: " + toString(mPlayer->mJobLevel));
+ mJobLvlLabel->setCaption(strprintf(_("Job: %d"), mPlayer->mJobLevel));
mJobLvlLabel->adjustSize();
- mGpLabel->setCaption("Money: " + toString(mPlayer->mGp) + " GP");
+ mGpLabel->setCaption(strprintf(_("Money: %d GP"), mPlayer->mGp));
mGpLabel->adjustSize();
mHpValueLabel->setCaption(toString(mPlayer->mHp) +
@@ -276,20 +278,20 @@ void StatusWindow::update()
// Stats Part
// ----------
- static const std::string attrNames[6] = {
- "Strength",
- "Agility",
- "Vitality",
- "Intelligence",
- "Dexterity",
- "Luck"
+ static const char *attrNames[6] = {
+ N_("Strength"),
+ N_("Agility"),
+ N_("Vitality"),
+ N_("Intelligence"),
+ N_("Dexterity"),
+ N_("Luck")
};
int statusPoints = mPlayer->mStatsPointsToAttribute;
// Update labels
for (int i = 0; i < 6; i++)
{
- mStatsLabel[i]->setCaption(attrNames[i]);
+ mStatsLabel[i]->setCaption(gettext(attrNames[i]));
mStatsDisplayLabel[i]->setCaption(toString((int) mPlayer->mAttr[i]));
mPointsLabel[i]->setCaption(toString((int) mPlayer->mAttrUp[i]));
@@ -299,8 +301,8 @@ void StatusWindow::update()
mStatsButton[i]->setEnabled(mPlayer->mAttrUp[i] <= statusPoints);
}
- mRemainingStatsPointsLabel->setCaption("Remaining Status Points: " +
- toString(statusPoints));
+ mRemainingStatsPointsLabel->setCaption(
+ strprintf(_("Remaining Status Points: %d"), statusPoints));
mRemainingStatsPointsLabel->adjustSize();
// Derived Stats Points
@@ -353,12 +355,12 @@ void StatusWindow::update()
mXpBar->getX() + mXpBar->getWidth() + 5,
mXpLabel->getY());
- mJobXpLabel->setPosition(mXpBar->getX() - mJobXpLabel->getWidth() - 5,
+ mJobXpLabel->setPosition(mXpBar->getX() - mJobXpLabel->getWidth() - 5,
mMpLabel->getY());
mJobXpBar->setPosition(
mJobXpLabel->getX() + mJobXpLabel->getWidth() + 5,
mJobXpLabel->getY());
- mJobValueLabel->setPosition(mJobXpBar->getX() + mJobXpBar->getWidth() + 5,
+ mJobValueLabel->setPosition(mJobXpBar->getX() + mJobXpBar->getWidth() + 5,
mJobXpLabel->getY());
}
diff --git a/src/gui/textfield.cpp b/src/gui/textfield.cpp
index ea82ba77..bbedb29d 100644
--- a/src/gui/textfield.cpp
+++ b/src/gui/textfield.cpp
@@ -19,11 +19,13 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "textfield.h"
+
#include <algorithm>
#include <guichan/font.hpp>
-#include "textfield.h"
+#include "sdlinput.h"
#include "../graphics.h"
@@ -32,6 +34,8 @@
#include "../utils/dtor.h"
+#undef DELETE //Win32 compatibility hack
+
int TextField::instances = 0;
ImageRect TextField::skin;
@@ -100,3 +104,99 @@ void TextField::drawFrame(gcn::Graphics *graphics)
static_cast<Graphics*>(graphics)->drawImageRect(0, 0, w, h, skin);
}
+
+void TextField::keyPressed(gcn::KeyEvent &keyEvent)
+{
+ int val = keyEvent.getKey().getValue();
+
+ if (val >= 32)
+ {
+ int l;
+ if (val < 128) l = 1; // 0xxxxxxx
+ else if (val < 0x800) l = 2; // 110xxxxx 10xxxxxx
+ else if (val < 0x10000) l = 3; // 1110xxxx 10xxxxxx 10xxxxxx
+ else l = 4; // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+
+ char buf[4];
+ for (int i = 0; i < l; ++i)
+ {
+ buf[i] = val >> (6 * (l - i - 1));
+ if (i > 0) buf[i] = (buf[i] & 63) | 128;
+ }
+
+ if (l > 1) buf[0] |= 255 << (8 - l);
+
+ mText.insert(mCaretPosition, std::string(buf, buf + l));
+ mCaretPosition += l;
+ }
+
+ /* In UTF-8, 10xxxxxx is only used for inner parts of characters. So skip
+ them when processing key presses. */
+
+ switch (val)
+ {
+ case Key::LEFT:
+ {
+ while (mCaretPosition > 0)
+ {
+ --mCaretPosition;
+ if ((mText[mCaretPosition] & 192) != 128)
+ break;
+ }
+ } break;
+
+ case Key::RIGHT:
+ {
+ unsigned sz = mText.size();
+ while (mCaretPosition < sz)
+ {
+ ++mCaretPosition;
+ if (mCaretPosition == sz ||
+ (mText[mCaretPosition] & 192) != 128)
+ break;
+ }
+ } break;
+
+ case Key::DELETE:
+ {
+ unsigned sz = mText.size();
+ while (mCaretPosition < sz)
+ {
+ --sz;
+ mText.erase(mCaretPosition, 1);
+ if (mCaretPosition == sz ||
+ (mText[mCaretPosition] & 192) != 128)
+ break;
+ }
+ } break;
+
+ case Key::BACKSPACE:
+ {
+ while (mCaretPosition > 0)
+ {
+ --mCaretPosition;
+ int v = mText[mCaretPosition];
+ mText.erase(mCaretPosition, 1);
+ if ((v & 192) != 128) break;
+ }
+ } break;
+
+ case Key::ENTER:
+ distributeActionEvent();
+ break;
+
+ case Key::HOME:
+ mCaretPosition = 0;
+ break;
+
+ case Key::END:
+ mCaretPosition = mText.size();
+ break;
+
+ case Key::TAB:
+ return;
+ }
+
+ keyEvent.consume();
+ fixScroll();
+}
diff --git a/src/gui/textfield.h b/src/gui/textfield.h
index 60a50c69..b808fad2 100644
--- a/src/gui/textfield.h
+++ b/src/gui/textfield.h
@@ -53,6 +53,11 @@ class TextField : public gcn::TextField {
*/
void drawFrame(gcn::Graphics *graphics);
+ /**
+ * Processes one keypress.
+ */
+ void keyPressed(gcn::KeyEvent &keyEvent);
+
private:
static int instances;
static ImageRect skin;
diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp
index 9347cc02..405d871f 100644
--- a/src/gui/trade.cpp
+++ b/src/gui/trade.cpp
@@ -41,6 +41,8 @@
#include "../resources/iteminfo.h"
+#include "../utils/gettext.h"
+#include "../utils/strprintf.h"
#include "../utils/tostring.h"
TradeWindow::TradeWindow(Network *network):
@@ -56,10 +58,10 @@ TradeWindow::TradeWindow(Network *network):
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);
+ mAddButton = new Button(_("Add"), "add", this);
+ mOkButton = new Button(_("Ok"), "ok", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+ mTradeButton = new Button(_("Trade"), "trade", this);
mMyItemContainer = new ItemContainer(mMyInventory.get());
mMyItemContainer->addSelectionListener(this);
@@ -75,8 +77,8 @@ TradeWindow::TradeWindow(Network *network):
mPartnerScroll = new ScrollArea(mPartnerItemContainer);
mPartnerScroll->setPosition(8, 64);
- mMoneyLabel = new gcn::Label("You get: 0 GP");
- mMoneyLabel2 = new gcn::Label("You give:");
+ mMoneyLabel = new gcn::Label(strprintf(_("You get %d GP."), 0));
+ mMoneyLabel2 = new gcn::Label(_("You give:"));
mMoneyField = new TextField;
mMoneyField->setWidth(50);
@@ -87,8 +89,9 @@ TradeWindow::TradeWindow(Network *network):
mTradeButton->setEnabled(false);
- mItemNameLabel = new gcn::Label("Name:");
- mItemDescriptionLabel = new gcn::Label("Description:");
+ mItemNameLabel = new gcn::Label(strprintf(_("Name: %s"), ""));
+ mItemDescriptionLabel = new gcn::Label(
+ strprintf(_("Description: %s"), ""));
add(mMyScroll);
add(mPartnerScroll);
@@ -150,7 +153,7 @@ void TradeWindow::widgetResized(const gcn::Event &event)
void TradeWindow::addMoney(int amount)
{
- mMoneyLabel->setCaption("You get: " + toString(amount) + " GP");
+ mMoneyLabel->setCaption(strprintf(_("You get %d GP."), amount));
mMoneyLabel->adjustSize();
}
@@ -198,7 +201,7 @@ void TradeWindow::reset()
mOkButton->setEnabled(true);
mOkOther = false;
mOkMe = false;
- mMoneyLabel->setCaption("You get: 0 GP");
+ mMoneyLabel->setCaption(strprintf(_("You get %d GP."), 0));
mMoneyField->setEnabled(true);
mMoneyField->setText("");
}
@@ -257,21 +260,11 @@ void TradeWindow::valueChanged(const gcn::SelectionEvent &event)
}
// Update name and description
- if (!item)
- {
- mItemNameLabel->setCaption("Name:");
- mItemDescriptionLabel->setCaption("Description:");
- }
- else
- {
- std::string SomeText;
- SomeText = "Name: " + item->getInfo().getName();
- mItemNameLabel->setCaption(SomeText);
- mItemNameLabel->adjustSize();
- SomeText = "Description: " + item->getInfo().getDescription();
- mItemDescriptionLabel->setCaption(SomeText);
- mItemDescriptionLabel->adjustSize();
- }
+ ItemInfo const *info = item ? &item->getInfo() : NULL;
+ mItemNameLabel->setCaption(strprintf(_("Name: %s"),
+ info ? info->getName().c_str() : ""));
+ mItemDescriptionLabel->setCaption(strprintf(_("Description: %s"),
+ info ? info->getDescription().c_str() : ""));
}
void TradeWindow::action(const gcn::ActionEvent &event)
@@ -287,8 +280,8 @@ void TradeWindow::action(const gcn::ActionEvent &event)
return;
if (mMyInventory->contains(item)) {
- chatWindow->chatLog("Failed adding item. You can not "
- "overlap one kind of item on the window.", BY_SERVER);
+ chatWindow->chatLog(_("Failed adding item. You can not "
+ "overlap one kind of item on the window."), BY_SERVER);
return;
}
diff --git a/src/gui/truetypefont.cpp b/src/gui/truetypefont.cpp
index 7f9abd3a..0eed6f08 100644
--- a/src/gui/truetypefont.cpp
+++ b/src/gui/truetypefont.cpp
@@ -17,8 +17,6 @@
* You should have received a copy of the GNU General Public License
* along with The Mana World; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
*/
#include "truetypefont.h"
@@ -47,8 +45,7 @@ class TextChunk
bool operator==(const TextChunk &chunk) const
{
- return (
- chunk.text == text && chunk.color == color);
+ return (chunk.text == text && chunk.color == color);
}
void generate(TTF_Font *font)
@@ -84,7 +81,7 @@ typedef std::list<TextChunk>::iterator CacheIterator;
static int fontCounter;
-TrueTypeFont::TrueTypeFont(const std::string& filename, int size)
+TrueTypeFont::TrueTypeFont(const std::string &filename, int size)
{
if (fontCounter == 0 && TTF_Init() == -1)
{
@@ -167,7 +164,7 @@ void TrueTypeFont::drawString(gcn::Graphics *graphics,
g->drawImage(cache.front().img, x, y);
}
-int TrueTypeFont::getWidth(const std::string& text) const
+int TrueTypeFont::getWidth(const std::string &text) const
{
int w, h;
TTF_SizeUTF8(mFont, text.c_str(), &w, &h);
diff --git a/src/gui/truetypefont.h b/src/gui/truetypefont.h
index 48502f1f..e8617c7d 100644
--- a/src/gui/truetypefont.h
+++ b/src/gui/truetypefont.h
@@ -17,8 +17,6 @@
* You should have received a copy of the GNU General Public License
* along with The Mana World; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
*/
#ifndef _TMW_TRUETYPEFONT_H
@@ -44,74 +42,7 @@ class TrueTypeFont : public gcn::Font
* @param filename Font filename.
* @param size Font size.
*/
- TrueTypeFont(const std::string& filename, int size);
-
- /**
- * Destructor.
- */
- ~TrueTypeFont();
-
- virtual int getWidth(const std::string& text) const;
-
- virtual int getHeight() const;
-
- /**
- * @see Font::drawString
- */
- void drawString(gcn::Graphics* graphics, const std::string& text, int x, int y);
-
- private:
- TTF_Font *mFont;
-};
-
-#endif
-/*
- * The Mana World
- * Copyright 2004 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * The Mana World 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.
- *
- * The Mana World 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 The Mana World; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * $Id$
- */
-
-#ifndef _TMW_TRUETYPEFONT_H
-#define _TMW_TRUETYPEFONT_H
-
-#include <string>
-
-#include <guichan/font.hpp>
-#include <guichan/graphics.hpp>
-#include <SDL/SDL_ttf.h>
-
-/**
- * A wrapper around SDL_ttf for allowing the use of TrueType fonts.
- *
- * <b>NOTE:</b> This class needs SDL_ttf to be initialized.
- */
-class TrueTypeFont : public gcn::Font
-{
- public:
- /**
- * Constructor.
- *
- * @param filename Font filename.
- * @param size Font size.
- */
- TrueTypeFont(const std::string& filename, int size);
+ TrueTypeFont(const std::string &filename, int size);
/**
* Destructor.
@@ -125,7 +56,9 @@ class TrueTypeFont : public gcn::Font
/**
* @see Font::drawString
*/
- void drawString(gcn::Graphics* graphics, const std::string& text, int x, int y);
+ void drawString(gcn::Graphics *graphics,
+ const std::string &text,
+ int x, int y);
private:
TTF_Font *mFont;
diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp
index 7f7d45fc..a6857d21 100644
--- a/src/gui/updatewindow.cpp
+++ b/src/gui/updatewindow.cpp
@@ -40,6 +40,7 @@
#include "../log.h"
#include "../main.h"
+#include "../utils/gettext.h"
#include "../utils/tostring.h"
#include "../resources/resourcemanager.h"
@@ -89,7 +90,7 @@ loadTextFile(const std::string &fileName)
UpdaterWindow::UpdaterWindow(const std::string &updateHost,
const std::string &updatesDir):
- Window("Updating..."),
+ Window(_("Updating...")),
mThread(NULL),
mDownloadStatus(UPDATE_NEWS),
mUpdateHost(updateHost),
@@ -112,10 +113,10 @@ UpdaterWindow::UpdaterWindow(const std::string &updateHost,
mBrowserBox = new BrowserBox();
mScrollArea = new ScrollArea(mBrowserBox);
- mLabel = new gcn::Label("Connecting...");
+ mLabel = new gcn::Label(_("Connecting..."));
mProgressBar = new ProgressBar(0.0, w - 10, 20, 37, 70, 200);
- mCancelButton = new Button("Cancel", "cancel", this);
- mPlayButton = new Button("Play", "play", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+ mPlayButton = new Button(_("Play"), "play", this);
mBrowserBox->setOpaque(false);
mPlayButton->setEnabled(false);
@@ -228,8 +229,9 @@ int UpdaterWindow::updateProgress(void *ptr,
float progress = dn / dt;
UpdaterWindow *uw = reinterpret_cast<UpdaterWindow *>(ptr);
- if (progress < 0) progress = 0.0f;
- if (progress > 1) progress = 1.0f;
+ if (progress != progress) progress = 0.0f; // check for NaN
+ if (progress < 0.0f) progress = 0.0f; // no idea how this could ever happen, but why not check for it anyway.
+ if (progress > 1.0f) progress = 1.0f;
uw->setLabel(
uw->mCurrentFile + " (" + toString((int) (progress * 100)) + "%)");
@@ -521,7 +523,7 @@ void UpdaterWindow::logic()
break;
case UPDATE_COMPLETE:
enable();
- setLabel("Completed");
+ setLabel(_("Completed"));
break;
case UPDATE_IDLE:
break;
diff --git a/src/gui/vbox.cpp b/src/gui/vbox.cpp
deleted file mode 100644
index 2ec1112d..00000000
--- a/src/gui/vbox.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * The Mana World
- * Copyright 2004 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * The Mana World 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.
- *
- * The Mana World 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 The Mana World; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "vbox.h"
-
-void VBox::draw(gcn::Graphics *graphics)
-{
- if (mWidgets.empty())
- {
- return;
- }
-
- int childWidth = getWidth();
- int childHeight = getHeight() / mWidgets.size();
- int i = 0;
-
- for (WidgetIterator w = mWidgets.begin(); w != mWidgets.end(); w++)
- {
- (*w)->setPosition(0, childHeight * i - padding);
- (*w)->setSize(childWidth, childHeight);
- i++;
- }
-
- gcn::Container::draw(graphics);
-}
diff --git a/src/gui/vbox.h b/src/gui/vbox.h
deleted file mode 100644
index 2072ab24..00000000
--- a/src/gui/vbox.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * The Mana World
- * Copyright 2004 The Mana World Development Team
- *
- * This file is part of The Mana World.
- *
- * The Mana World 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.
- *
- * The Mana World 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 The Mana World; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef VBOX_H
-#define VBOX_H
-
-#include "box.h"
-
-class VBox : public Box
-{
- public:
- void draw(gcn::Graphics *);
-};
-
-#endif
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index 37aa40ce..9eab7c95 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -21,8 +21,6 @@
#include "viewport.h"
-#include <guichan/sdl/sdlinput.hpp>
-
#include "gui.h"
#include "popupmenu.h"
#include "ministatus.h"
diff --git a/src/gui/widgets/layout.cpp b/src/gui/widgets/layout.cpp
new file mode 100644
index 00000000..bcc54cf7
--- /dev/null
+++ b/src/gui/widgets/layout.cpp
@@ -0,0 +1,327 @@
+/*
+ * The Mana World
+ * Copyright 2007 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World 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.
+ *
+ * The Mana World 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 The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <cassert>
+
+#include "layout.h"
+
+ContainerPlacer ContainerPlacer::at(int x, int y)
+{
+ return ContainerPlacer(mContainer, &mCell->at(x, y));
+}
+
+LayoutCell &ContainerPlacer::operator()
+ (int x, int y, gcn::Widget *wg, int w, int h)
+{
+ mContainer->add(wg);
+ return mCell->place(wg, x, y, w, h);
+}
+
+LayoutCell::~LayoutCell()
+{
+ if (mType == ARRAY) delete mArray;
+}
+
+LayoutArray &LayoutCell::getArray()
+{
+ assert(mType != WIDGET);
+ if (mType == ARRAY) return *mArray;
+ mArray = new LayoutArray;
+ mType = ARRAY;
+ mExtent[0] = 1;
+ mExtent[1] = 1;
+ mPadding = 0;
+ mAlign[0] = FILL;
+ mAlign[1] = FILL;
+ return *mArray;
+}
+
+void LayoutCell::reflow(int nx, int ny, int nw, int nh)
+{
+ assert(mType != NONE);
+ nx += mPadding;
+ ny += mPadding;
+ nw -= 2 * mPadding;
+ nh -= 2 * mPadding;
+ if (mType == ARRAY)
+ mArray->reflow(nx, ny, nw, nh);
+ else
+ mWidget->setDimension(gcn::Rectangle(nx, ny, nw, nh));
+}
+
+void LayoutCell::computeSizes()
+{
+ assert(mType == ARRAY);
+
+ for (std::vector< std::vector< LayoutCell * > >::iterator
+ i = mArray->mCells.begin(), i_end = mArray->mCells.end();
+ i != i_end; ++i)
+ {
+ for (std::vector< LayoutCell * >::iterator
+ j = i->begin(), j_end = i->end(); j != j_end; ++j)
+ {
+ LayoutCell *cell = *j;
+ if (cell && cell->mType == ARRAY) cell->computeSizes();
+ }
+ }
+
+ mSize[0] = mArray->getSize(0);
+ mSize[1] = mArray->getSize(1);
+}
+
+LayoutArray::LayoutArray(): mSpacing(4)
+{
+}
+
+LayoutArray::~LayoutArray()
+{
+ for (std::vector< std::vector< LayoutCell * > >::iterator
+ i = mCells.begin(), i_end = mCells.end(); i != i_end; ++i)
+ {
+ for (std::vector< LayoutCell * >::iterator
+ j = i->begin(), j_end = i->end(); j != j_end; ++j)
+ {
+ delete *j;
+ }
+ }
+}
+
+LayoutCell &LayoutArray::at(int x, int y, int w, int h)
+{
+ resizeGrid(x + w, y + h);
+ LayoutCell *&cell = mCells[y][x];
+ if (!cell)
+ {
+ cell = new LayoutCell;
+ }
+ return *cell;
+}
+
+void LayoutArray::resizeGrid(int w, int h)
+{
+ bool extW = w && w > (int)mSizes[0].size(),
+ extH = h && h > (int)mSizes[1].size();
+ if (!extW && !extH) return;
+
+ if (extH)
+ {
+ mSizes[1].resize(h, Layout::AUTO_DEF);
+ mCells.resize(h);
+ if (!extW) w = mSizes[0].size();
+ }
+
+ if (extW)
+ {
+ mSizes[0].resize(w, Layout::AUTO_DEF);
+ }
+
+ for (std::vector< std::vector< LayoutCell * > >::iterator
+ i = mCells.begin(), i_end = mCells.end(); i != i_end; ++i)
+ {
+ i->resize(w, NULL);
+ }
+}
+
+void LayoutArray::setColWidth(int n, int w)
+{
+ resizeGrid(n + 1, 0);
+ mSizes[0][n] = w;
+}
+
+void LayoutArray::setRowHeight(int n, int h)
+{
+ resizeGrid(0, n + 1);
+ mSizes[1][n] = h;
+}
+
+void LayoutArray::matchColWidth(int n1, int n2)
+{
+ resizeGrid(std::max(n1, n2) + 1, 0);
+ std::vector< short > widths = getSizes(0, Layout::AUTO_DEF);
+ int s = std::max(widths[n1], widths[n2]);
+ mSizes[0][n1] = s;
+ mSizes[0][n2] = s;
+}
+
+void LayoutArray::extend(int x, int y, int w, int h)
+{
+ LayoutCell &cell = at(x, y, w, h);
+ cell.mExtent[0] = w;
+ cell.mExtent[1] = h;
+}
+
+LayoutCell &LayoutArray::place(gcn::Widget *widget, int x, int y, int w, int h)
+{
+ LayoutCell &cell = at(x, y, w, h);
+ assert(cell.mType == LayoutCell::NONE);
+ cell.mType = LayoutCell::WIDGET;
+ cell.mWidget = widget;
+ cell.mSize[0] = w == 1 ? widget->getWidth() : 0;
+ cell.mSize[1] = h == 1 ? widget->getHeight() : 0;
+ cell.mExtent[0] = w;
+ cell.mExtent[1] = h;
+ cell.mPadding = 0;
+ cell.mAlign[0] = LayoutCell::FILL;
+ cell.mAlign[1] = LayoutCell::FILL;
+ short &cs = mSizes[0][x], &rs = mSizes[1][y];
+ if (cs == Layout::AUTO_DEF && w == 1) cs = 0;
+ if (rs == Layout::AUTO_DEF && h == 1) rs = 0;
+ return cell;
+}
+
+void LayoutArray::align(int &pos, int &size, int dim,
+ LayoutCell const &cell, short *sizes) const
+{
+ int size_max = sizes[0];
+ for (int i = 1; i < cell.mExtent[dim]; ++i)
+ size_max += sizes[i] + mSpacing;
+ size = std::min<int>(cell.mSize[dim], size_max);
+
+ switch (cell.mAlign[dim])
+ {
+ case LayoutCell::LEFT:
+ return;
+ case LayoutCell::RIGHT:
+ pos += size_max - size;
+ return;
+ case LayoutCell::CENTER:
+ pos += (size_max - size) / 2;
+ return;
+ case LayoutCell::FILL:
+ size = size_max;
+ return;
+ }
+}
+
+std::vector< short > LayoutArray::getSizes(int dim, int upp) const
+{
+ int gridW = mSizes[0].size(), gridH = mSizes[1].size();
+ std::vector< short > sizes = mSizes[dim];
+
+ // Compute minimum sizes.
+ for (int gridY = 0; gridY < gridH; ++gridY)
+ {
+ for (int gridX = 0; gridX < gridW; ++gridX)
+ {
+ LayoutCell const *cell = mCells[gridY][gridX];
+ if (!cell || cell->mType == LayoutCell::NONE) continue;
+
+ if (cell->mExtent[dim] == 1)
+ {
+ int n = dim == 0 ? gridX : gridY;
+ int s = cell->mSize[dim] + cell->mPadding * 2;
+ if (s > sizes[n]) sizes[n] = s;
+ }
+ }
+ }
+
+ if (upp == Layout::AUTO_DEF) return sizes;
+
+ // Compute the FILL sizes.
+ int nb = sizes.size();
+ int nbFill = 0;
+ for (int i = 0; i < nb; ++i)
+ {
+ if (mSizes[dim][i] <= Layout::AUTO_DEF)
+ {
+ ++nbFill;
+ if (mSizes[dim][i] == Layout::AUTO_SET ||
+ sizes[i] <= Layout::AUTO_DEF)
+ {
+ sizes[i] = 0;
+ }
+ }
+ upp -= sizes[i] + mSpacing;
+ }
+ upp = upp + mSpacing;
+
+ if (nbFill == 0) return sizes;
+
+ for (int i = 0; i < nb; ++i)
+ {
+ if (mSizes[dim][i] > Layout::AUTO_DEF) continue;
+ int s = upp / nbFill;
+ sizes[i] += s;
+ upp -= s;
+ --nbFill;
+ }
+
+ return sizes;
+}
+
+int LayoutArray::getSize(int dim) const
+{
+ std::vector< short > sizes = getSizes(dim, Layout::AUTO_DEF);
+ int size = 0;
+ int nb = sizes.size();
+ for (int i = 0; i < nb; ++i)
+ {
+ if (sizes[i] > Layout::AUTO_DEF) size += sizes[i];
+ size += mSpacing;
+ }
+ return size - mSpacing;
+}
+
+void LayoutArray::reflow(int nx, int ny, int nw, int nh)
+{
+ int gridW = mSizes[0].size(), gridH = mSizes[1].size();
+
+ std::vector< short > widths = getSizes(0, nw);
+ std::vector< short > heights = getSizes(1, nh);
+
+ int y = ny;
+ for (int gridY = 0; gridY < gridH; ++gridY)
+ {
+ int x = nx;
+ for (int gridX = 0; gridX < gridW; ++gridX)
+ {
+ LayoutCell *cell = mCells[gridY][gridX];
+ if (cell && cell->mType != LayoutCell::NONE)
+ {
+ int dx = x, dy = y, dw, dh;
+ align(dx, dw, 0, *cell, &widths[gridX]);
+ align(dy, dh, 1, *cell, &heights[gridY]);
+ cell->reflow(dx, dy, dw, dh);
+ }
+ x += widths[gridX] + mSpacing;
+ }
+ y += heights[gridY] + mSpacing;
+ }
+}
+
+Layout::Layout(): mComputed(false)
+{
+ getArray();
+ setPadding(6);
+}
+
+void Layout::reflow(int &nw, int &nh)
+{
+ if (!mComputed)
+ {
+ computeSizes();
+ mComputed = true;
+ }
+
+ nw = nw == 0 ? mSize[0] + 2 * mPadding : nw;
+ nh = nh == 0 ? mSize[1] + 2 * mPadding : nh;
+ LayoutCell::reflow(0, 0, nw, nh);
+}
diff --git a/src/gui/widgets/layout.h b/src/gui/widgets/layout.h
new file mode 100644
index 00000000..d631c154
--- /dev/null
+++ b/src/gui/widgets/layout.h
@@ -0,0 +1,320 @@
+/*
+ * The Mana World
+ * Copyright 2007 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * The Mana World 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.
+ *
+ * The Mana World 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 The Mana World; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _TMW_WIDGET_LAYOUT_H__
+#define _TMW_WIDGET_LAYOUT_H__
+
+#include <vector>
+
+#include <guichan/widgets/container.hpp>
+
+class LayoutCell;
+
+/**
+ * This class is a helper for adding widgets to nested tables in a window.
+ */
+class ContainerPlacer
+{
+ public:
+
+ ContainerPlacer(gcn::Container *c = NULL, LayoutCell *l = NULL):
+ mContainer(c), mCell(l)
+ {}
+
+ /**
+ * Gets the pointed cell.
+ */
+ LayoutCell &getCell()
+ { return *mCell; }
+
+ /**
+ * Returns a placer for the same container but to an inner cell.
+ */
+ ContainerPlacer at(int x, int y);
+
+ /**
+ * Adds the given widget to the container and places it in the layout.
+ * @see LayoutArray::place
+ */
+ LayoutCell &operator()
+ (int x, int y, gcn::Widget *, int w = 1, int h = 1);
+
+ private:
+
+ gcn::Container *mContainer;
+ LayoutCell *mCell;
+};
+
+/**
+ * This class contains a rectangular array of cells.
+ */
+class LayoutArray
+{
+ friend class LayoutCell;
+
+ public:
+
+ LayoutArray();
+
+ ~LayoutArray();
+
+ /**
+ * Returns a reference on the cell at given position.
+ */
+ LayoutCell &at(int x, int y, int w = 1, int h = 1);
+
+ /**
+ * Places a widget in a given cell.
+ * @param w number of columns the widget spawns.
+ * @param h number of rows the widget spawns.
+ * @note When @a w is 1, the width of column @a x is reset to zero if
+ * it was AUTO_DEF. Similarly for @a h.
+ */
+ LayoutCell &place(gcn::Widget *, int x, int y, int w = 1, int h = 1);
+
+ /**
+ * Sets the minimum width of a column.
+ */
+ void setColWidth(int n, int w);
+
+ /**
+ * Sets the minimum height of a row.
+ */
+ void setRowHeight(int n, int h);
+
+ /**
+ * Sets the widths of two columns to the maximum of their widths.
+ */
+ void matchColWidth(int n1, int n2);
+
+ /**
+ * Spawns a cell over several columns/rows.
+ */
+ void extend(int x, int y, int w, int h);
+
+ /**
+ * Computes and sets the positions of all the widgets.
+ * @param nW width of the array, used to resize the AUTO_ columns.
+ * @param nH height of the array, used to resize the AUTO_ rows.
+ */
+ void reflow(int nX, int nY, int nW, int nH);
+
+ private:
+
+ // Copy not allowed, as the array owns all its cells.
+ LayoutArray(LayoutArray const &);
+ LayoutArray &operator=(LayoutArray const &);
+
+ /**
+ * Gets the position and size of a widget along a given axis
+ */
+ void align(int &pos, int &size, int dim,
+ LayoutCell const &cell, short *sizes) const;
+
+ /**
+ * Ensures the private vectors are large enough.
+ */
+ void resizeGrid(int w, int h);
+
+ /**
+ * Gets the column/row sizes along a given axis.
+ * @param upp target size for the array. Ignored if AUTO_DEF.
+ */
+ std::vector< short > getSizes(int dim, int upp) const;
+
+ /**
+ * Gets the total size along a given axis.
+ */
+ int getSize(int dim) const;
+
+ std::vector< short > mSizes[2];
+ std::vector< std::vector < LayoutCell * > > mCells;
+
+ char mSpacing;
+};
+
+/**
+ * This class describes the formatting of a widget in the cell of a layout
+ * table. Horizontally, a widget can either fill the width of the cell (minus
+ * the cell padding), or it can retain its size and be flushed left, or flush
+ * right, or centered in the cell. The process is similar for the vertical
+ * alignment, except that top is represented by LEFT and bottom by RIGHT.
+ */
+class LayoutCell
+{
+ friend class Layout;
+ friend class LayoutArray;
+
+ public:
+
+ enum Alignment
+ {
+ LEFT, RIGHT, CENTER, FILL
+ };
+
+ LayoutCell(): mType(NONE) {}
+
+ ~LayoutCell();
+
+ /**
+ * Sets the padding around the cell content.
+ */
+ LayoutCell &setPadding(int p)
+ { mPadding = p; return *this; }
+
+ /**
+ * Sets the horizontal alignment of the cell content.
+ */
+ LayoutCell &setHAlign(Alignment a)
+ { mAlign[0] = a; return *this; }
+
+ /**
+ * Sets the vertical alignment of the cell content.
+ */
+ LayoutCell &setVAlign(Alignment a)
+ { mAlign[1] = a; return *this; }
+
+ /**
+ * @see LayoutArray::at
+ */
+ LayoutCell &at(int x, int y)
+ { return getArray().at(x, y); }
+
+ /**
+ * @see LayoutArray::place
+ */
+ LayoutCell &place(gcn::Widget *wg, int x, int y, int w = 1, int h = 1)
+ { return getArray().place(wg, x, y, w, h); }
+
+ /**
+ * @see LayoutArray::matchColWidth
+ */
+ void matchColWidth(int n1, int n2)
+ { getArray().matchColWidth(n1, n2); }
+
+ /**
+ * @see LayoutArray::setColWidth
+ */
+ void setColWidth(int n, int w)
+ { getArray().setColWidth(n, w); }
+
+ /**
+ * @see LayoutArray::setRowHeight
+ */
+ void setRowHeight(int n, int h)
+ { getArray().setRowHeight(n, h); }
+
+ /**
+ * @see LayoutArray::extend.
+ */
+ void extend(int x, int y, int w, int h)
+ { getArray().extend(x, y, w, h); }
+
+ /**
+ * Sets the minimum widths and heights of this cell and of all the
+ * inner cells.
+ */
+ void computeSizes();
+
+ private:
+
+ // Copy not allowed, as the cell may own an array.
+ LayoutCell(LayoutCell const &);
+ LayoutCell &operator=(LayoutCell const &);
+
+ union
+ {
+ gcn::Widget *mWidget;
+ LayoutArray *mArray;
+ };
+
+ enum
+ {
+ NONE, WIDGET, ARRAY
+ };
+
+ /**
+ * Returns the embedded array. Creates it if the cell does not contain
+ * anything yet. Aborts if it contains a widget.
+ */
+ LayoutArray &getArray();
+
+ /**
+ * @see LayoutArray::reflow
+ */
+ void reflow(int nx, int ny, int nw, int nh);
+
+ short mSize[2];
+ char mPadding;
+ char mExtent[2];
+ char mAlign[2];
+ char mNbFill[2];
+ char mType;
+};
+
+/**
+ * This class is an helper for setting the position of widgets. They are
+ * positioned along the cells of some rectangular tables. The layout may either
+ * be a single table or a tree of nested tables.
+ *
+ * The size of a given table column can either be set manually or be chosen
+ * from the widest widget of the column. An empty column has a AUTO_DEF width,
+ * which means it will be extended so that the layout fits its minimum width.
+ *
+ * The process is similar for table rows. By default, there is a spacing of 4
+ * pixels between rows and between columns, and a margin of 6 pixels around the
+ * whole layout.
+ */
+class Layout: public LayoutCell
+{
+ public:
+
+ Layout();
+
+ /**
+ * Sets the margin around the layout.
+ */
+ void setMargin(int m)
+ { setPadding(m); }
+
+ /**
+ * Sets the positions of all the widgets.
+ * @see LayoutArray::reflow
+ */
+ void reflow(int &nW, int &nH);
+
+ /**
+ * When the minimum size of the layout is less than the available size,
+ * the remaining pixels are equally split amongst the FILL items.
+ */
+ enum
+ {
+ AUTO_DEF = -42, /**< Default value, behaves like AUTO_ADD. */
+ AUTO_SET = -43, /**< Uses the share as the new size. */
+ AUTO_ADD = -44 /**< Adds the share to the current size. */
+ };
+
+ private:
+
+ bool mComputed;
+};
+
+#endif
diff --git a/src/gui/window.cpp b/src/gui/window.cpp
index 630b4ddd..dfe7ac64 100644
--- a/src/gui/window.cpp
+++ b/src/gui/window.cpp
@@ -20,8 +20,8 @@
*/
#include <algorithm>
-#include <climits>
#include <cassert>
+#include <climits>
#include <guichan/exception.hpp>
#include <guichan/widgets/icon.hpp>
@@ -29,9 +29,9 @@
#include "window.h"
#include "gui.h"
-#include "gccontainer.h"
#include "windowcontainer.h"
+#include "widgets/layout.h"
#include "widgets/resizegrip.h"
#include "../configlistener.h"
@@ -63,6 +63,7 @@ Window::Window(const std::string& caption, bool modal, Window *parent):
gcn::Window(caption),
mGrip(0),
mParent(parent),
+ mLayout(NULL),
mWindowName("window"),
mShowTitle(true),
mModal(modal),
@@ -76,7 +77,7 @@ Window::Window(const std::string& caption, bool modal, Window *parent):
logger->log("Window::Window(\"%s\")", caption.c_str());
if (!windowContainer) {
- throw GCN_EXCEPTION("Window::Window. no windowContainer set");
+ throw GCN_EXCEPTION("Window::Window(): no windowContainer set");
}
if (instances == 0)
@@ -108,11 +109,6 @@ Window::Window(const std::string& caption, bool modal, Window *parent):
setPadding(3);
setTitleBarHeight(20);
- // Add chrome
- mChrome = new GCContainer();
- mChrome->setOpaque(false);
- gcn::Window::add(mChrome);
-
// Add this window to the window container
windowContainer->add(this);
@@ -145,6 +141,15 @@ Window::~Window()
}
}
+ delete mLayout;
+
+ while (!mWidgets.empty())
+ {
+ gcn::Widget *w = mWidgets.front();
+ remove(w);
+ delete(w);
+ }
+
instances--;
if (instances == 0)
@@ -165,9 +170,6 @@ Window::~Window()
delete border.grid[8];
closeImage->decRef();
}
-
- delete mChrome;
- delete mGrip;
}
void Window::setWindowContainer(WindowContainer *wc)
@@ -202,7 +204,6 @@ void Window::draw(gcn::Graphics *graphics)
void Window::setContentSize(int width, int height)
{
- mChrome->setSize(width, height);
setSize(width + 2 * getPadding(),
height + getPadding() + getTitleBarHeight());
}
@@ -248,10 +249,11 @@ void Window::setResizable(bool r)
mGrip = new ResizeGrip();
mGrip->setX(getWidth() - mGrip->getWidth() - getChildrenArea().x);
mGrip->setY(getHeight() - mGrip->getHeight() - getChildrenArea().y);
- gcn::Window::add(mGrip);
+ add(mGrip);
}
else
{
+ remove(mGrip);
delete mGrip;
mGrip = 0;
}
@@ -259,15 +261,19 @@ void Window::setResizable(bool r)
void Window::widgetResized(const gcn::Event &event)
{
- const gcn::Rectangle area = getChildrenArea();
-
- mChrome->setSize(area.width, area.height);
-
if (mGrip)
{
+ const gcn::Rectangle area = getChildrenArea();
mGrip->setPosition(getWidth() - mGrip->getWidth() - area.x,
getHeight() - mGrip->getHeight() - area.y);
}
+
+ if (mLayout)
+ {
+ int w = getWidth() - 2 * getPadding();
+ int h = getHeight() - getPadding() - getTitleBarHeight();
+ mLayout->reflow(w, h);
+ }
}
void Window::setCloseButton(bool flag)
@@ -292,14 +298,7 @@ bool Window::isSticky()
void Window::setVisible(bool visible)
{
- if (isSticky())
- {
- gcn::Window::setVisible(true);
- }
- else
- {
- gcn::Window::setVisible(visible);
- }
+ gcn::Window::setVisible(isSticky() || visible);
}
void Window::scheduleDelete()
@@ -307,16 +306,6 @@ void Window::scheduleDelete()
windowContainer->scheduleDelete(this);
}
-void Window::add(gcn::Widget *w)
-{
- mChrome->add(w);
-}
-
-void Window::add(gcn::Widget *w, int x, int y)
-{
- mChrome->add(w, x, y);
-}
-
void Window::mousePressed(gcn::MouseEvent &event)
{
// Let Guichan move window to top and figure out title bar drag
@@ -535,3 +524,29 @@ int Window::getResizeHandles(gcn::MouseEvent &event)
return resizeHandles;
}
+
+Layout &Window::getLayout()
+{
+ if (!mLayout) mLayout = new Layout;
+ return *mLayout;
+}
+
+LayoutCell &Window::place(int x, int y, gcn::Widget *wg, int w, int h)
+{
+ add(wg);
+ return getLayout().place(wg, x, y, w, h);
+}
+
+ContainerPlacer Window::getPlacer(int x, int y)
+{
+ return ContainerPlacer(this, &getLayout().at(x, y));
+}
+
+void Window::reflowLayout(int w, int h)
+{
+ assert(mLayout);
+ mLayout->reflow(w, h);
+ delete mLayout;
+ mLayout = NULL;
+ setContentSize(w, h);
+}
diff --git a/src/gui/window.h b/src/gui/window.h
index 984c6f06..a49788a5 100644
--- a/src/gui/window.h
+++ b/src/gui/window.h
@@ -28,11 +28,13 @@
#include "../guichanfwd.h"
class ConfigListener;
-class GCContainer;
+class ContainerPlacer;
+class Image;
class ImageRect;
+class Layout;
+class LayoutCell;
class ResizeGrip;
class WindowContainer;
-class Image;
/**
* A window. This window can be dragged around and has a title bar. Windows are
@@ -59,7 +61,7 @@ class Window : public gcn::Window, gcn::WidgetListener
Window *parent = NULL);
/**
- * Destructor.
+ * Destructor. Deletes all the added widgets.
*/
~Window();
@@ -74,18 +76,6 @@ class Window : public gcn::Window, gcn::WidgetListener
void draw(gcn::Graphics *graphics);
/**
- * Adds a widget to the window. The widget will be deleted by the
- * window.
- */
- void add(gcn::Widget *w);
-
- /**
- * Adds a widget to the window and also specifices its position. The
- * widget will be deleted by the window.
- */
- void add(gcn::Widget *w, int x, int y);
-
- /**
* Sets the size of this window.
*/
void setContentSize(int width, int height);
@@ -163,8 +153,7 @@ class Window : public gcn::Window, gcn::WidgetListener
*
* @return The parent window or <code>NULL</code> if there is none.
*/
- Window*
- getParentWindow() { return mParent; }
+ Window *getParentWindow() { return mParent; }
/**
* Schedule this window for deletion. It will be deleted at the start
@@ -204,14 +193,12 @@ class Window : public gcn::Window, gcn::WidgetListener
/**
* Sets the name of the window. This is not the window title.
*/
- void
- setWindowName(const std::string &name) { mWindowName = name; }
+ void setWindowName(const std::string &name) { mWindowName = name; }
/**
* Returns the name of the window. This is not the window title.
*/
- const std::string&
- getWindowName() { return mWindowName; }
+ const std::string &getWindowName() { return mWindowName; }
/**
* Reads the position (and the size for resizable windows) in the
@@ -220,21 +207,51 @@ class Window : public gcn::Window, gcn::WidgetListener
* Don't forget to set these default values and resizable before
* calling this function.
*/
- virtual void loadWindowState();
+ void loadWindowState();
/**
* Set the default win pos and size.
* (which can be different of the actual ones.)
*/
- virtual void setDefaultSize(int defaultX, int defaultY,
- int defaultWidth, int defaultHeight);
+ void setDefaultSize(int defaultX, int defaultY,
+ int defaultWidth, int defaultHeight);
/**
* Reset the win pos and size to default. Don't forget to set defaults
* first.
*/
- virtual void resetToDefaultSize();
+ void resetToDefaultSize();
+
+ /**
+ * Gets the layout handler for this window.
+ */
+ Layout &getLayout();
+
+ /**
+ * Computes the position of the widgets according to the current
+ * layout. Resizes the window so that the layout fits. Deletes the
+ * layout.
+ * @param w if non-zero, force the window to this width.
+ * @param h if non-zero, force the window to this height.
+ * @note This function is meant to be called with fixed-size windows.
+ */
+ void reflowLayout(int w = 0, int h = 0);
+ /**
+ * 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);
+
+ /**
+ * Returns a proxy for adding widgets in an inner table of the layout.
+ */
+ ContainerPlacer getPlacer(int x, int y);
+
+ protected:
+ /** The window container windows add themselves to. */
+ static WindowContainer *windowContainer;
+
+ private:
enum ResizeHandles
{
TOP = 0x01,
@@ -243,7 +260,6 @@ class Window : public gcn::Window, gcn::WidgetListener
LEFT = 0x08
};
- protected:
/**
* Determines if the mouse is in a resize area and returns appropriate
* resize handles. Also initializes drag offset in case the resize
@@ -253,9 +269,9 @@ class Window : public gcn::Window, gcn::WidgetListener
*/
int getResizeHandles(gcn::MouseEvent &event);
- GCContainer *mChrome; /**< Contained container */
ResizeGrip *mGrip; /**< Resize grip */
Window *mParent; /**< The parent window */
+ Layout *mLayout; /**< Layout handler */
std::string mWindowName; /**< Name of the window */
bool mShowTitle; /**< Window has a title bar */
bool mModal; /**< Window is modal */
@@ -270,9 +286,6 @@ class Window : public gcn::Window, gcn::WidgetListener
int mDefaultWidth; /**< Default window width */
int mDefaultHeight; /**< Default window height */
- /** The window container windows add themselves to. */
- static WindowContainer *windowContainer;
-
/**
* The config listener that listens to changes relevant to all windows.
*/