summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/buy.cpp117
-rw-r--r--src/gui/buy.h6
-rw-r--r--src/gui/chat.cpp4
-rw-r--r--src/gui/chat.h4
-rw-r--r--src/gui/debugwindow.cpp10
-rw-r--r--src/gui/debugwindow.h1
-rw-r--r--src/gui/inventorywindow.cpp7
-rw-r--r--src/gui/sell.cpp159
-rw-r--r--src/gui/sell.h6
-rw-r--r--src/gui/updatewindow.cpp7
-rw-r--r--src/gui/viewport.cpp108
-rw-r--r--src/gui/viewport.h20
-rw-r--r--src/gui/widgets/resizegrip.cpp65
-rw-r--r--src/gui/widgets/resizegrip.h61
-rw-r--r--src/gui/window.cpp185
-rw-r--r--src/gui/window.h66
16 files changed, 531 insertions, 295 deletions
diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp
index cb07da22..2a8616f8 100644
--- a/src/gui/buy.cpp
+++ b/src/gui/buy.cpp
@@ -111,27 +111,21 @@ void BuyDialog::setMoney(int amount)
{
mMoney = amount;
mShopItemList->setPlayersMoney(amount);
- mMoneyLabel->setCaption("Price: 0 GP / " + toString(mMoney) + " GP");
- mMoneyLabel->adjustSize();
+
+ updateButtonsAndLabels();
}
void BuyDialog::reset()
{
mShopItems->clear();
+ mShopItemList->adjustSize();
mMoney = 0;
mSlider->setValue(0.0);
- mAmountItems = 0;
// Reset Previous Selected Items to prevent failing asserts
mShopItemList->setSelected(-1);
- mIncreaseButton->setEnabled(false);
- mDecreaseButton->setEnabled(false);
- mQuantityLabel->setCaption("0");
- mQuantityLabel->adjustSize();
- mMoneyLabel->setCaption("Price: 0 GP / " + toString(mMoney) + " GP");
- mMoneyLabel->adjustSize();
- mItemDescLabel->setCaption("");
- mItemEffectLabel->setCaption("");
+
+ updateButtonsAndLabels();
}
void BuyDialog::addItem(short id, int price)
@@ -151,45 +145,36 @@ void BuyDialog::action(const gcn::ActionEvent &event)
}
// The following actions require a valid selection
- if (selectedItem < 0 || selectedItem >= int(mShopItems->getNumberOfElements()))
+ if (selectedItem < 0 ||
+ selectedItem >= (int) mShopItems->getNumberOfElements())
{
return;
}
- bool updateButtonsAndLabels = false;
-
if (event.getId() == "slider")
{
mAmountItems = (int)(mSlider->getValue() * mMaxItems);
- updateButtonsAndLabels = true;
+ updateButtonsAndLabels();
}
- else if (event.getId() == "+")
+ else if (event.getId() == "+" && mAmountItems < mMaxItems)
{
- if (mAmountItems < mMaxItems) {
- mAmountItems++;
- } else {
- mAmountItems = mMaxItems;
- }
+ mAmountItems++;
- mSlider->setValue(double(mAmountItems)/double(mMaxItems));
- updateButtonsAndLabels = true;
+ mSlider->setValue((double) mAmountItems / (double) mMaxItems);
+ updateButtonsAndLabels();
}
- else if (event.getId() == "-")
+ else if (event.getId() == "-" && mAmountItems > 0)
{
- if (mAmountItems > 0) {
- mAmountItems--;
- } else {
- mAmountItems = 0;
- }
+ mAmountItems--;
- mSlider->setValue(double(mAmountItems)/double(mMaxItems));
- updateButtonsAndLabels = true;
+ mSlider->setValue((double) mAmountItems / (double) mMaxItems);
+ updateButtonsAndLabels();
}
// TODO: Actually we'd have a bug elsewhere if this check for the number
// of items to be bought ever fails, Bertram removed the assertions, is
// there a better way to ensure this fails in an _obivous_ way in C++?
- else if (event.getId() == "buy" && (mAmountItems > 0 &&
- mAmountItems <= mMaxItems))
+ else if (event.getId() == "buy" && mAmountItems > 0 &&
+ mAmountItems <= mMaxItems)
{
// XXX Convert for new server
/*
@@ -199,38 +184,15 @@ void BuyDialog::action(const gcn::ActionEvent &event)
outMsg.writeShort(mShopItems->at(selectedItem).id);
*/
- // update money !
+ // Update money and adjust the max number of items that can be bought
mMoney -= mAmountItems * mShopItems->at(selectedItem).price;
- // Update number of items that can be bought at max
mMaxItems -= mAmountItems;
- if (!mMaxItems) {
- mSlider->setEnabled(false);
- }
-
// Reset selection
mAmountItems = 0;
- mSlider->setValue(0);
-
- updateButtonsAndLabels = true;
- }
+ mSlider->setValue(0.0);
- // If anything has changed, we have to update the buttons and labels
- if (updateButtonsAndLabels)
- {
- // Update buttons
- mIncreaseButton->setEnabled(mAmountItems < mMaxItems);
- mDecreaseButton->setEnabled(mAmountItems > 0);
- mBuyButton->setEnabled(mAmountItems > 0);
-
- // Update labels
- mQuantityLabel->setCaption(toString(mAmountItems));
- mQuantityLabel->adjustSize();
-
- int price = mAmountItems * mShopItems->at(selectedItem).price;
- mMoneyLabel->setCaption("Price: " + toString(price) + " GP / "
- + toString(mMoney) + " GP" );
- mMoneyLabel->adjustSize();
+ updateButtonsAndLabels();
}
}
@@ -238,17 +200,16 @@ void BuyDialog::selectionChanged(const SelectionEvent &event)
{
// Reset amount of items and update labels
mAmountItems = 0;
- mSlider->setValue(0);
- mQuantityLabel->setCaption("0");
- mQuantityLabel->adjustSize();
- mMoneyLabel->setCaption("Price: 0 GP / " + toString(mMoney) + " GP");
- mMoneyLabel->adjustSize();
+ mSlider->setValue(0.0);
- // Disable buttons for buying and decreasing
- mBuyButton->setEnabled(false);
- mDecreaseButton->setEnabled(false);
+ updateButtonsAndLabels();
+}
+void
+BuyDialog::updateButtonsAndLabels()
+{
int selectedItem = mShopItemList->getSelected();
+ int price = 0;
if (selectedItem > -1)
{
@@ -259,16 +220,32 @@ void BuyDialog::selectionChanged(const SelectionEvent &event)
// Calculate how many the player can afford
mMaxItems = mMoney / mShopItems->at(selectedItem).price;
+ if (mAmountItems > mMaxItems)
+ {
+ mAmountItems = mMaxItems;
+ }
+
+ // Calculate price of pending purchase
+ price = mAmountItems * mShopItems->at(selectedItem).price;
}
else
{
mItemDescLabel->setCaption("Description:");
mItemEffectLabel->setCaption("Effect:");
mMaxItems = 0;
+ mAmountItems = 0;
}
- // When at least one item can be bought, enable the slider and the
- // increase button
- mIncreaseButton->setEnabled(mMaxItems > 0);
+ // Enable or disable buttons and slider
+ mIncreaseButton->setEnabled(mAmountItems < mMaxItems);
+ mDecreaseButton->setEnabled(mAmountItems > 0);
+ mBuyButton->setEnabled(mAmountItems > 0);
mSlider->setEnabled(mMaxItems > 0);
+
+ // Update quantity and money labels
+ mQuantityLabel->setCaption(toString(mAmountItems));
+ mQuantityLabel->adjustSize();
+ mMoneyLabel->setCaption("Price: " + toString(price) + " GP / "
+ + toString(mMoney - price) + " GP" );
+ mMoneyLabel->adjustSize();
}
diff --git a/src/gui/buy.h b/src/gui/buy.h
index 13116b6e..7834a434 100644
--- a/src/gui/buy.h
+++ b/src/gui/buy.h
@@ -92,6 +92,12 @@ class BuyDialog : public Window, public gcn::ActionListener, SelectionListener
*/
std::string getElementAt(int i);
+ /**
+ * Updates the state of buttons and labels.
+ */
+ void
+ updateButtonsAndLabels();
+
private:
gcn::Button *mBuyButton;
gcn::Button *mQuitButton;
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
index eb6b7612..48df9efe 100644
--- a/src/gui/chat.cpp
+++ b/src/gui/chat.cpp
@@ -160,7 +160,7 @@ ChatWindow::chatLog(std::string line, int own, std::string channelName)
break;
case BY_OTHER:
tmp.nick += CAT_NORMAL;
- lineColor = "##4"; // Equiv. to BrowserBox::ORANGE
+ lineColor = "##0"; // Equiv. to BrowserBox::BLACK
break;
case BY_SERVER:
tmp.nick += std::string("Server: ");
@@ -195,7 +195,7 @@ ChatWindow::chatLog(std::string line, int own, std::string channelName)
// We look if the Vertical Scroll Bar is set at the max before
// adding a row, otherwise the max will always be a row higher
// at comparison.
- if (mScrollArea->getVerticalScrollAmount() == mScrollArea->getVerticalMaxScroll() )
+ if (mScrollArea->getVerticalScrollAmount() == mScrollArea->getVerticalMaxScroll())
{
mTextOutput->addRow(line);
mScrollArea->setVerticalScrollAmount(mScrollArea->getVerticalMaxScroll());
diff --git a/src/gui/chat.h b/src/gui/chat.h
index c7e51ebf..6f9b91fe 100644
--- a/src/gui/chat.h
+++ b/src/gui/chat.h
@@ -168,13 +168,13 @@ class ChatWindow : public Window, public gcn::ActionListener,
/*
* Determines whether to send a command or an ordinary message, then
- * contructs packets & sends them
+ * contructs packets & sends them.
*
* @param nick The character's name to display in front.
* @param msg The message text which is to be send.
*
* NOTE:
- * the nickname is required by the server, if not specified
+ * The nickname is required by the server, if not specified
* the message may not be sent unless a command was intended
* which requires another packet to be constructed! you can
* achieve this by putting a slash ("/") infront of the
diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp
index 563f380f..ebf7d974 100644
--- a/src/gui/debugwindow.cpp
+++ b/src/gui/debugwindow.cpp
@@ -33,6 +33,7 @@
#include "../game.h"
#include "../engine.h"
+#include "../particle.h"
#include "../map.h"
#include "../utils/tostring.h"
@@ -58,6 +59,9 @@ DebugWindow::DebugWindow():
mTileMouseLabel = new gcn::Label("[Mouse: 0, 0]");
mTileMouseLabel->setPosition(100, 0);
+ mParticleCountLabel = new gcn::Label("[Particle count: 0]");
+ mParticleCountLabel->setPosition(100, 60);
+
Button *closeButton = new Button("Close", "close", this);
closeButton->setPosition(5, 60);
@@ -65,6 +69,7 @@ DebugWindow::DebugWindow():
add(mMusicFileLabel);
add(mMapFileLabel);
add(mTileMouseLabel);
+ add(mParticleCountLabel);
add(closeButton);
}
@@ -97,6 +102,11 @@ DebugWindow::logic()
mMapFileLabel->setCaption(minimap);
mMapFileLabel->adjustSize();
}
+
+ mParticleCountLabel->setCaption("[Particle count: " +
+ toString(Particle::particleCount)
+ +"]");
+ mParticleCountLabel->adjustSize();
}
void
diff --git a/src/gui/debugwindow.h b/src/gui/debugwindow.h
index 4fd33d83..d082b2ca 100644
--- a/src/gui/debugwindow.h
+++ b/src/gui/debugwindow.h
@@ -58,6 +58,7 @@ class DebugWindow : public Window, public gcn::ActionListener
private:
gcn::Label *mMusicFileLabel, *mMapFileLabel;
gcn::Label *mTileMouseLabel, *mFPSLabel;
+ gcn::Label *mParticleCountLabel;
};
#endif
diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp
index 44d042a6..2018c75a 100644
--- a/src/gui/inventorywindow.cpp
+++ b/src/gui/inventorywindow.cpp
@@ -165,8 +165,8 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event)
if (!item) return;
- /* Convert relative to the window coordinates to
- * absolute screen coordinates.
+ /* Convert relative to the window coordinates to absolute screen
+ * coordinates.
*/
int mx = event.getX() + getX();
int my = event.getY() + getY();
@@ -178,7 +178,8 @@ void InventoryWindow::mouseDragged(gcn::MouseEvent &event)
{
int tmpWidth = getWidth(), tmpHeight = getHeight();
Window::mouseDragged(event);
- if (getWidth() != tmpWidth || getHeight() != tmpHeight) {
+ if (getWidth() != tmpWidth || getHeight() != tmpHeight)
+ {
updateWidgets();
}
}
diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp
index c9878c84..478371b1 100644
--- a/src/gui/sell.cpp
+++ b/src/gui/sell.cpp
@@ -88,7 +88,7 @@ SellDialog::SellDialog():
quitButton->setPosition(208, 186);
mShopItemList->setActionEventId("item");
- mSlider->setActionEventId("mSlider");
+ mSlider->setActionEventId("slider");
mShopItemList->setPriceCheck(false);
@@ -119,20 +119,11 @@ void SellDialog::reset()
{
mShopItems->clear();
mSlider->setValue(0.0);
- mAmountItems = 0;
-
- mQuantityLabel->setCaption("0");
- mQuantityLabel->adjustSize();
- mMoneyLabel->setCaption("Money: 0 GP / Total: "
- + toString(mPlayerMoney) + " GP");
- mMoneyLabel->adjustSize();
- mItemDescLabel->setCaption("");
- mItemEffectLabel->setCaption("");
- // Reset Previous Selected Items to prevent failing asserts
+ // Reset previous selected item to prevent failing asserts
mShopItemList->setSelected(-1);
- mIncreaseButton->setEnabled(false);
- mDecreaseButton->setEnabled(false);
+
+ updateButtonsAndLabels();
}
void SellDialog::addItem(Item *item, int price)
@@ -162,25 +153,7 @@ void SellDialog::action(const gcn::ActionEvent &event)
{
mAmountItems = 0;
mSlider->setValue(0);
- mDecreaseButton->setEnabled(false);
- mSellButton->setEnabled(false);
-
- mQuantityLabel->adjustSize();
- mMoneyLabel->setCaption("Money: 0 GP / Total: "
- + toString(mPlayerMoney) + " GP");
- mMoneyLabel->adjustSize();
-
- if (selectedItem > -1) {
- mSlider->setEnabled(true);
- mIncreaseButton->setEnabled(true);
- mMaxItems = mShopItems->at(selectedItem).quantity;
- mQuantityLabel->setCaption("0 / " + toString(mMaxItems));
- } else {
- mSlider->setEnabled(false);
- mIncreaseButton->setEnabled(false);
- mQuantityLabel->setCaption("0");
- }
- mQuantityLabel->adjustSize();
+ updateButtonsAndLabels();
}
else if (event.getId() == "quit")
{
@@ -189,40 +162,35 @@ void SellDialog::action(const gcn::ActionEvent &event)
}
// The following actions require a valid item selection
- if (selectedItem == -1 || selectedItem >= int(mShopItems->getNumberOfElements())) {
+ if (selectedItem == -1 ||
+ selectedItem >= (int) mShopItems->getNumberOfElements())
+ {
return;
}
- bool updateButtonsAndLabels = false;
-
- if (event.getId() == "mSlider")
+ if (event.getId() == "slider")
{
- mAmountItems = (int)(mSlider->getValue() * mMaxItems);
-
- updateButtonsAndLabels = true;
+ mAmountItems = (int) (mSlider->getValue() * mMaxItems);
+ updateButtonsAndLabels();
}
- else if (event.getId() == "+")
+ else if (event.getId() == "+" && mAmountItems < mMaxItems)
{
- assert(mAmountItems < mMaxItems);
mAmountItems++;
- mSlider->setValue(double(mAmountItems)/double(mMaxItems));
- updateButtonsAndLabels = true;
+ mSlider->setValue((double) mAmountItems /(double) mMaxItems);
+ updateButtonsAndLabels();
}
- else if (event.getId() == "-")
+ else if (event.getId() == "-" && mAmountItems > 0)
{
- assert(mAmountItems > 0);
mAmountItems--;
- mSlider->setValue(double(mAmountItems)/double(mMaxItems));
-
- updateButtonsAndLabels = true;
+ mSlider->setValue((double) mAmountItems / (double) mMaxItems);
+ updateButtonsAndLabels();
}
- else if (event.getId() == "sell")
+ else if (event.getId() == "sell" && mAmountItems > 0
+ && mAmountItems <= mMaxItems)
{
// Attempt sell
- assert(mAmountItems > 0 && mAmountItems <= mMaxItems);
-
// XXX Convert for new server
/*
MessageOut outMsg(CMSG_NPC_SELL_REQUEST);
@@ -236,60 +204,77 @@ void SellDialog::action(const gcn::ActionEvent &event)
mPlayerMoney += (mAmountItems * mShopItems->at(selectedItem).price);
mAmountItems = 0;
mSlider->setValue(0);
- mSlider->setEnabled(mMaxItems != 0);
-
- // All were sold
- if (!mMaxItems) {
+ if (!mMaxItems)
+ {
+ // All were sold
mShopItemList->setSelected(-1);
- mShopItems->getShop()->erase(mShopItems->getShop()->begin() + selectedItem);
+ mShopItems->getShop()->erase(
+ mShopItems->getShop()->begin() + selectedItem);
+ }
+ else
+ {
+ // Update only when there are items left, the entry doesn't exist
+ // otherwise and can't be updated
+ updateButtonsAndLabels();
}
-
- // Update only when there are items left, the entry doesn't exist
- // otherwise and can't be updated
- updateButtonsAndLabels = bool(mMaxItems);
- }
-
- // If anything changed, we need to update the buttons and labels
- if (updateButtonsAndLabels)
- {
- // Update labels
- mQuantityLabel->setCaption(toString(mAmountItems) + " / " + toString(mMaxItems));
- mQuantityLabel->adjustSize();
-
- int price = mAmountItems * mShopItems->at(selectedItem).price;
- mMoneyLabel->setCaption("Money: " + toString(price) + " GP / Total: "
- + toString(price + mPlayerMoney) + " GP");
- mMoneyLabel->adjustSize();
-
- // Update Buttons
- mSellButton->setEnabled(mAmountItems > 0);
- mDecreaseButton->setEnabled(mAmountItems > 0);
- mIncreaseButton->setEnabled(mAmountItems < mMaxItems);
}
}
void SellDialog::selectionChanged(const SelectionEvent &event)
{
+ // Reset amount of items and update labels
+ mAmountItems = 0;
+ mSlider->setValue(0);
+
+ updateButtonsAndLabels();
+}
+
+void SellDialog::setMoney(int amount)
+{
+ mPlayerMoney = amount;
+ mShopItemList->setPlayersMoney(amount);
+}
+
+void
+SellDialog::updateButtonsAndLabels()
+{
int selectedItem = mShopItemList->getSelected();
+ int income = 0;
if (selectedItem > -1)
{
- const ItemInfo &info =
- ItemDB::get(mShopItems->at(selectedItem).id);
+ mMaxItems = mShopItems->at(selectedItem).quantity;
+ if (mAmountItems > mMaxItems)
+ {
+ mAmountItems = mMaxItems;
+ }
+ income = mAmountItems * mShopItems->at(selectedItem).price;
+
+ const ItemInfo &info = ItemDB::get(mShopItems->at(selectedItem).id);
mItemDescLabel->setCaption("Description: " + info.getDescription());
mItemEffectLabel->setCaption("Effect: " + info.getEffect());
}
else
{
- mItemDescLabel->setCaption("Description");
- mItemEffectLabel->setCaption("Effect");
+ mMaxItems = 0;
+ mAmountItems = 0;
+ mItemDescLabel->setCaption("Description:");
+ mItemEffectLabel->setCaption("Effect:");
}
-}
-void SellDialog::setMoney(int amount)
-{
- mPlayerMoney = amount;
- mShopItemList->setPlayersMoney(amount);
+ // Update Buttons and slider
+ mSellButton->setEnabled(mAmountItems > 0);
+ mDecreaseButton->setEnabled(mAmountItems > 0);
+ mIncreaseButton->setEnabled(mAmountItems < mMaxItems);
+ mSlider->setEnabled(selectedItem > -1);
+
+ // Update the quantity and money labels
+ mQuantityLabel->setCaption(
+ toString(mAmountItems) + " / " + toString(mMaxItems));
+ mQuantityLabel->adjustSize();
+ mMoneyLabel->setCaption("Money: " + toString(income) + " GP / Total: "
+ + toString(mPlayerMoney + income) + " GP");
+ mMoneyLabel->adjustSize();
}
diff --git a/src/gui/sell.h b/src/gui/sell.h
index 68bd7b8b..b8385a6f 100644
--- a/src/gui/sell.h
+++ b/src/gui/sell.h
@@ -82,6 +82,12 @@ class SellDialog : public Window, gcn::ActionListener, SelectionListener
*/
void setMoney(int amount);
+ /**
+ * Updates the state of buttons and labels.
+ */
+ void
+ updateButtonsAndLabels();
+
private:
gcn::Button *mSellButton;
gcn::Button *mIncreaseButton;
diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp
index d8130cd3..ed75e5b3 100644
--- a/src/gui/updatewindow.cpp
+++ b/src/gui/updatewindow.cpp
@@ -157,6 +157,7 @@ void UpdaterWindow::setLabel(const std::string &str)
void UpdaterWindow::enable()
{
+ mCancelButton->setEnabled(false);
mPlayButton->setEnabled(true);
mPlayButton->requestFocus();
}
@@ -168,11 +169,7 @@ void UpdaterWindow::action(const gcn::ActionEvent &event)
// Register the user cancel
mUserCancel = true;
// Skip the updating process
- if (mDownloadStatus == UPDATE_COMPLETE)
- {
- state = STATE_EXIT;
- }
- else
+ if (mDownloadStatus != UPDATE_COMPLETE)
{
mDownloadStatus = UPDATE_ERROR;
}
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index f3e9031c..2af1d960 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -41,10 +41,13 @@
#include "../resources/animation.h"
#include "../resources/monsterinfo.h"
#include "../resources/resourcemanager.h"
+#include "../resources/image.h"
#include "../resources/imageset.h"
#include "../utils/tostring.h"
+#include <cassert>
+
Viewport::Viewport():
mMap(0),
mViewX(0.0f),
@@ -67,37 +70,62 @@ Viewport::Viewport():
mPopupMenu = new PopupMenu();
// Load target cursors
+ loadTargetCursor("graphics/gui/target-cursor-blue-s.png", 44, 35,
+ false, Being::TC_SMALL);
+ loadTargetCursor("graphics/gui/target-cursor-red-s.png", 44, 35,
+ true, Being::TC_SMALL);
+ loadTargetCursor("graphics/gui/target-cursor-blue-m.png", 62, 44,
+ false, Being::TC_MEDIUM);
+ loadTargetCursor("graphics/gui/target-cursor-red-m.png", 62, 44,
+ true, Being::TC_MEDIUM);
+ loadTargetCursor("graphics/gui/target-cursor-blue-l.png", 82, 60,
+ false, Being::TC_LARGE);
+ loadTargetCursor("graphics/gui/target-cursor-red-l.png", 82, 60,
+ true, Being::TC_LARGE);
+}
+
+void
+Viewport::loadTargetCursor(std::string filename, int width, int height,
+ bool outRange, Being::TargetCursorSize size)
+{
+ assert(size > -1);
+ assert(size < 3);
+
+ ImageSet* currentImageSet;
+ SimpleAnimation* currentCursor;
+
ResourceManager *resman = ResourceManager::getInstance();
- mInRangeImages = resman->getImageSet(
- "graphics/gui/target-cursor-blue.png", 44, 35);
- mOutRangeImages = resman->getImageSet(
- "graphics/gui/target-cursor-red.png", 44, 35);
- Animation *animInRange = new Animation();
- Animation *animOutRange = new Animation();
-
- for (unsigned int i = 0; i < mInRangeImages->size(); ++i)
+
+ currentImageSet = resman->getImageSet(filename, width, height);
+ Animation *anim = new Animation();
+ for (unsigned int i = 0; i < currentImageSet->size(); ++i)
{
- animInRange->addFrame(mInRangeImages->get(i), 75, 0, 0);
+ anim->addFrame(currentImageSet->get(i), 75, 0, 0);
}
+ currentCursor = new SimpleAnimation(anim);
- for (unsigned int j = 0; j < mOutRangeImages->size(); ++j)
+ if (outRange)
{
- animOutRange->addFrame(mOutRangeImages->get(j), 75, 0, 0);
+ mOutRangeImages[size] = currentImageSet;
+ mTargetCursorOutRange[size] = currentCursor;
+ }
+ else {
+ mInRangeImages[size] = currentImageSet;
+ mTargetCursorInRange[size] = currentCursor;
}
-
- mTargetCursorInRange = new SimpleAnimation(animInRange);
- mTargetCursorOutRange = new SimpleAnimation(animOutRange);
}
Viewport::~Viewport()
{
delete mPopupMenu;
- delete mTargetCursorInRange;
- delete mTargetCursorOutRange;
-
- mInRangeImages->decRef();
- mOutRangeImages->decRef();
+ for (int i = Being::TC_SMALL; i < Being::NUM_TC; i++)
+ {
+ delete mTargetCursorInRange[i];
+ delete mTargetCursorOutRange[i];
+ mInRangeImages[i]->decRef();
+ mOutRangeImages[i]->decRef();
+ }
}
void
@@ -259,8 +287,11 @@ Viewport::logic()
mWalkTime = player_node->mWalkTime;
}
- mTargetCursorInRange->update(10);
- mTargetCursorOutRange->update(10);
+ for (int i = 0; i < 3; i++)
+ {
+ mTargetCursorInRange[i]->update(10);
+ mTargetCursorOutRange[i]->update(10);
+ }
}
void
@@ -270,26 +301,31 @@ Viewport::drawTargetCursor(Graphics *graphics)
Being *target = player_node->getTarget();
if (target)
{
+ // Calculate target circle position
+
// Find whether target is in range
int rangeX = abs(target->mX - player_node->mX);
int rangeY = abs(target->mY - player_node->mY);
int attackRange = player_node->getAttackRange();
- // Draw the target cursor, which one depends if the target is in range
+ // Get the correct target cursors graphic
+ Being::TargetCursorSize cursorSize = target->getTargetCursorSize();
+ Image* targetCursor;
if (rangeX > attackRange || rangeY > attackRange)
{
- // Draw the out of range cursor
- graphics->drawImage(mTargetCursorOutRange->getCurrentImage(),
- target->getPixelX() - mCameraX,
- target->getPixelY() - mCameraY);
+ targetCursor = mTargetCursorOutRange[cursorSize]->getCurrentImage();
}
- else
- {
- // Draw the in range cursor
- graphics->drawImage(mTargetCursorInRange->getCurrentImage(),
- target->getPixelX() - mCameraX,
- target->getPixelY() - mCameraY);
+ else {
+ targetCursor = mTargetCursorInRange[cursorSize]->getCurrentImage();
}
+
+ // Draw the target cursor at the correct position
+ int posX = target->getPixelX() + 16 -
+ targetCursor->getWidth() / 2 - mCameraX;
+ int posY = target->getPixelY() + 16 -
+ targetCursor->getHeight() / 2 - mCameraY;
+
+ graphics->drawImage(targetCursor, posX, posY);
}
}
@@ -304,10 +340,10 @@ Viewport::drawTargetName(Graphics *graphics)
graphics->setColor(gcn::Color(255, 32, 32));
const MonsterInfo &mi = static_cast<Monster*>(target)->getInfo();
- graphics->drawText(mi.getName(),
- target->getPixelX() - mCameraX + 15,
- target->getPixelY() - mCameraY - 42,
- gcn::Graphics::CENTER);
+ int posX = target->getPixelX() + 16 - mCameraX;
+ int posY = target->getPixelY() + 16 - target->getHeight() - mCameraY;
+
+ graphics->drawText(mi.getName(), posX, posY, gcn::Graphics::CENTER);
}
}
diff --git a/src/gui/viewport.h b/src/gui/viewport.h
index 84efeff3..22d0f249 100644
--- a/src/gui/viewport.h
+++ b/src/gui/viewport.h
@@ -29,9 +29,9 @@
#include "windowcontainer.h"
#include "../configlistener.h"
+#include "../being.h"
class Map;
-class Being;
class FloorItem;
class ImageSet;
class Item;
@@ -142,6 +142,13 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
void showPopup(int x, int y, Being *being);
/**
+ * Helper function for loading target cursors
+ */
+ void
+ loadTargetCursor(std::string filename, int width, int height,
+ bool outRange, Being::TargetCursorSize size);
+
+ /**
* Draws range based target cursor
*/
void
@@ -164,14 +171,17 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
int mCameraY; /**< Current viewpoint in tiles. */
bool mShowDebugPath; /**< Show a path from player to pointer. */
- ImageSet *mInRangeImages; /**< Images of in range target cursor. */
- ImageSet *mOutRangeImages; /**< Images of out of range target cursor.*/
+ /** Images of in range target cursor. */
+ ImageSet *mInRangeImages[Being::NUM_TC];
+
+ /** Images of out of range target cursor. */
+ ImageSet *mOutRangeImages[Being::NUM_TC];
/** Animated in range target cursor. */
- SimpleAnimation *mTargetCursorInRange;
+ SimpleAnimation *mTargetCursorInRange[Being::NUM_TC];
/** Animated out of range target cursor. */
- SimpleAnimation *mTargetCursorOutRange;
+ SimpleAnimation *mTargetCursorOutRange[Being::NUM_TC];
bool mPlayerFollowMouse;
int mWalkTime;
diff --git a/src/gui/widgets/resizegrip.cpp b/src/gui/widgets/resizegrip.cpp
new file mode 100644
index 00000000..50a6fce4
--- /dev/null
+++ b/src/gui/widgets/resizegrip.cpp
@@ -0,0 +1,65 @@
+/*
+ * 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$
+ */
+
+#include "resizegrip.h"
+
+#include <guichan/graphics.hpp>
+
+#include "../../graphics.h"
+
+#include "../../resources/image.h"
+#include "../../resources/resourcemanager.h"
+
+Image *ResizeGrip::gripImage = 0;
+int ResizeGrip::mInstances = 0;
+
+ResizeGrip::ResizeGrip()
+{
+ if (mInstances == 0)
+ {
+ // Load the grip image
+ ResourceManager *resman = ResourceManager::getInstance();
+ gripImage = resman->getImage("graphics/gui/resize.png");
+ }
+
+ mInstances++;
+
+ setWidth(gripImage->getWidth() + 2);
+ setHeight(gripImage->getHeight() + 2);
+}
+
+ResizeGrip::~ResizeGrip()
+{
+ mInstances--;
+
+ if (mInstances == 0)
+ {
+ gripImage->decRef();
+ }
+}
+
+void
+ResizeGrip::draw(gcn::Graphics *graphics)
+{
+ dynamic_cast<Graphics*>(graphics)->drawImage(gripImage, 0, 0);
+}
diff --git a/src/gui/widgets/resizegrip.h b/src/gui/widgets/resizegrip.h
new file mode 100644
index 00000000..04be3db3
--- /dev/null
+++ b/src/gui/widgets/resizegrip.h
@@ -0,0 +1,61 @@
+/*
+ * 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_RESIZEGRIP_H
+#define _TMW_RESIZEGRIP_H
+
+#include <guichan/widget.hpp>
+
+class Image;
+
+/**
+ * Resize grip. The resize grip is part of a resizable Window. It relies on the
+ * fact that uncaught mouse events are automatically routed to the parent
+ * window.
+ *
+ * \ingroup GUI
+ */
+class ResizeGrip : public gcn::Widget
+{
+ public:
+ /**
+ * Constructor.
+ */
+ ResizeGrip();
+
+ /**
+ * Destructor.
+ */
+ ~ResizeGrip();
+
+ /**
+ * Draws the resize grip.
+ */
+ void draw(gcn::Graphics *graphics);
+
+ private:
+ static Image *gripImage; /**< Resize grip image */
+ static int mInstances; /**< Number of resize grip instances */
+};
+
+#endif
diff --git a/src/gui/window.cpp b/src/gui/window.cpp
index bb60c6ff..8a052bba 100644
--- a/src/gui/window.cpp
+++ b/src/gui/window.cpp
@@ -24,10 +24,13 @@
#include "window.h"
#include <guichan/exception.hpp>
+#include <guichan/widgets/icon.hpp>
#include "gccontainer.h"
#include "windowcontainer.h"
+#include "widgets/resizegrip.h"
+
#include "../configlistener.h"
#include "../configuration.h"
#include "../graphics.h"
@@ -36,11 +39,10 @@
#include "../resources/image.h"
#include "../resources/resourcemanager.h"
-ConfigListener *Window::windowConfigListener = NULL;
-WindowContainer *Window::windowContainer = NULL;
+ConfigListener *Window::windowConfigListener = 0;
+WindowContainer *Window::windowContainer = 0;
int Window::instances = 0;
ImageRect Window::border;
-Image *Window::resizeGrip;
class WindowConfigListener : public ConfigListener
{
@@ -54,16 +56,16 @@ class WindowConfigListener : public ConfigListener
Window::Window(const std::string& caption, bool modal, Window *parent):
gcn::Window(caption),
+ mGrip(0),
mParent(parent),
mWindowName("window"),
- mSnapSize(8),
mShowTitle(true),
mModal(modal),
mResizable(false),
- mMouseResize(false),
+ mMouseResize(0),
mSticky(false),
mMinWinWidth(100),
- mMinWinHeight(28),
+ mMinWinHeight(40),
mMaxWinWidth(INT_MAX),
mMaxWinHeight(INT_MAX)
{
@@ -87,7 +89,6 @@ Window::Window(const std::string& caption, bool modal, Window *parent):
border.grid[6] = dBorders->getSubImage(0, 15, 4, 4);
border.grid[7] = dBorders->getSubImage(4, 15, 3, 4);
border.grid[8] = dBorders->getSubImage(7, 15, 4, 4);
- resizeGrip = resman->getImage("graphics/gui/resize.png");
dBorders->decRef();
windowConfigListener = new WindowConfigListener();
// Send GUI alpha changed for initialization
@@ -151,10 +152,10 @@ Window::~Window()
delete border.grid[6];
delete border.grid[7];
delete border.grid[8];
- resizeGrip->decRef();
}
delete mChrome;
+ delete mGrip;
}
void Window::setWindowContainer(WindowContainer *wc)
@@ -162,22 +163,15 @@ void Window::setWindowContainer(WindowContainer *wc)
windowContainer = wc;
}
-void Window::draw(gcn::Graphics* graphics)
+void Window::draw(gcn::Graphics *graphics)
{
- Graphics *g = (Graphics*)graphics;
+ Graphics *g = static_cast<Graphics*>(graphics);
g->drawImageRect(0, 0, getWidth(), getHeight(), border);
- // Draw grip
- if (mResizable)
- {
- g->drawImage(Window::resizeGrip,
- getWidth() - resizeGrip->getWidth(),
- getHeight() - resizeGrip->getHeight());
- }
-
// Draw title
- if (mShowTitle) {
+ if (mShowTitle)
+ {
graphics->setFont(getFont());
graphics->drawText(getCaption(), 7, 5, gcn::Graphics::LEFT);
}
@@ -188,13 +182,13 @@ void Window::draw(gcn::Graphics* graphics)
void Window::setContentWidth(int width)
{
mChrome->setWidth(width);
- resizeToContent();
+ setWidth(width + 2 * getPadding());
}
void Window::setContentHeight(int height)
{
mChrome->setHeight(height);
- resizeToContent();
+ setHeight(height + getPadding() + getTitleBarHeight());
}
void Window::setContentSize(int width, int height)
@@ -203,6 +197,37 @@ void Window::setContentSize(int width, int height)
setContentHeight(height);
}
+void Window::setWidth(int width)
+{
+ gcn::Window::setWidth(width);
+
+ if (mGrip)
+ {
+ mGrip->setX(getWidth() - mGrip->getWidth() - getChildrenArea().x);
+ }
+}
+
+void Window::setHeight(int height)
+{
+ gcn::Window::setHeight(height);
+
+ if (mGrip)
+ {
+ mGrip->setY(getHeight() - mGrip->getHeight() - getChildrenArea().y);
+ }
+}
+
+void Window::setDimension(const gcn::Rectangle &dimension)
+{
+ gcn::Window::setDimension(dimension);
+
+ if (mGrip)
+ {
+ mGrip->setX(getWidth() - mGrip->getWidth() - getChildrenArea().x);
+ mGrip->setY(getHeight() - mGrip->getHeight() - getChildrenArea().y);
+ }
+}
+
void Window::setLocationRelativeTo(gcn::Widget *widget)
{
int wx, wy;
@@ -238,6 +263,19 @@ void Window::setMaxHeight(unsigned int height)
void Window::setResizable(bool r)
{
mResizable = r;
+
+ if (mResizable)
+ {
+ mGrip = new ResizeGrip();
+ mGrip->setX(getWidth() - mGrip->getWidth() - getChildrenArea().x);
+ mGrip->setY(getHeight() - mGrip->getHeight() - getChildrenArea().y);
+ gcn::Window::add(mGrip);
+ }
+ else
+ {
+ delete mGrip;
+ mGrip = 0;
+ }
}
bool Window::isResizable()
@@ -287,15 +325,27 @@ void Window::mousePressed(gcn::MouseEvent &event)
// Let Guichan move window to top and figure out title bar drag
gcn::Window::mousePressed(event);
- int x = event.getX();
- int y = event.getY();
+ const int x = event.getX();
+ const int y = event.getY();
+ mMouseResize = 0;
- // Activate resizing if the left mouse button was pressed on the grip
- mMouseResize =
- isResizable() &&
- event.getButton() == gcn::MouseEvent::LEFT &&
- getGripDimension().isPointInRect(x, y) &&
- !getChildrenArea().isPointInRect(x, y);
+ // Activate resizing handles as appropriate
+ if (event.getSource() == this && isResizable() &&
+ event.getButton() == gcn::MouseEvent::LEFT &&
+ !getChildrenArea().isPointInRect(x, y))
+ {
+ mMouseResize |= (x > getWidth() - resizeBorderWidth) ? RIGHT :
+ (x < resizeBorderWidth) ? LEFT : 0;
+ mMouseResize |= (y > getHeight() - resizeBorderWidth) ? BOTTOM :
+ (y < resizeBorderWidth) ? TOP : 0;
+ }
+ else if (event.getSource() == mGrip)
+ {
+ mDragOffsetX = x + mGrip->getX();
+ mDragOffsetY = y + mGrip->getY();
+ mMouseResize |= BOTTOM | RIGHT;
+ mIsMoving = false;
+ }
}
void Window::mouseDragged(gcn::MouseEvent &event)
@@ -303,20 +353,47 @@ void Window::mouseDragged(gcn::MouseEvent &event)
// Let Guichan handle title bar drag
gcn::Window::mouseDragged(event);
- // Keep guichan window inside screen
- int newX = std::max(0, getX());
- int newY = std::max(0, getY());
- newX = std::min(windowContainer->getWidth() - getWidth(), newX);
- newY = std::min(windowContainer->getHeight() - getHeight(), newY);
- setPosition(newX, newY);
+ // Keep guichan window inside screen when it may be moved
+ if (isMovable() && mIsMoving)
+ {
+ int newX = std::max(0, getX());
+ int newY = std::max(0, getY());
+ newX = std::min(windowContainer->getWidth() - getWidth(), newX);
+ newY = std::min(windowContainer->getHeight() - getHeight(), newY);
+ setPosition(newX, newY);
+ }
if (mMouseResize && !mIsMoving)
{
+ const int dx = event.getX() - mDragOffsetX +
+ ((event.getSource() == mGrip) ? mGrip->getX() : 0);
+ const int dy = event.getY() - mDragOffsetY +
+ ((event.getSource() == mGrip) ? mGrip->getY() : 0);
gcn::Rectangle newDim = getDimension();
- // We're dragging bottom right
- newDim.width += event.getX() - mDragOffsetX;
- newDim.height += event.getY() - mDragOffsetY;
+ if (mMouseResize & (TOP | BOTTOM))
+ {
+ int newHeight = newDim.height + ((mMouseResize & TOP) ? -dy : dy);
+ newDim.height = std::min(mMaxWinHeight,
+ std::max(mMinWinHeight, newHeight));
+
+ if (mMouseResize & TOP)
+ {
+ newDim.y -= newDim.height - getHeight();
+ }
+ }
+
+ if (mMouseResize & (LEFT | RIGHT))
+ {
+ int newWidth = newDim.width + ((mMouseResize & LEFT) ? -dx : dx);
+ newDim.width = std::min(mMaxWinWidth,
+ std::max(mMinWinWidth, newWidth));
+
+ if (mMouseResize & LEFT)
+ {
+ newDim.x -= newDim.width - getWidth();
+ }
+ }
// Keep guichan window inside screen (supports resizing any side)
if (newDim.x < 0)
@@ -338,29 +415,16 @@ void Window::mouseDragged(gcn::MouseEvent &event)
newDim.height = windowContainer->getHeight() - newDim.y;
}
- // Keep the window at least its minimum size
- if (newDim.width < mMinWinWidth)
- {
- newDim.width = mMinWinWidth;
- }
- else if (newDim.width > mMaxWinWidth)
- {
- newDim.width = mMaxWinWidth;
- }
-
- if (newDim.height < mMinWinHeight)
+ // Update mouse offset when dragging bottom or right border
+ if (mMouseResize & BOTTOM)
{
- newDim.height = mMinWinHeight;
+ mDragOffsetY += newDim.height - getHeight();
}
- else if (newDim.height > mMaxWinHeight)
+ if (mMouseResize & RIGHT)
{
- newDim.height = mMaxWinHeight;
+ mDragOffsetX += newDim.width - getWidth();
}
- // Update mouse offset when dragging bottom or right border
- mDragOffsetX += newDim.width - getWidth();
- mDragOffsetY += newDim.height - getHeight();
-
// Set the new window and content dimensions
setDimension(newDim);
const gcn::Rectangle area = getChildrenArea();
@@ -368,15 +432,6 @@ void Window::mouseDragged(gcn::MouseEvent &event)
}
}
-gcn::Rectangle
-Window::getGripDimension()
-{
- return gcn::Rectangle(getWidth() - resizeGrip->getWidth(),
- getHeight() - resizeGrip->getHeight(),
- getWidth(),
- getHeight());
-}
-
void
Window::loadWindowState()
{
diff --git a/src/gui/window.h b/src/gui/window.h
index 31c260cf..03248908 100644
--- a/src/gui/window.h
+++ b/src/gui/window.h
@@ -30,11 +30,10 @@
class ConfigListener;
class GCContainer;
-class Image;
class ImageRect;
+class ResizeGrip;
class WindowContainer;
-
/**
* A window. This window can be dragged around and has a title bar. Windows are
* invisible by default.
@@ -100,6 +99,21 @@ class Window : public gcn::Window
void setContentSize(int width, int height);
/**
+ * Sets the width of this window.
+ */
+ void setWidth(int width);
+
+ /**
+ * Sets the height of this window.
+ */
+ void setHeight(int height);
+
+ /**
+ * Sets the position and size of this window.
+ */
+ void setDimension(const gcn::Rectangle &dimension);
+
+ /**
* Sets the location relative to the given widget.
*/
void setLocationRelativeTo(gcn::Widget *widget);
@@ -168,16 +182,15 @@ class Window : public gcn::Window
void scheduleDelete();
/**
- * Window dragging and resizing mouse related. These methods also makes
- * sure the window is not dragged/resized outside of the screen.
+ * Starts window resizing when appropriate.
*/
void mousePressed(gcn::MouseEvent &event);
- void mouseDragged(gcn::MouseEvent &event);
/**
- * Gets the position of the resize grip.
+ * Implements window resizing and makes sure the window is not
+ * dragged/resized outside of the screen.
*/
- gcn::Rectangle getGripDimension();
+ void mouseDragged(gcn::MouseEvent &event);
/**
* Sets the name of the window. This is not the window title.
@@ -214,37 +227,50 @@ class Window : public gcn::Window
*/
virtual void resetToDefaultSize();
+ enum ResizeHandles
+ {
+ TOP = 0x01,
+ RIGHT = 0x02,
+ BOTTOM = 0x04,
+ LEFT = 0x08
+ };
+
protected:
- GCContainer *mChrome; /**< Contained container */
+ GCContainer *mChrome; /**< Contained container */
+ ResizeGrip *mGrip; /**< Resize grip */
Window *mParent; /**< The parent window */
std::string mWindowName; /**< Name of the window */
- int mSnapSize; /**< Snap distance to window edge */
bool mShowTitle; /**< Window has a title bar */
bool mModal; /**< Window is modal */
- bool mResizable; /**< Window can be resized */
- bool mMouseResize; /**< Window is being resized */
- bool mSticky; /**< Window resists minimzation */
- int mMinWinWidth; /**< Minimum window width */
- int mMinWinHeight; /**< Minimum window height */
- int mMaxWinWidth; /**< Maximum window width */
- int mMaxWinHeight; /**< Maximum window height */
+ bool mResizable; /**< Window can be resized */
+ int mMouseResize; /**< Window is being resized */
+ bool mSticky; /**< Window resists minimization */
+ int mMinWinWidth; /**< Minimum window width */
+ int mMinWinHeight; /**< Minimum window height */
+ int mMaxWinWidth; /**< Maximum window width */
+ int mMaxWinHeight; /**< Maximum window height */
int mDefaultX; /**< Default window X position */
int mDefaultY; /**< Default window Y position */
int mDefaultWidth; /**< Default window width */
int mDefaultHeight; /**< Default window height */
/** The window container windows add themselves to. */
- static WindowContainer* windowContainer;
+ static WindowContainer *windowContainer;
/**
- * The config listener that listens to changes relevant to all
- * windows
+ * The config listener that listens to changes relevant to all windows.
*/
static ConfigListener *windowConfigListener;
static int instances; /**< Number of Window instances */
static ImageRect border; /**< The window border and background */
- static Image *resizeGrip; /**< The grip to resize window */
+
+ /**
+ * The width of the resize border. Is independent of the actual window
+ * border width, and determines mostly the size of the corner area
+ * where two borders are moved at the same time.
+ */
+ static const int resizeBorderWidth = 10;
};
#endif