#ifndef GRAPHICS_MENU_H_
#define GRAPHICS_MENU_H_
+namespace app {
+ class Application;
+ class State;
+}
+
+#include "Animation.h"
#include "Font.h"
-#include "fwd.h"
#include "Sprite.h"
-#include "../geometry/Vector.h"
+#include "../math/Vector.h"
#include <algorithm>
#include <vector>
const Font *disabledFont;
const Sprite *cursor;
const Sprite *selectedCursor;
+ const Animation *cursorAnimation;
+ const Animation *selectedCursorAnimation;
int charsPerEntry;
int rows;
int rowGap;
MenuProperties()
: font(0), disabledFont(0), cursor(0), selectedCursor(0)
+ , cursorAnimation(0), selectedCursorAnimation(0)
, charsPerEntry(0), rows(1), rowGap(0)
, iconSpace(0), cols(1), colGap(0)
, charsPerNumber(0), charsPerAdditionalText(0)
void Clear() { entries.clear(); }
void ClearEntry(int at) { entries[at] = Entry(0, T(), false); }
- void Draw(SDL_Surface *dest, const geometry::Vector<int> &position) const;
+ void StartAnimation(app::Application &ctrl);
+ void StartAnimation(app::State &ctrl);
+ void StopAnimation();
+
+ void Draw(SDL_Surface *dest, const math::Vector<int> &position) const;
private:
int GetRow(int index) const { return index / cols; }
int GetCol(int index) const { return index % cols; }
+ void DrawCursor(SDL_Surface *, const math::Vector<int> &) const;
+ void DrawSelectedCursor(SDL_Surface *, const math::Vector<int> &) const;
+
private:
struct Entry {
Entry(const char *title, const T &value, bool enabled = true, const Sprite *icon = 0, int number = 0, const char *additionalText = 0)
T value;
bool enabled;
};
+ AnimationRunner animation;
+ AnimationRunner selectedAnimation;
std::vector<Entry> entries;
int selected;
int secondarySelection;
template<class T>
Menu<T>::Menu(const MenuProperties &p)
: MenuProperties(p)
+, animation(cursorAnimation)
+, selectedAnimation(selectedCursorAnimation)
, selected(0)
, secondarySelection(0)
, topRow(0)
template<class T>
-void Menu<T>::Draw(SDL_Surface *dest, const geometry::Vector<int> &position) const {
+void Menu<T>::StartAnimation(app::Application &ctrl) {
+ if (cursorAnimation) {
+ animation.Start(ctrl);
+ }
+ if (selectedCursorAnimation) {
+ selectedAnimation.Start(ctrl);
+ }
+}
+
+template<class T>
+void Menu<T>::StartAnimation(app::State &ctrl) {
+ if (cursorAnimation) {
+ animation.Start(ctrl);
+ }
+ if (selectedCursorAnimation) {
+ selectedAnimation.Start(ctrl);
+ }
+}
+
+template<class T>
+void Menu<T>::StopAnimation() {
+ animation.Stop();
+ selectedAnimation.Stop();
+}
+
+
+template<class T>
+void Menu<T>::Draw(SDL_Surface *dest, const math::Vector<int> &position) const {
int start(topRow * cols);
int slots(rows * cols);
int items(entries.size() - start);
int end(start + (items < slots ? items : slots));
for (int i(0), count(end - start); i < count; ++i) {
if (!entries[start + i].title) continue;
- geometry::Vector<int> iconOffset(
+ math::Vector<int> iconOffset(
(i % cols) * (ColWidth() + colGap),
(i / cols) * RowHeight());
// This fixes the position of the third column of the inventory and capsule menus.
if (thirdColumnHack && i % cols == 2) {
- iconOffset += geometry::Vector<int>(font->CharWidth() * thirdColumnHack, 0);
+ iconOffset += math::Vector<int>(font->CharWidth() * thirdColumnHack, 0);
}
if (entries[start + i].icon) {
entries[start + i].icon->Draw(dest, position + iconOffset);
}
- geometry::Vector<int> textOffset(iconOffset.X() + iconSpace, iconOffset.Y());
+ math::Vector<int> textOffset(iconOffset.X() + iconSpace, iconOffset.Y());
const Font *usedFont(entries[start + i].enabled ? font : disabledFont);
usedFont->DrawString(entries[start + i].title, dest, position + textOffset, charsPerEntry);
- textOffset += geometry::Vector<int>(charsPerEntry * usedFont->CharWidth(), 0);
+ textOffset += math::Vector<int>(charsPerEntry * usedFont->CharWidth(), 0);
if (charsPerAdditionalText) {
- textOffset += geometry::Vector<int>(additionalTextGap, 0);
+ textOffset += math::Vector<int>(additionalTextGap, 0);
if (entries[start + i].additionalText) {
usedFont->DrawString(entries[start + i].additionalText, dest, position + textOffset, charsPerAdditionalText);
}
- textOffset += geometry::Vector<int>(charsPerAdditionalText * usedFont->CharWidth(), 0);
+ textOffset += math::Vector<int>(charsPerAdditionalText * usedFont->CharWidth(), 0);
}
if (charsPerNumber) {
usedFont->DrawChar(delimiter, dest, position + textOffset);
- textOffset += geometry::Vector<int>(usedFont->CharWidth(), 0);
+ textOffset += math::Vector<int>(usedFont->CharWidth(), 0);
usedFont->DrawNumber(entries[start + i].number, dest, position + textOffset, charsPerNumber);
}
}
- geometry::Vector<int> cursorOffset(
+ math::Vector<int> cursorOffset(
(selected % cols) * (ColWidth() + colGap) - cursor->Width(),
((selected - start) / cols) * RowHeight());
// This fixes the position of the third column of the inventory and capsule menus.
if (thirdColumnHack && selected % cols == 2) {
- cursorOffset += geometry::Vector<int>(font->CharWidth() * thirdColumnHack, 0);
+ cursorOffset += math::Vector<int>(font->CharWidth() * thirdColumnHack, 0);
}
switch (state) {
case STATE_INACTIVE:
break;
case STATE_ACTIVE:
- cursor->Draw(dest, position + cursorOffset);
+ DrawCursor(dest, position + cursorOffset);
break;
case STATE_SELECTED:
- selectedCursor->Draw(dest, position + cursorOffset);
+ DrawSelectedCursor(dest, position + cursorOffset);
break;
case STATE_DUAL:
- cursor->Draw(dest, position + cursorOffset
- - geometry::Vector<int>(selectedCursor->Width(), 0));
+ DrawCursor(dest, position + cursorOffset
+ - math::Vector<int>(selectedCursor->Width(), 0));
if (secondarySelection >= start && secondarySelection <= end) {
- geometry::Vector<int> secondaryOffset(
+ math::Vector<int> secondaryOffset(
(secondarySelection % cols) * (ColWidth() + colGap) - cursor->Width(),
((secondarySelection - start) / cols) * RowHeight());
- selectedCursor->Draw(dest, position + secondaryOffset);
+ DrawSelectedCursor(dest, position + secondaryOffset);
}
break;
}
}
+template<class T>
+void Menu<T>::DrawCursor(
+ SDL_Surface *dest,
+ const math::Vector<int> &position) const {
+ if (animation.Running()) {
+ animation.Draw(dest, position);
+ } else {
+ cursor->Draw(dest, position);
+ }
+}
+
+template<class T>
+void Menu<T>::DrawSelectedCursor(
+ SDL_Surface *dest,
+ const math::Vector<int> &position) const {
+ if (selectedAnimation.Running()) {
+ selectedAnimation.Draw(dest, position);
+ } else {
+ selectedCursor->Draw(dest, position);
+ }
+}
+
}
-#endif /* GRAPHICS_MENU_H_ */
+#endif