Embark on an epic journey to document the dialog engine in as much detail as possible.
... and the previous commits (from 56f73cb on) were by and large a result of things noticed during this process.
This commit is contained in:
@@ -289,12 +289,10 @@ void cLedGroup::recalcRect(){
|
||||
frame.inset(-6,-6);
|
||||
}
|
||||
|
||||
/** A click handler is called whenever a click is received, even on the currently selected element. */
|
||||
void cLedGroup::attachClickHandler(click_callback_t f) throw() {
|
||||
onClick = f;
|
||||
}
|
||||
|
||||
/** A focus handler is called when the currently selected element changes. */
|
||||
void cLedGroup::attachFocusHandler(focus_callback_t f) throw() {
|
||||
onFocus = f;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#ifndef BUTTON_H
|
||||
#define BUTTON_H
|
||||
|
||||
/// @file
|
||||
/// Button-related classes and types.
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
#include <string>
|
||||
@@ -17,27 +20,35 @@
|
||||
#include "control.h"
|
||||
#include "graphtool.h" // for eFont
|
||||
|
||||
/// A button type.
|
||||
enum eBtnType { // w x h
|
||||
BTN_SM = 0, // 23x23 (PICT id 2000 / 2001)
|
||||
BTN_REG, // 63x23 (PICT id 2002 / 2003)
|
||||
BTN_LG, // 102x23 (PICT id 2004 / 2005)
|
||||
BTN_HELP, // 16x13 (PICT id 2006 / 2007) white bubble w/ ? mark
|
||||
BTN_LEFT, // 63x23 (PICT id 2008 / 2009) with left arrow
|
||||
BTN_RIGHT, // 63x23 (PICT id 2010 / 2011) with right arrow
|
||||
BTN_UP, // 63x23 (PICT id 2012 / 2013) with up arrow
|
||||
BTN_DOWN, // 63x23 (PICT id 2014 / 2015) with down arrow
|
||||
BTN_TINY, // 14x10 (PICT id 2021)
|
||||
BTN_DONE, // 63x23 (PICT id 2022 / 2023) says "Done"
|
||||
BTN_TALL, // 63x40 (PICT id 2024 / 2025)
|
||||
BTN_TRAIT, // 63x40 (PICT id 2026 / 2027) says "Race Good/Bad Traits"
|
||||
BTN_PUSH, // 30x30 (PICT id 2028 / 2029) red round button
|
||||
BTN_LED, // 14x10 (PICT id 2018 / 2019 / 2020)
|
||||
BTN_SM = 0, /**< A small 23x23 button */// (PICT id 2000 / 2001)
|
||||
BTN_REG, /**< A normal-sized 63x23 button */// (PICT id 2002 / 2003)
|
||||
BTN_LG, /**< A large 102x23 button */// (PICT id 2004 / 2005)
|
||||
BTN_HELP, /**< A small 16x13 help button - a white bubble with a ? mark */// (PICT id 2006 / 2007)
|
||||
BTN_LEFT, /**< A normal-sized 63x23 button with a left-pointing arrow */// (PICT id 2008 / 2009)
|
||||
BTN_RIGHT, /**< A normal-sized 63x23 button with a right-pointing arrow */// (PICT id 2010 / 2011)
|
||||
BTN_UP, /**< A normal-sized 63x23 button with an up-pointing arrow */// (PICT id 2012 / 2013)
|
||||
BTN_DOWN, /**< A normal-sized 63x23 button with a down-pointing arrow */// (PICT id 2014 / 2015)
|
||||
BTN_TINY, /**< A tiny 14x10 button, same size as an LED */// (PICT id 2021)
|
||||
BTN_DONE, /**< A normal-sized 63x23 button with "Done" on it */// (PICT id 2022 / 2023)
|
||||
BTN_TALL, /**< A tall 63x40 button */// (PICT id 2024 / 2025)
|
||||
BTN_TRAIT, /**< A tall 63x40 button with "Race Good/Bad Traits" on it */// (PICT id 2026 / 2027)
|
||||
BTN_PUSH, /**< A round red 30x30 push button */// (PICT id 2028 / 2029)
|
||||
BTN_LED, /**< A tiny 14x10 LED button */// (PICT id 2018 / 2019 / 2020)
|
||||
};
|
||||
|
||||
/// Represents the state of an LED button.
|
||||
/// Generally, led_red is used to indicate a selected button.
|
||||
/// Currently, led_green is only used by the spell selection dialog,
|
||||
/// where led_red indicates the spell is available amd led_green indicates it is selected.
|
||||
enum eLedState {led_green = 0, led_red, led_off};
|
||||
|
||||
|
||||
/// A clickable button control.
|
||||
class cButton : public cControl {
|
||||
public:
|
||||
/// @copydoc cDialog::init()
|
||||
static void init();
|
||||
void attachClickHandler(click_callback_t f) throw();
|
||||
void attachFocusHandler(focus_callback_t f) throw(xHandlerNotSupported);
|
||||
@@ -47,8 +58,14 @@ public:
|
||||
short getFormat(eFormat prop) throw(xUnsupportedProp);
|
||||
void setColour(sf::Color clr) throw(xUnsupportedProp);
|
||||
sf::Color getColour() throw(xUnsupportedProp);
|
||||
/// Set the type of this button.
|
||||
/// @param newType The desired button type.
|
||||
void setBtnType(eBtnType newType);
|
||||
/// Get the type of this button.
|
||||
/// @return The button type.
|
||||
eBtnType getBtnType();
|
||||
/// Create a new button.
|
||||
/// @param parent The parent dialog.
|
||||
explicit cButton(cDialog* parent);
|
||||
bool isClickable();
|
||||
virtual ~cButton();
|
||||
@@ -56,8 +73,13 @@ public:
|
||||
cButton& operator=(cButton& other) = delete;
|
||||
cButton(cButton& other) = delete;
|
||||
protected:
|
||||
/// The type of button.
|
||||
eBtnType type;
|
||||
/// The click handler.
|
||||
click_callback_t onClick;
|
||||
/// Construct a new button.
|
||||
/// @param parent The parent dialog.
|
||||
/// @param t The type of control. Should be either CTRL_LED or CTRL_BTN.
|
||||
cButton(cDialog* parent,eControlType t);
|
||||
private:
|
||||
bool wrapLabel;
|
||||
@@ -65,13 +87,23 @@ private:
|
||||
std::string fromList;
|
||||
static RECT btnRects[13][2];
|
||||
protected:
|
||||
/// The index in buttons of the texture for each button type.
|
||||
static size_t btnGW[14];
|
||||
/// The textures that hold the graphics for the buttons.
|
||||
static sf::Texture buttons[7];
|
||||
};
|
||||
|
||||
/// A LED button that can be either on or off.
|
||||
/// Additionally, it supports two possible colours, red and green.
|
||||
/// By default, it behaves like a checkbox, turning on or off when clicked.
|
||||
/// This default behaviour always assumes a red LED.
|
||||
class cLed : public cButton {
|
||||
public:
|
||||
/// @copydoc cDialog::init()
|
||||
static void init();
|
||||
/// A handler that can be attached as a click handler to prevent the
|
||||
/// default toggle-selected action of an LED.
|
||||
/// @return true to indicate the event should continue.
|
||||
static bool noAction(cDialog&,std::string,eKeyMod) {return true;}
|
||||
void attachClickHandler(click_callback_t f) throw();
|
||||
void attachFocusHandler(focus_callback_t f) throw();
|
||||
@@ -79,9 +111,15 @@ public:
|
||||
bool triggerFocusHandler(cDialog& me, std::string id, bool losingFocus);
|
||||
void setFormat(eFormat prop, short val) throw(xUnsupportedProp);
|
||||
short getFormat(eFormat prop) throw(xUnsupportedProp);
|
||||
/// Create a new LED button.
|
||||
/// @param parent The parent dialog.
|
||||
explicit cLed(cDialog* parent);
|
||||
virtual ~cLed();
|
||||
/// Set the LED's current state,.
|
||||
/// @param to The new state.
|
||||
void setState(eLedState to);
|
||||
/// Get the LED's current state.
|
||||
/// @return The current state.
|
||||
eLedState getState();
|
||||
void draw();
|
||||
cLed& operator=(cLed& other) = delete;
|
||||
@@ -95,6 +133,24 @@ private:
|
||||
focus_callback_t onFocus;
|
||||
};
|
||||
|
||||
/// A group of LED buttons that behave like radio buttons.
|
||||
/// As with other standard LEDs, this always assumes red LEDs.
|
||||
///
|
||||
/// When an LED in the group is clicked, the following sequence of events are fired:
|
||||
///
|
||||
/// 1. The click handler of the clicked LED.
|
||||
/// 2. The click handler of the LED group.
|
||||
/// 3. The focus handler of the currently selected LED (if any), with the third parameter true.
|
||||
/// 4. The focus handler of the clicked LED, with the third parameter false.
|
||||
/// 5. The focus handler of the LED group, with the third parameter false.
|
||||
///
|
||||
/// If at any stage a handler returns false, the entire sequence is aborted, and the
|
||||
/// selection is not changed. A click within the group's space but not on any choice
|
||||
/// triggers no events.
|
||||
/// @note When the focus handlers of the individual LEDs are called, the selection has not yet been updated,
|
||||
/// so calling the LED group's getSelected() method will still return the previous selection.
|
||||
/// However, when the focus handler of the LED group is called, the selection _has_ been updated.,
|
||||
/// so getSelected() will return the new selection. (This is the reason for the getPreviousSelection() method.)
|
||||
class cLedGroup : public cControl {
|
||||
std::vector<cLed> btns;
|
||||
click_callback_t onClick;
|
||||
@@ -106,30 +162,71 @@ class cLedGroup : public cControl {
|
||||
cLedGroup& operator=(cLedGroup& other) = delete;
|
||||
cLedGroup(cLedGroup& other) = delete;
|
||||
public:
|
||||
void attachClickHandler(click_callback_t f) throw(); // activated whenever a click is received, even on the currently active LED
|
||||
void attachFocusHandler(focus_callback_t f) throw(); // activated only when the selection changes
|
||||
/// @copydoc cControl::attachClickHandler()
|
||||
///
|
||||
/// The click handler is called whenever an LED in the group is clicked, even if it's the currently selected LED.
|
||||
void attachClickHandler(click_callback_t f) throw();
|
||||
/// @copydoc cControl::attachFocusHandler()
|
||||
///
|
||||
/// An LED group triggers focus handlers when a choice other than the currently selected one is clicked.
|
||||
/// The third parameter is always false for an LED group's focus handler.
|
||||
/// You can determine what changed using getPrevSelection() and getSelected(), and can do whatever post-processing
|
||||
/// you want, including selecting a completely different option.
|
||||
void attachFocusHandler(focus_callback_t f) throw();
|
||||
bool triggerClickHandler(cDialog& me, std::string id, eKeyMod mods);
|
||||
bool triggerFocusHandler(cDialog& me, std::string id, bool losingFocus);
|
||||
/// Add a new LED to this group.
|
||||
/// @param ctrl A pointer to the LED, which should already be constructed.
|
||||
/// @param key A key to be used to look up the LED later.
|
||||
/// @note This function is intended for internal use, which is why it takes a control pointer instead of a unique key.
|
||||
void addChoice(cLed* ctrl, std::string key);
|
||||
/// Disable one of the choices in this group.
|
||||
/// @param id The unique key of the choice.
|
||||
void disable(std::string id);
|
||||
/// Enable one of the choices in this group.
|
||||
/// @param id The unique key of the choice.
|
||||
void enable(std::string id);
|
||||
using cControl::show;
|
||||
using cControl::hide;
|
||||
/// Hide one of the choices in this group.
|
||||
/// @param id The unique key of the choice.
|
||||
void hide(std::string id);
|
||||
/// Show one of the choices in this group.
|
||||
/// @param id The unique key of the choice.
|
||||
void show(std::string id);
|
||||
void setFormat(eFormat prop, short val) throw(xUnsupportedProp);
|
||||
short getFormat(eFormat prop) throw(xUnsupportedProp);
|
||||
void setColour(sf::Color clr) throw(xUnsupportedProp);
|
||||
sf::Color getColour() throw(xUnsupportedProp);
|
||||
/// Create a new LED group.
|
||||
/// @param parent The parent dialog.
|
||||
explicit cLedGroup(cDialog* parent);
|
||||
bool isClickable();
|
||||
bool handleClick(location where);
|
||||
virtual ~cLedGroup();
|
||||
/// Get one of the LED's in this group.
|
||||
/// @param id The unique key of the choice.
|
||||
/// @return A reference to the LED object.
|
||||
/// @throw std::invalid_argument if the choice does not exist in the group.
|
||||
cLed& operator[](std::string id);
|
||||
/// Set the currently selected LED in this group.
|
||||
/// @param id The unique key of the choice.
|
||||
/// @throw std::invalid_argument if the choice does not exist in the group.
|
||||
void setSelected(std::string id);
|
||||
/// Get the currently selected choice.
|
||||
/// @return id The unique key of the choice.
|
||||
std::string getSelected();
|
||||
std::string getPrevSelection(); // The id of the element that was last selected before the selection changed to the current selection.
|
||||
/// Get the previously selected choice.
|
||||
/// @return id The unique key of the choice.
|
||||
/// @note This is intended for use by focus handlers.
|
||||
///
|
||||
/// This refers to the element that was last selected before the selection changed to the current selection.
|
||||
std::string getPrevSelection();
|
||||
/// Recalculate the LED group's bounding rect.
|
||||
/// Call this after adding choices to the group to ensure that the choice is within the bounding rect.
|
||||
/// If a choice is not within the bounding rect, it will not respond to clicks.
|
||||
void recalcRect();
|
||||
/// A convenience type for making an iterator into the choice map.
|
||||
typedef std::map<std::string,cLed*>::iterator ledIter;
|
||||
void draw();
|
||||
};
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#ifndef CONTROL_H
|
||||
#define CONTROL_H
|
||||
|
||||
/// @file
|
||||
/// Control-related classes and types.
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
#include <string>
|
||||
@@ -23,94 +26,217 @@
|
||||
// short type;
|
||||
//};
|
||||
|
||||
/// Formatting properties
|
||||
enum eFormat {
|
||||
TXT_FRAME,
|
||||
TXT_FONT,
|
||||
TXT_SIZE,
|
||||
TXT_WRAP,
|
||||
TXT_FRAMESTYLE,
|
||||
TXT_FRAME, ///< Whether to draw a frame around the control. Should be a boolean (true or false).
|
||||
TXT_FONT, ///< The control's text font. Should be one of the constants FONT_PLAIN, FONT_BOLD, FONT_DUNGEON, FONT_MAIDEN.
|
||||
TXT_SIZE, ///< The control's text size. Should be an integer indicating point size.
|
||||
TXT_WRAP, ///< Whether the control should wrap. Should be a boolean (true or false).
|
||||
TXT_FRAMESTYLE, ///< The control's frame style. Should be a boolean (true or false). @see cControl::drawFrame()
|
||||
};
|
||||
|
||||
/// Specifies the type of a control.
|
||||
enum eControlType {
|
||||
CTRL_UNKNOWN,
|
||||
CTRL_BTN, // An ordinary push button
|
||||
CTRL_LED, // An LED (checkbox/radiobutton)
|
||||
CTRL_PICT, // A picture
|
||||
CTRL_FIELD, // An edit text field
|
||||
CTRL_TEXT, // A static text object
|
||||
CTRL_GROUP, // A LED radiobutton-like group
|
||||
CTRL_STACK, // A group of controls that display pages (not implemented yet)
|
||||
CTRL_SCROLL,// A scrollbar (not implemented yet)
|
||||
CTRL_BTN, ///< An ordinary push button
|
||||
CTRL_LED, ///< An LED (checkbox/radiobutton)
|
||||
CTRL_PICT, ///< A picture
|
||||
CTRL_FIELD, ///< An edit text field
|
||||
CTRL_TEXT, ///< A static text object
|
||||
CTRL_GROUP, ///< A LED radiobutton-like group
|
||||
CTRL_STACK, ///< A group of controls that display pages (not implemented yet)
|
||||
CTRL_SCROLL,///< A scrollbar
|
||||
};
|
||||
|
||||
//typedef bool (*click_callback_t)(cDialog&/*me*/,std::string/*id*/, eKeyMod/*mods*/);
|
||||
//typedef bool (*focus_callback_t)(cDialog&/*me*/,std::string/*id*/,bool/*losing*/); // losing is true if losing focus, false if gaining focus.
|
||||
/// The signature of a click handler.
|
||||
typedef std::function<bool(cDialog&,std::string,eKeyMod)> click_callback_t;
|
||||
/// The signature of a focus handler.
|
||||
typedef std::function<bool(cDialog&,std::string,bool)> focus_callback_t;
|
||||
|
||||
/// Thrown when you try to set a handler that the control does not support.
|
||||
class xHandlerNotSupported : std::exception {
|
||||
static const char* focusMsg;
|
||||
static const char* clickMsg;
|
||||
bool isFocus;
|
||||
public:
|
||||
/// Construct a new exception.
|
||||
/// @param isFocus true to indicate a focus event, false for a click event.
|
||||
xHandlerNotSupported(bool isFocus);
|
||||
/// @return The error message.
|
||||
const char* what();
|
||||
};
|
||||
|
||||
/// Thrown when you try to set or retrieve a formatting property that the control does not support.
|
||||
class xUnsupportedProp : std::exception {
|
||||
eFormat whichProp;
|
||||
char* msg;
|
||||
public:
|
||||
/// Construct a new exception.
|
||||
/// @param prop The unsupported format property.
|
||||
xUnsupportedProp(eFormat prop) throw();
|
||||
~xUnsupportedProp() throw();
|
||||
/// @return The error message.
|
||||
const char* what() throw();
|
||||
};
|
||||
|
||||
/// The superclass of all dialog controls.
|
||||
/// Some controls can be created in an arbitrary window, rather than a dialog controlled by cDialog.
|
||||
/// In this case, the event loop of the parent window is responsible for calling draw() when the control needs
|
||||
/// to be drawn, handleClick() when a mousedown event is received within the control's bounding rect, and
|
||||
/// triggerClickHandler() if a click occurs, either because handleClick() returns true or because
|
||||
/// a keyboard event is received that should trigger the control.
|
||||
class cControl {
|
||||
public:
|
||||
/// Attach a keyboard shortcut to a control. Pressing the keyboard shortcut is equivalent to clicking the control.
|
||||
/// @param key The desired keyboard shortcut.
|
||||
void attachKey(cKey key);
|
||||
/// Detach any currently assigned keyboard shortcut from the control.
|
||||
void detachKey();
|
||||
/// Set the control's text to a representation of its assigned keyboard shortcut.
|
||||
void setTextToKey();
|
||||
/// Check if the control has an assigned keyboard shortcut.
|
||||
/// @return true if a keyboard shortcut is assigned.
|
||||
bool hasKey();
|
||||
/// Retrieve the control's current keyboard shortcut.
|
||||
/// @return the currently-assigned keyboard shortcut.
|
||||
/// @note You should first check that a shortcut is assigned using hasKey().
|
||||
cKey getAttachedKey();
|
||||
/// Attach a click handler to this control.
|
||||
/// @param f The click handler to attach.
|
||||
/// @throw xHandlerNotSupported if this control does not support click handlers. Most controls do support click handlers.
|
||||
/// @note Only one click handler can be set at a time. To remove the click handler, set it to null.
|
||||
///
|
||||
/// A click handler must be able to accept three parameters: a reference to the containing dialog, the unique key of the
|
||||
/// clicked item, and a representation of any modifier keys that are currently held.
|
||||
virtual void attachClickHandler(click_callback_t f) throw(xHandlerNotSupported) = 0;
|
||||
/// Attach a focus handler to this control.
|
||||
/// @param f The focus handler to attach.
|
||||
/// @throw xHandlerNotSupported if this control does not support focus handlers. Most controls do not support focus handlers.
|
||||
/// @note Only one focus handler can be set at a time. To remove the focus handler, set it to null.
|
||||
///
|
||||
/// A focus handler must be able to accept three parameters: a reference to the containing dialog, the unique key of the
|
||||
/// clicked item, and a boolean indicating whether focus is being lost or gained; a value of true indicates that
|
||||
/// focus is being lost, while false indicates it's being gained. Most handlers will only need to act when the
|
||||
/// third parameter is true. If the handler returns false, the focus change is cancelled.
|
||||
virtual void attachFocusHandler(focus_callback_t f) throw(xHandlerNotSupported) = 0;
|
||||
/// Trigger the click handler for this control.
|
||||
/// @param me A reference to the current dialog.
|
||||
/// @param id The unique key of this control.
|
||||
/// @param mods The currently-held keyboard modifiers.
|
||||
/// @return true if the event should continue, false if it should be cancelled.
|
||||
virtual bool triggerClickHandler(cDialog& me, std::string id, eKeyMod mods);
|
||||
/// Trigger the focus handler for this control.
|
||||
/// @param me A reference to the current dialog.
|
||||
/// @param id The unique key of this control.
|
||||
/// @param losingFocus true if this control is losing focus, false if it is gaining focus.
|
||||
/// @return true if the event should continue, false if it should be cancelled.
|
||||
virtual bool triggerFocusHandler(cDialog& me, std::string id, bool losingFocus);
|
||||
//virtual void setPict(short pict, short type) = 0;
|
||||
/// Make this control visible.
|
||||
virtual void show(); // cd_activate_item true
|
||||
/// Make this control invisible.
|
||||
virtual void hide(); // cd_activate_item false
|
||||
/// Check if this control is visible.
|
||||
/// @return true if it's visible
|
||||
bool isVisible(); // cd_get_active
|
||||
/// Set if this control is active. A control is normally active when the mouse button is held down within its bounding rect.
|
||||
/// @param active true if it should be active, false if not
|
||||
void setActive(bool active); // "active" here means "selected", so if it's a button, draw it pressed
|
||||
/// Get the type of this control
|
||||
/// @return The type of control
|
||||
eControlType getType();
|
||||
/// Set the control's text.
|
||||
/// @param l The new text.
|
||||
virtual void setText(std::string l);
|
||||
/// Fetch the control's text.
|
||||
/// @return The control's current text.
|
||||
virtual std::string getText();
|
||||
/// Get the bounding rect of this control.
|
||||
/// @return The control's bounding rect.
|
||||
RECT getBounds();
|
||||
/// Set the bounding rect of this control.
|
||||
/// @param newBounds The new bounding rect.
|
||||
void setBounds(RECT newBounds);
|
||||
/// Set the position of this control.
|
||||
/// @param to The new position.
|
||||
void relocate(location to);
|
||||
/// Get the control's text as an integer.
|
||||
/// @return The control's text, coerced to an integer.
|
||||
long long getTextAsNum();
|
||||
/// Set the control's text to an integer value.
|
||||
/// @param what The desired value.
|
||||
void setTextToNum(long long what);
|
||||
/// Set one of the control's formatting parameters.
|
||||
/// @param prop The parameter to set.
|
||||
/// @param val The desired value of the parameter.
|
||||
/// @throw xUnsupportedProp if this control doesn't support the given parameter.
|
||||
virtual void setFormat(eFormat prop, short val) throw(xUnsupportedProp) = 0;
|
||||
/// Get one of the control's formatting parameters.
|
||||
/// @param prop The parameter to retrieve.
|
||||
/// @return The value of the parameter.
|
||||
/// @throw xUnsupportedProp if this control doesn't support the given parameter.
|
||||
virtual short getFormat(eFormat prop) throw(xUnsupportedProp) = 0;
|
||||
/// Set the control's colour (usually text colour).
|
||||
/// @param clr The desired colour.
|
||||
/// @throw xUnsupportedProp if this control does not support colour.
|
||||
virtual void setColour(sf::Color clr) throw(xUnsupportedProp) = 0;
|
||||
/// Get the control's colour.
|
||||
/// @return The current colour.
|
||||
/// @throw xUnsupportedProp if this control does not support colour.
|
||||
virtual sf::Color getColour() throw(xUnsupportedProp) = 0;
|
||||
/// Check if the control is clickable.
|
||||
/// @return true if it's clickable.
|
||||
/// @note This does not indicate whether the control supports click handlers.
|
||||
/// In fact, some controls return true only if a click handler is assigned.
|
||||
/// Others, like editable text fields, are clickable but do not support click handlers.
|
||||
virtual bool isClickable() = 0;
|
||||
/// Handles the action of clicking this control.
|
||||
/// @param where The exact location at which the mouse was pressed, relative to the dialog.
|
||||
/// @return true if the click was successful; false if it was cancelled.
|
||||
///
|
||||
/// This function should implement an event loop and terminate when the mouse button is released.
|
||||
/// It can be overridden to customize the reaction of the control to mouse events.
|
||||
/// The default implementation works for a simple clickable object such as a button that
|
||||
/// should be hilited in some way while pressed and is cancelled by releasing the mouse
|
||||
/// button outside the control's bounds.
|
||||
virtual bool handleClick(location where);
|
||||
/// Create a new control attached to an arbitrary window, rather than a dialog.
|
||||
/// @param t The type of the control.
|
||||
/// @param p The parent window.
|
||||
cControl(eControlType t, sf::RenderWindow& p);
|
||||
/// Create a new control attached to a dialog.
|
||||
/// @param t The type of the control.
|
||||
/// @param p The parent dialog.
|
||||
cControl(eControlType t, cDialog& p);
|
||||
virtual ~cControl();
|
||||
/// Draw the control into its parent window.
|
||||
virtual void draw() = 0;
|
||||
cControl& operator=(cControl& other) = delete;
|
||||
cControl(cControl& other) = delete;
|
||||
protected:
|
||||
/// The parent dialog of the control.
|
||||
/// May be null, if the control was created via cControl(eControlType,sf::RenderWindow&).
|
||||
cDialog* parent;
|
||||
/// The parent window of the control.
|
||||
/// This is for use in implementing draw().
|
||||
sf::RenderWindow* inWindow;
|
||||
/// The control's current text.
|
||||
std::string lbl;
|
||||
bool visible, depressed = false; // depressed is only applicable for clickable controls
|
||||
/// Whether the control is visible
|
||||
bool visible, depressed = false; ///< Whether the control is depressed; only applicable for clickable controls
|
||||
/// The control's bounding rect.
|
||||
RECT frame;
|
||||
/// The control's frame style.
|
||||
int frameStyle;
|
||||
/// The control's attached key.
|
||||
cKey key;
|
||||
/// Draw a frame around the control.
|
||||
/// @param amt How much to offset the frame from the control's bounding rect.
|
||||
/// @param med_or_lt true to use a darker colour for the frame.
|
||||
/// @note The TXT_FRAMESTYLE formatting property is normally used for the second parameter.
|
||||
void drawFrame(short amt, bool med_or_lt);
|
||||
/// Redraws the parent dialog, if any.
|
||||
/// Intended to be called from handleClick(), where there is usually a minor event loop happening.
|
||||
void redraw();
|
||||
private:
|
||||
eControlType type;
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#ifndef DIALOG_H
|
||||
#define DIALOG_H
|
||||
|
||||
/// @file
|
||||
/// Dialog-related classes and types.
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
#include <string>
|
||||
@@ -24,10 +27,12 @@
|
||||
class cControl;
|
||||
class cTextField;
|
||||
|
||||
/// Specifies the relative position of a control's labelling text.
|
||||
enum eLabelPos {
|
||||
LABEL_LEFT, LABEL_ABOVE, LABEL_RIGHT, LABEL_BELOW,
|
||||
};
|
||||
|
||||
/// Defines a fancy dialog box with various controls.
|
||||
class cDialog {
|
||||
typedef std::map<std::string,cControl*>::iterator ctrlIter;
|
||||
std::map<std::string,cControl*> controls;
|
||||
@@ -43,35 +48,113 @@ class cDialog {
|
||||
template<typename Iter> void handleTabOrder(std::string& itemHit, Iter begin, Iter end);
|
||||
std::vector<std::pair<std::string,cTextField*>> tabOrder;
|
||||
public:
|
||||
/// Performs essential startup initialization. Generally should not be called directly.
|
||||
static void init();
|
||||
static const short BG_LIGHT, BG_DARK;
|
||||
/// The light background pattern used by the scenario editor dialogs.
|
||||
static const short BG_LIGHT, BG_DARK; ///< The dark background pattern used by the game dialogs.
|
||||
/// The default background pattern for newly created dialogs.
|
||||
static short defaultBackground;
|
||||
explicit cDialog(cDialog* p = NULL); // dialog with no items
|
||||
/// Create a new dialog with no items.
|
||||
/// @param p Optionally, a parent dialog.
|
||||
explicit cDialog(cDialog* p = NULL);
|
||||
/// Creates a new dialog, loading its definition from a file.
|
||||
/// @param path The name of the file to load. It must be in the game's dialogs directory.
|
||||
/// @param p Optionally, a parent dialog.
|
||||
explicit cDialog(std::string path, cDialog* p = NULL); // cd_create_dialog
|
||||
~cDialog(); // cd_kill_dialog
|
||||
bool add(cControl* what, RECT ctrl_frame, std::string key); // returns false if the key is used, true if the control was added
|
||||
bool remove(std::string key); // returns true if the key existed and was removed, false if the key did not exist
|
||||
bool addLabelFor(std::string key, std::string label, eLabelPos where, short offset, bool bold); // returns true if the label was added
|
||||
/// Add a new control to the dialog.
|
||||
/// @param what A pointer to the control, which should already be constructed.
|
||||
/// @param ctrl_frame The control's bounding rect, which includes its position in the dialog.
|
||||
/// @param key A key to be used to look up the control later.
|
||||
/// @return false if the key is used, true if the control was added.
|
||||
/// @note This function is intended for internal use, which is why it takes a control pointer instead of a unique key.
|
||||
bool add(cControl* what, RECT ctrl_frame, std::string key);
|
||||
/// Remove a control from the dialog.
|
||||
/// @param key The control's unique key.
|
||||
/// @return true if the key existed and the control was removed, false if the key did not exist
|
||||
bool remove(std::string key);
|
||||
/// Add a new static text control, positioned to function as a label for an existing control.
|
||||
/// @param key The unique key of the control to be labelled.
|
||||
/// @param label The text of the label.
|
||||
/// @param where Specifies the position of the label relative to the control.
|
||||
/// @param offset An offset in pixels between the control and the label.
|
||||
/// @param bold If true, the label will be bolded.
|
||||
/// @return true if the label was added, false if not (usually because it already had a label)
|
||||
bool addLabelFor(std::string key, std::string label, eLabelPos where, short offset, bool bold);
|
||||
/// Show the dialog and start its event loop. All dialogs are modal.
|
||||
void run(); // cd_run_dialog
|
||||
/// Get the result of the dialog.
|
||||
/// @tparam type The result type.
|
||||
/// @throw boost::bad_any_cast if the provided result type is different from the type set by getResult().
|
||||
/// @return The dialog's result.
|
||||
template<typename type> type getResult(){
|
||||
return boost::any_cast<type>(result);
|
||||
}
|
||||
/// Set the result of the dialog.
|
||||
/// @tparam type The result type.
|
||||
/// @param val The result value.
|
||||
template<typename type> void setResult(const type& val){
|
||||
result = val;
|
||||
}
|
||||
/// Set the background pattern of the dialog.
|
||||
/// @param n The numeric index of the background pattern, which should be in the range [0,20].
|
||||
/// You can use the constants BG_LIGHT or BG_DARK to reference the most commonly used backgrounds.
|
||||
void setBg(short n);
|
||||
/// Get the background pattern of the dialog.
|
||||
/// @return The numeric index of the background pattern.
|
||||
short getBg();
|
||||
/// Set the default text colour applied to new dialogs when loading from a file.
|
||||
/// @param clr The text colour.
|
||||
void setDefTextClr(sf::Color clr);
|
||||
/// Set the default button, which will be drawn outlined and respond to the enter key.
|
||||
/// @param defBtn The unique key of the default button.
|
||||
///
|
||||
/// This function does not check that the default button exists and is a button.
|
||||
void setDefBtn(std::string defBtn);
|
||||
/// Get the default text colour applied to new dialogs when loading from a file.
|
||||
/// @return The text colour.
|
||||
sf::Color getDefTextClr();
|
||||
bool setFocus(cTextField* newFocus, bool force = false); // Setting force = true skips focus handlers
|
||||
/// Set the focused text field.
|
||||
/// @param newFocus A pointer to the text field to receive focus.
|
||||
/// @param force If true, the change will be forced.
|
||||
/// The focus handlers for both the previously focused text field and the newly focused text field will not be triggered.
|
||||
/// @return true if the focus changed; if it returns false, it could mean either that the control did not exist in the dialog
|
||||
/// or that one of the focus handlers prevented the focus change.
|
||||
/// @note This function is intended for internal use, which is why it takes a control pointer instead of a unique key.
|
||||
bool setFocus(cTextField* newFocus, bool force = false);
|
||||
/// Close the dialog.
|
||||
/// @param triggerFocus true to allow the focus handler of the currently focused text field to prevent the dialog from closing
|
||||
/// @return true unless the currently focused field prevented the dialog from closing
|
||||
///
|
||||
/// Generally, you would pass true in a handler for an OK button and false in a handler for a Cancel button.
|
||||
bool toast(bool triggerFocus);
|
||||
/// Get a reference to a control.
|
||||
/// @param id The unique key of the control.
|
||||
/// @throw std::invalid_argument if the control does not exist.
|
||||
/// @return a reference to the requested control.
|
||||
cControl& getControl(std::string id);
|
||||
/// @copydoc getControl()
|
||||
cControl& operator[](std::string id);
|
||||
/// Recalculate the dialog's bounding rect.
|
||||
/// Call this after adding controls to the dialog to ensure that the control is within the bounding rect.
|
||||
void recalcRect();
|
||||
// TODO: It seems like a bad thing for these two to not use the typedefs...
|
||||
/// Attach the same click handler to several controls.
|
||||
/// @param handler The handler to attach.
|
||||
/// @param controls A list of the unique keys of the controls to which you want the handler attached.
|
||||
/// @throw xHandlerNotSupported if any of the controls do not support click handlers.
|
||||
/// @throw std::invalid_argument if any of the controls do not exist.
|
||||
/// @see cControl::attachClickHandler()
|
||||
void attachClickHandlers(std::function<bool(cDialog&,std::string,eKeyMod)> handler, std::vector<std::string> controls);
|
||||
/// Attach the same focus handler to several controls.
|
||||
/// @param handler The handler to attach.
|
||||
/// @param controls A list of the unique keys of the controls to which you want the handler attached.
|
||||
/// @throw xHandlerNotSupported if any of the controls do not support focus handlers.
|
||||
/// @throw std::invalid_argument if any of the controls do not exist.
|
||||
/// @see cControl::attachFocusHandler()
|
||||
void attachFocusHandlers(std::function<bool(cDialog&,std::string,bool)> handler, std::vector<std::string> controls);
|
||||
/// Get the bounding rect of the dialog.
|
||||
/// @return The dialog's bounding rect.
|
||||
RECT getBounds() {return winRect;}
|
||||
cDialog& operator=(cDialog& other) = delete;
|
||||
cDialog(cDialog& other) = delete;
|
||||
@@ -87,44 +170,78 @@ private:
|
||||
friend class cControl;
|
||||
};
|
||||
|
||||
/// Thrown when an invalid element is found while parsing an XML dialog definition.
|
||||
class xBadNode : std::exception {
|
||||
std::string type, dlg;
|
||||
int row, col;
|
||||
const char* msg;
|
||||
public:
|
||||
/// Construct a new exception.
|
||||
/// @param t The tag name of the invalid element.
|
||||
/// @param r The line number of the element in the source.
|
||||
/// @param c The column number of the element in the source.
|
||||
/// @param dlg The name of the file in which the element occurred.
|
||||
xBadNode(std::string t, int r, int c, std::string dlg) throw();
|
||||
~xBadNode() throw();
|
||||
/// @return The error message.
|
||||
const char* what() throw();
|
||||
};
|
||||
|
||||
/// Thrown when an invalid attribute is found while parsing an XML dialog definition.
|
||||
class xBadAttr : std::exception {
|
||||
std::string type, name, dlg;
|
||||
int row, col;
|
||||
const char* msg;
|
||||
public:
|
||||
/// Construct a new exception.
|
||||
/// @param t The tag name of the element with the invalid attribute.
|
||||
/// @param n The name of the invalid attribute.
|
||||
/// @param r The line number of the element in the source.
|
||||
/// @param c The column number of the element in the source.
|
||||
/// @param dlg The name of the file in which the element occurred.
|
||||
xBadAttr(std::string t,std::string n, int r, int c, std::string dlg) throw();
|
||||
~xBadAttr() throw();
|
||||
/// @return The error message.
|
||||
const char* what() throw();
|
||||
};
|
||||
|
||||
/// Thrown when an element is missing a required attribute while parsing an XML dialog definition.
|
||||
class xMissingAttr : std::exception {
|
||||
std::string type, name, dlg;
|
||||
int row, col;
|
||||
const char* msg;
|
||||
public:
|
||||
/// Construct a new exception.
|
||||
/// @param t The tag name of the element with the missing attribute.
|
||||
/// @param n The name of the missing attribute.
|
||||
/// @param r The line number of the element in the source.
|
||||
/// @param c The column number of the element in the source.
|
||||
/// @param dlg The name of the file in which the element occurred.
|
||||
xMissingAttr(std::string t,std::string n, int r, int c, std::string dlg) throw();
|
||||
~xMissingAttr() throw();
|
||||
/// @return The error message.
|
||||
const char* what() throw();
|
||||
};
|
||||
|
||||
/// Thrown when an invalid value is found anywhere within an element's or attribute's content.
|
||||
class xBadVal : std::exception {
|
||||
std::string type, name, val, dlg;
|
||||
int row, col;
|
||||
const char* msg;
|
||||
public:
|
||||
/// A magic value to indicate errors in an element's content, rather than an attribute's content.
|
||||
static constexpr const char*const CONTENT = "<content>";
|
||||
/// Construct a new exception.
|
||||
/// @param t The tag name of the element with the invalid value.
|
||||
/// @param n The name of the attribute with the invalid value.
|
||||
/// You should pass xBadVal::CONTENT if the bad value is within an element's content.
|
||||
/// @param v The invalid value.
|
||||
/// @param r The line number of the element in the source.
|
||||
/// @param c The column number of the element in the source.
|
||||
/// @param dlg The name of the file in which the element occurred.
|
||||
xBadVal(std::string t,std::string n,std::string v, int r, int c, std::string dlg) throw();
|
||||
~xBadVal() throw();
|
||||
/// @return The error message.
|
||||
const char* what() throw();
|
||||
};
|
||||
|
||||
|
||||
@@ -9,15 +9,32 @@
|
||||
#ifndef BoE_dialog_keys_h
|
||||
#define BoE_dialog_keys_h
|
||||
|
||||
/// @file
|
||||
/// Key-related classes and types.
|
||||
|
||||
/// Keyboard modifiers, as a bit-field-like enumeration.
|
||||
/// Note that mod_ctrl refers to both the control key and the Mac's command key.
|
||||
/// It also covers the "meta" key supported in certain other systems, and may
|
||||
/// also be triggered by the Windows key.
|
||||
///
|
||||
/// Use mod_contains() to check if a specific modifier is set in the bit field.
|
||||
enum eKeyMod {
|
||||
mod_none = 0,
|
||||
mod_none = 0, ///< No modifier
|
||||
/// @{ A single modifier
|
||||
mod_alt = 1, mod_shift = 2, mod_ctrl = 4,
|
||||
/// @}
|
||||
/// @{ Two modifiers
|
||||
mod_altshift = mod_alt + mod_shift,
|
||||
mod_altctrl = mod_alt + mod_ctrl,
|
||||
mod_shiftctrl = mod_shift + mod_ctrl,
|
||||
/// @}
|
||||
/// All modifiers
|
||||
mod_all = mod_alt + mod_shift + mod_ctrl,
|
||||
};
|
||||
|
||||
/// Representations of special keys.
|
||||
/// Not all of these represent a literal single keypress.
|
||||
/// Some refer to common two-keypress keyboard shortcuts.
|
||||
enum eSpecKey {
|
||||
key_left, key_right, key_up, key_down,
|
||||
key_esc, key_enter, key_tab, key_help, // key_help should bind to the help key on Mac and the F1 key on Windows
|
||||
@@ -28,21 +45,47 @@ enum eSpecKey {
|
||||
// This is in addition to the home, end, pgup, pgdn keys triggering these.
|
||||
};
|
||||
|
||||
/// Represents a keypress.
|
||||
struct cKey {
|
||||
/// If true, it's a special key. Otherwise, a character has been typed.
|
||||
bool spec;
|
||||
union {
|
||||
/// The character that has been typed.
|
||||
unsigned char c;
|
||||
/// The special key that was pressed.
|
||||
eSpecKey k;
|
||||
};
|
||||
/// A bit field of held key modifiers.
|
||||
eKeyMod mod;
|
||||
};
|
||||
|
||||
/// Combine two key modifiers.
|
||||
/// @param lhs @param rhs
|
||||
/// @return lhs + rhs
|
||||
eKeyMod operator + (eKeyMod lhs, eKeyMod rhs);
|
||||
/// Cancel out a key modifier.
|
||||
/// @param lhs @param rhs
|
||||
/// @return lhs - rhs
|
||||
eKeyMod operator - (eKeyMod lhs, eKeyMod rhs);
|
||||
/// Combine two key modifiers.
|
||||
/// @param lhs The key modifier set to modify.
|
||||
/// @param rhs The key modifier to remove.
|
||||
/// @return lhs, now modified.
|
||||
eKeyMod&operator += (eKeyMod&lhs, eKeyMod rhs);
|
||||
/// Cancel out a key modifier.
|
||||
/// @param lhs The key modifier set to modify.
|
||||
/// @param rhs The key modifier to remove.
|
||||
/// @return lhs, now modified.
|
||||
eKeyMod&operator -= (eKeyMod&lhs, eKeyMod rhs);
|
||||
|
||||
/// Compare two keys.
|
||||
/// @param a @param b
|
||||
/// @return Whether they are equal.
|
||||
bool operator== (cKey a, cKey b);
|
||||
/// Check if haystack contains the modifier specified by needle.
|
||||
/// @param haystack The set of modifiers to check.
|
||||
/// @param needle The modifier to check for; generally one of mod_alt, mod_shift, or mod_ctrl.
|
||||
/// @return true if the needle is in the haystack
|
||||
bool mod_contains(eKeyMod haystack, eKeyMod needle);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,7 +6,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
size_t available_btns[53] = { // This array is a list of indices into the following array.
|
||||
/// @file
|
||||
/// Preset button specifications for cThreeChoice
|
||||
|
||||
/// The buttons available to special nodes; consists of indices into the basic_buttons array.
|
||||
size_t available_btns[53] = {
|
||||
0, 63, 64, 65, 1, 4, 5, 8, 128,9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 29, 51,
|
||||
60, 61, 62, 66, 69, 70, 71, 72, 73, 74,
|
||||
@@ -15,6 +19,7 @@ size_t available_btns[53] = { // This array is a list of indices into the follow
|
||||
135,136,137
|
||||
};
|
||||
|
||||
/// A list of preset button types. Many of these are unused.
|
||||
bbtt basic_buttons[] = {
|
||||
{BTN_DONE, " ", {false,0,mod_none}}, // Formerly DLG_BTN_REG with "Done " as the string
|
||||
{BTN_REG, "Ask", {false,0,mod_none}},
|
||||
|
||||
@@ -536,7 +536,7 @@ void giveError(std::string str1, std::string str2, cDialog* parent){
|
||||
error.show();
|
||||
}
|
||||
|
||||
void oopsError(short error, short code, short mode){ // mode is 0 for scened, 1 for game, 2 for pced
|
||||
void oopsError(short error, short code, short mode){
|
||||
std::ostringstream error_str1, error_str2;
|
||||
static const char* progname[3] = {"the scenario editor", "Blades of Exile", "the PC editor"};
|
||||
static const char* filetname[3] = {"scenario", "game", "game"};
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#ifndef DIALOG_UTIL_H
|
||||
#define DIALOG_UTIL_H
|
||||
|
||||
/// @file
|
||||
/// A set of utility classes for simple and common dialogs.
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
@@ -19,9 +22,10 @@
|
||||
#include "button.h"
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
//typedef void (*record_callback_t)(std::string,std::string);
|
||||
/// The signature of a record handler for cStrDlog.
|
||||
typedef std::function<void(cDialog&)> record_callback_t;
|
||||
|
||||
/// A simple dialog with one or two long strings, an optional title, and an optional record button.
|
||||
class cStrDlog {
|
||||
static std::string getFileName(short n_strs, ePicType type, bool hasTitle);
|
||||
cDialog dlg;
|
||||
@@ -32,31 +36,75 @@ class cStrDlog {
|
||||
bool onRecord(std::string id);
|
||||
bool onDismiss();
|
||||
public:
|
||||
/// Construct a string dialog.
|
||||
/// @param str1 The first string.
|
||||
/// @param str2 The second string. If left as an empty string, there will be only one string in the dialog.
|
||||
/// @param title The title. If left as an empty string, there will be no title.
|
||||
/// @param pic The icon to show at the top left.
|
||||
/// @param t The type of icon to show.
|
||||
/// @param parent Optionally, a parent dialog.
|
||||
cStrDlog(std::string str1,std::string str2,std::string title,pic_num_t pic,ePicType t,cDialog* parent = NULL);
|
||||
/// Set a sound to be played when the dialog is shown.
|
||||
/// @param num The sound number.
|
||||
/// @return This object, for method-call chaining.
|
||||
cStrDlog& setSound(snd_num_t num);
|
||||
/// Set a record handler.
|
||||
/// @param rec The handler.
|
||||
/// @return This object, for method-call chaining.
|
||||
/// @note Only one record handler can be set at a time. To remove it, set it to null.
|
||||
/// @note The presence of the Record button is determined entirely by the presence of a record handler.
|
||||
///
|
||||
/// A record handler should take one parameter, which is a reference to the dialog.
|
||||
/// (That's the cDialog, not the cStrDlog.) It should return void.
|
||||
cStrDlog& setRecordHandler(record_callback_t rec);
|
||||
/// Reference the cDialog powering this choice dialog, perhaps to customize details of it.
|
||||
/// @return A pointer to the dialog.
|
||||
cDialog* operator->();
|
||||
/// Show the dialog.
|
||||
void show();
|
||||
};
|
||||
|
||||
/// A simple dialog that lets you select one of several buttons.
|
||||
/// This class loads a definition from a file, so there can be any amount of other stuff in the dialog,
|
||||
/// and the buttons could be arranged in any fashion you want.
|
||||
class cChoiceDlog {
|
||||
cDialog dlg;
|
||||
protected:
|
||||
/// The click handler for the dialog's buttons.
|
||||
/// @param me A reference to the current dialog.
|
||||
/// @param id The unique key of the clicked control.
|
||||
/// @return true, indicating the event should continue.
|
||||
bool onClick(cDialog& me, std::string id);
|
||||
/// Create a choice dialog, but don't initialize it.
|
||||
/// @param p Optionally, a parent dialog.
|
||||
explicit cChoiceDlog(cDialog* p = NULL);
|
||||
public:
|
||||
/// Create a choice dialog with just one button.
|
||||
/// @param file The file to load the dialog definition from.
|
||||
/// @param p Optionally, a parent dialog.
|
||||
/// @note The dialog definition file must include a button whose name attribute is "okay".
|
||||
explicit cChoiceDlog(std::string file, cDialog* p = NULL);
|
||||
/// Create a choice dialog with several buttons.
|
||||
/// @param file The file to load the dialog definition from.
|
||||
/// @param buttons A list of the buttons to handle. All of them must be defined in the file.
|
||||
/// @param p Optionally, a parent dialog.
|
||||
cChoiceDlog(std::string file, std::vector<std::string> buttons, cDialog* p = NULL);
|
||||
/// Reference the cDialog powering this choice dialog, perhaps to customize details of it.
|
||||
/// @return A pointer to the dialog.
|
||||
cDialog* operator->();
|
||||
/// Show the dialog.
|
||||
/// @return The unique key of the clicked button.
|
||||
std::string show();
|
||||
};
|
||||
|
||||
struct bbtt { // stands for "basic button type template"
|
||||
eBtnType type;
|
||||
std::string label;
|
||||
cKey defaultKey;
|
||||
/// Basic button type template
|
||||
struct bbtt {
|
||||
eBtnType type; ///< The type of the preset button.
|
||||
std::string label; ///< The preset button's label, if any.
|
||||
cKey defaultKey; ///< The preset button's default key shortcut, if any.
|
||||
};
|
||||
|
||||
/// Represents a preset button for use with cThreeChoice.
|
||||
typedef boost::optional<bbtt> cBasicButtonType;
|
||||
|
||||
namespace {cBasicButtonType null_btn = boost::none;}
|
||||
@@ -65,6 +113,10 @@ extern bbtt basic_buttons[];
|
||||
extern size_t available_btns[53];
|
||||
#endif
|
||||
|
||||
/// A choice dialog with several strings and up to three buttons.
|
||||
/// This is the class used for dialogs generated by special nodes.
|
||||
/// It generates the dialog dynamically from the given input.
|
||||
/// Note that the dialog is not limited to six strings.
|
||||
class cThreeChoice : public cChoiceDlog {
|
||||
//static std::string getFileName(size_t n_strs);
|
||||
cBasicButtonType btns[3];
|
||||
@@ -74,12 +126,34 @@ class cThreeChoice : public cChoiceDlog {
|
||||
void init_pict(pic_num_t pic);
|
||||
const ePicType type;
|
||||
public:
|
||||
/// Create a dialog with just one button.
|
||||
/// @param strings A list of the strings to place in the dialog.
|
||||
/// @param button The specification of the button.
|
||||
/// @param pic The icon to show at the top left.
|
||||
/// @param t The type of the icon.
|
||||
/// @param parent Optionally, a parent dialog.
|
||||
cThreeChoice(std::vector<std::string>& strings, cBasicButtonType button, pic_num_t pic, ePicType t, cDialog* parent = NULL);
|
||||
/// Create a dialog with up to three buttons.
|
||||
/// @param strings A list of the strings to place in the dialog.
|
||||
/// @param buttons A list of the button specifications.
|
||||
/// @param pic The icon to show at the top left.
|
||||
/// @param t The type of the icon.
|
||||
/// @param parent Optionally, a parent dialog.
|
||||
cThreeChoice(std::vector<std::string>& strings, std::array<cBasicButtonType, 3>& buttons, pic_num_t pic, ePicType t, cDialog* parent = NULL);
|
||||
/// Create a dialog with up to three buttons.
|
||||
/// @param strings A list of the strings to place in the dialog.
|
||||
/// @param buttons A list of the index of the button; this is an index into available_btns which is in turn used to index basic_buttons.
|
||||
/// @param pic The icon to show at the top left.
|
||||
/// @param t The type of the icon.
|
||||
/// @param parent Optionally, a parent dialog.
|
||||
cThreeChoice(std::vector<std::string>& strings, std::array<short, 3>& buttons, pic_num_t pic, ePicType t, cDialog* parent = NULL);
|
||||
/// @copydoc cChoiceDlog::show()
|
||||
/// @note The unique key in this case is the label specified in the button specification.
|
||||
std::string show();
|
||||
};
|
||||
|
||||
/// A dialog that presents a list of strings with LEDs and allows you to choose one.
|
||||
/// The list may span several pages.
|
||||
class cStringChoice {
|
||||
static const size_t per_page;
|
||||
cDialog dlg;
|
||||
@@ -94,12 +168,29 @@ class cStringChoice {
|
||||
size_t page, cur;
|
||||
cLedGroup* leds;
|
||||
public:
|
||||
/// Initializes a dialog from a list of strings.
|
||||
/// @param strs A list of all strings in the dialog.
|
||||
/// @param title The title to show in the dialog.
|
||||
/// @param parent Optionally, a parent dialog.
|
||||
explicit cStringChoice(std::vector<std::string>& strs, std::string title, cDialog* parent = NULL);
|
||||
/// Initializes a dialog from an iterator pair.
|
||||
/// @param begin An iterator to the first string in the dialog.
|
||||
/// @param end An iterator to one past the last string in the dialog.
|
||||
/// @param title The title to show in the dialog.
|
||||
/// @param parent Optionally, a parent dialog.
|
||||
/// @note Currently, only vector iterators are supported.
|
||||
cStringChoice(std::vector<std::string>::iterator begin, std::vector<std::string>::iterator end, std::string title, cDialog* parent = NULL);
|
||||
/// Reference the cDialog powering this choice dialog, perhaps to customize details of it.
|
||||
/// @return A pointer to the dialog.
|
||||
cDialog* operator->();
|
||||
/// Show the dialog.
|
||||
/// @param selectedIndex The index of the string that should be initially selected when the dialog is shown.
|
||||
/// @return The index of the newly selected string; if the user cancelled, this will be equal to selectedIndex.
|
||||
/// If initialized from an iterator range, this will be relative to begin.
|
||||
size_t show(size_t selectedIndex);
|
||||
};
|
||||
|
||||
/// Like cStringChoice, but presents a list of icons rather than strings.
|
||||
class cPictChoice {
|
||||
static const size_t per_page;
|
||||
bool didAccept;
|
||||
@@ -115,17 +206,51 @@ class cPictChoice {
|
||||
size_t page, cur;
|
||||
cLedGroup* leds;
|
||||
public:
|
||||
/// Initializes a dialog from a list of icons.
|
||||
/// @param pics A list of all icons in the dialog.
|
||||
/// @param t The type of icons to show; all icons are assumed to be of the same type.
|
||||
/// @param parent Optionally, a parent dialog.
|
||||
cPictChoice(std::vector<pic_num_t>& pics, ePicType t, cDialog* parent = NULL);
|
||||
/// Initializes a dialog from a list of icons.
|
||||
/// @param pics A list of all icons in the dialog as {num,type} pairs.
|
||||
/// @param parent Optionally, a parent dialog.
|
||||
cPictChoice(std::vector<std::pair<pic_num_t,ePicType>>& pics, cDialog* parent = NULL);
|
||||
/// Initializes a dialog from an iterator pair.
|
||||
/// @param begin An iterator to the first icon in the dialog.
|
||||
/// @param end An iterator to one past the last icon in the dialog.
|
||||
/// @param t The type of icons to show; all icons are assumed to be of the same type.
|
||||
/// @param parent Optionally, a parent dialog.
|
||||
cPictChoice(std::vector<pic_num_t>::iterator begin, std::vector<pic_num_t>::iterator end, ePicType t, cDialog* parent = NULL);
|
||||
/// Initializes a dialog from an index pair.
|
||||
/// @param first The number of the first icon in the dialog.
|
||||
/// @param last The number of the last icon in the dialog.
|
||||
/// @param t The type of icons to show; all icons are assumed to be of the same type.
|
||||
/// @param parent Optionally, a parent dialog.
|
||||
cPictChoice(pic_num_t first, pic_num_t last, ePicType t, cDialog* parent = NULL);
|
||||
/// Reference the cDialog powering this choice dialog, perhaps to customize details of it.
|
||||
/// @return A pointer to the dialog.
|
||||
cDialog* operator->();
|
||||
/// Show the dialog.
|
||||
/// @param cur_sel The index of the icon that should be initially selected when the dialog is shown.
|
||||
/// @return false if the user clicked Cancel, true otherwise.
|
||||
/// @note If for some reason an icon appears twice in the list, there's no way to determine which of the two was selected.
|
||||
bool show(size_t cur_sel);
|
||||
/// Get the chosen icon.
|
||||
/// @return The number of the chosen icon.
|
||||
pic_num_t getPicChosen();
|
||||
/// Get the chosen icon.
|
||||
/// @return The type of the chosen icon.
|
||||
ePicType getPicChosenType();
|
||||
// returns the _number_ of the chosen picture, _not_ the index; there's no way to distinguish between duplicates
|
||||
};
|
||||
#endif
|
||||
|
||||
/// Shows a simple error dialog.
|
||||
/// @param str1 The first string in the error dialog.
|
||||
/// @param str2 The second string in the error dialog.
|
||||
/// @param parent Optionally, a parent dialog.
|
||||
void giveError(std::string str1, std::string str2 = "", cDialog* parent = NULL);
|
||||
/// Shows a generic error dialog and exits.
|
||||
/// @param error An arbitrary code intended to be used for locating the error in the source.
|
||||
/// @param code A code indicating the result of a failed action that triggered the error.
|
||||
/// @param mode 0 for scenario editor, 1 for game, 2 for pc editor
|
||||
void oopsError(short error,short code = 0, short mode = 0);
|
||||
|
||||
@@ -9,36 +9,59 @@
|
||||
#ifndef FIELD_H
|
||||
#define FIELD_H
|
||||
|
||||
/// @file
|
||||
/// Field-related classes and types.
|
||||
|
||||
#include <string>
|
||||
#include "control.h"
|
||||
|
||||
/// The field's expected input type.
|
||||
enum eFldType {
|
||||
FLD_INT,
|
||||
FLD_UINT,
|
||||
FLD_REAL,
|
||||
FLD_TEXT,
|
||||
FLD_INT, ///< A field that accepts only integers.
|
||||
FLD_UINT, ///< A field that accepts only positive integers.
|
||||
FLD_REAL, ///< A field that accepts any real (floating-point) number.
|
||||
FLD_TEXT, ///< A field that accepts any text. This is the default.
|
||||
};
|
||||
|
||||
/// An editable text field.
|
||||
/// The text field supports multiline input and text selection.
|
||||
/// It automatically scrolls to keep the insertion point in view.
|
||||
/// (If there's a current selection, the mobile end of the selection is kept in view.)
|
||||
/// Mouse support is currently nonexistent, except for focusing when clicked.
|
||||
/// There is no Unicode support.
|
||||
class cTextField : public cControl {
|
||||
public:
|
||||
void attachClickHandler(click_callback_t f) throw(xHandlerNotSupported);
|
||||
/// @copydoc cControl::attachFocusHandler()
|
||||
/// For text fields, this is triggered when it loses or gains the input focus.
|
||||
void attachFocusHandler(focus_callback_t f) throw();
|
||||
bool triggerFocusHandler(cDialog& me, std::string id, bool losingFocus);
|
||||
bool handleClick(location where);
|
||||
void setFormat(eFormat prop, short val) throw(xUnsupportedProp);
|
||||
short getFormat(eFormat prop) throw(xUnsupportedProp);
|
||||
void setColour(sf::Color clr) throw(xUnsupportedProp);
|
||||
/// Get the current input type of the field.
|
||||
/// @return The input type.
|
||||
eFldType getInputType();
|
||||
/// Set the input type of the field.
|
||||
/// @param newType The new input type.
|
||||
void setInputType(eFldType newType);
|
||||
sf::Color getColour() throw(xUnsupportedProp);
|
||||
/// Create a new editable text field.
|
||||
/// @param parent The parent dialog.
|
||||
explicit cTextField(cDialog* parent);
|
||||
bool isClickable();
|
||||
virtual ~cTextField();
|
||||
void draw();
|
||||
/// Check if this text field currently has input focus.
|
||||
/// @return true if it it is currently focused.
|
||||
bool hasFocus();
|
||||
/// Handle keyboard input.
|
||||
/// @param key The keypress to handle.
|
||||
void handleInput(cKey key);
|
||||
cTextField& operator=(cTextField& other) = delete;
|
||||
cTextField(cTextField& other) = delete;
|
||||
/// This field is only used by cDialog during the loading process. Changing it will have no effect.
|
||||
long tabOrder = 0;
|
||||
private:
|
||||
eFldType field_type;
|
||||
|
||||
@@ -9,12 +9,17 @@
|
||||
#ifndef MESSAGE_H
|
||||
#define MESSAGE_H
|
||||
|
||||
/// @file
|
||||
/// Message-related classes and types.
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
#include <string>
|
||||
#include "control.h"
|
||||
#include "graphtool.h" // for eFont
|
||||
|
||||
/// A simple static text message.
|
||||
/// This class can also create a frame for grouping controls or a clickable area.
|
||||
class cTextMsg : public cControl {
|
||||
public:
|
||||
void attachClickHandler(click_callback_t f) throw();
|
||||
@@ -24,7 +29,11 @@ public:
|
||||
short getFormat(eFormat prop) throw(xUnsupportedProp);
|
||||
void setColour(sf::Color clr) throw(xUnsupportedProp);
|
||||
sf::Color getColour() throw(xUnsupportedProp);
|
||||
/// Create a new text message.
|
||||
/// @param parent The parent dialog.
|
||||
explicit cTextMsg(cDialog& parent);
|
||||
/// Create a new text message without a parent dialog.
|
||||
/// @param parent The parent window.
|
||||
explicit cTextMsg(sf::RenderWindow& parent);
|
||||
bool isClickable();
|
||||
virtual ~cTextMsg();
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#ifndef PICT_H
|
||||
#define PICT_H
|
||||
|
||||
/// @file
|
||||
/// Icon-related classes and types.
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
#include <vector>
|
||||
@@ -16,86 +19,94 @@
|
||||
#include "graphtool.h" // for pic_num_t
|
||||
#include "control.h"
|
||||
|
||||
/// Specifies an icon type.
|
||||
enum ePicType {
|
||||
PIC_TER = 1, // 28x36 terrain graphic from the preset sheets
|
||||
PIC_TER_ANIM = 2, // 28x36 terrain graphic from the preset animated terrain sheet
|
||||
PIC_MONST = 3, // 28x36 monster graphic from the preset sheets
|
||||
PIC_DLOG = 4, // 36x36 dialog graphic from the preset sheet
|
||||
PIC_TALK = 5, // 32x32 talking portrait from the preset sheet
|
||||
PIC_SCEN = 6, // 32x32 scenario graphic from the scenario sheet
|
||||
PIC_ITEM = 7, // 28x36 item graphic from the large item sheet, or 18x18 item graphic from the small sheet centred in a 28x36 space
|
||||
PIC_PC = 8, // 28x36 pc graphic from the player sheet
|
||||
PIC_FIELD = 9, // 28x36 field graphic from the fields sheet
|
||||
PIC_BOOM = 10, // 28x36 boom graphic from the booms sheet
|
||||
PIC_FULL = 11, // entire sheet graphic; number is the resource ID
|
||||
PIC_MISSILE = 12, // 18x18 missile graphic from the missiles sheet
|
||||
PIC_DLOG_LG = 13, // 72x72 dialog graphic from the dialog sheet
|
||||
PIC_SCEN_LG = 14, // 64x64 scenario graphic (currently each is on its own sheet)
|
||||
PIC_TER_MAP = 15, // 12x12 map graphic... or should it be 6x6?
|
||||
PIC_STATUS = 16, // 12x12 status icon
|
||||
PIC_MONST_WIDE = 23, // 56x36 monster graphic from the preset sheets, resized to fit and centred in a 28x36 space
|
||||
PIC_MONST_TALL = 43, // 28x72 monster graphic from the preset sheets, resized to fit and centred in a 28x36 space
|
||||
PIC_MONST_LG = 63, // 56x72 monster graphic from the preset sheets, resized to fit in a 28x36 space
|
||||
PIC_CUSTOM_TER = 101, // 28x36 custom graphic from the custom sheets
|
||||
PIC_CUSTOM_TER_ANIM = 102,
|
||||
PIC_CUSTOM_MONST = 103,
|
||||
PIC_CUSTOM_DLOG = 104, // 36x36 dialog graphic drawn from two 18x26 halves in the custom sheets
|
||||
PIC_CUSTOM_TALK = 105, // 32x32 talking portrait drawn from two 16x32 halves in the custom sheets
|
||||
PIC_CUSTOM_SCEN = 106, // 32x32 scenario portrait loading from scenname.exr/scenario.png
|
||||
PIC_CUSTOM_ITEM = 107,
|
||||
PIC_CUSTOM_FULL = 111, // entire sheet graphic, drawn from scenname.exr/sheetxxx.png where xxx is the number
|
||||
PIC_CUSTOM_MISSILE = 112, // 18x18 missile graphic drawn from the the custom sheets
|
||||
PIC_CUSTOM_DLOG_LG = 113, // 72x72 dialog graphic from the custom sheet, taken from 8 successive slots
|
||||
PIC_CUSTOM_TER_MAP = 115, // 12x12 map graphic (should it be 6x6?) taken from the custom sheet
|
||||
PIC_CUSTOM_MONST_WIDE = 123, // 56x36 monster graphic from the custom sheets, resized to fit and centred in a 28x36 space
|
||||
PIC_CUSTOM_MONST_TALL = 143, // 28x72 monster graphic from the custom sheets, resized to fit and centred in a 28x36 space
|
||||
PIC_CUSTOM_MONST_LG = 163, // 56x72 monster graphic from the custom sheets, resized to fit in a 28x36 space
|
||||
PIC_PARTY_MONST = 203, // 28x36 graphic drawn from the savegame sheet
|
||||
PIC_PARTY_SCEN = 206, // 32x32 graphic drawn from the scenario headers sheet
|
||||
PIC_PARTY_ITEM = 207,
|
||||
PIC_PARTY_PC = 208,
|
||||
PIC_PARTY_MONST_WIDE = 223, // 56x36 monster graphic from the savegame sheet, resized to fit and centred in a 28x36 space
|
||||
PIC_PARTY_MONST_TALL = 243, // 28x72 monster graphic from the savegame sheet, resized to fit and centred in a 28x36 space
|
||||
PIC_PARTY_MONST_LG = 263, // 56x72 monster graphic from the savegame sheet, resized to fit in a 28x36 space
|
||||
PIC_TER = 1, ///< 28x36 terrain graphic from the preset sheets
|
||||
PIC_TER_ANIM = 2, ///< 28x36 terrain graphic from the preset animated terrain sheet
|
||||
PIC_MONST = 3, ///< 28x36 monster graphic from the preset sheets
|
||||
PIC_DLOG = 4, ///< 36x36 dialog graphic from the preset sheet
|
||||
PIC_TALK = 5, ///< 32x32 talking portrait from the preset sheet
|
||||
PIC_SCEN = 6, ///< 32x32 scenario graphic from the scenario sheet
|
||||
PIC_ITEM = 7, ///< 28x36 item graphic from the large item sheet,
|
||||
///< or 18x18 item graphic from the small sheet centred in a 28x36 space
|
||||
PIC_PC = 8, ///< 28x36 pc graphic from the player sheet
|
||||
PIC_FIELD = 9, ///< 28x36 field graphic from the fields sheet
|
||||
PIC_BOOM = 10, ///< 28x36 boom graphic from the booms sheet
|
||||
PIC_FULL = 11, ///< entire sheet graphic; number is the resource ID
|
||||
PIC_MISSILE = 12, ///< 18x18 missile graphic from the missiles sheet
|
||||
PIC_DLOG_LG = 13, ///< 72x72 dialog graphic from the dialog sheet
|
||||
PIC_SCEN_LG = 14, ///< 64x64 scenario graphic (currently each is on its own sheet)
|
||||
PIC_TER_MAP = 15, ///< 12x12 map graphic... or should it be 6x6?
|
||||
PIC_STATUS = 16, ///< 12x12 status icon
|
||||
PIC_MONST_WIDE = 23, ///< 56x36 monster graphic from the preset sheets, resized to fit and centred in a 28x36 space
|
||||
PIC_MONST_TALL = 43, ///< 28x72 monster graphic from the preset sheets, resized to fit and centred in a 28x36 space
|
||||
PIC_MONST_LG = 63, ///< 56x72 monster graphic from the preset sheets, resized to fit in a 28x36 space
|
||||
PIC_CUSTOM_TER = 101, ///< 28x36 custom terrain graphic from the custom sheets
|
||||
PIC_CUSTOM_TER_ANIM = 102, ///< 28x36 custom animated terrain graphic from the custom sheets
|
||||
PIC_CUSTOM_MONST = 103, ///< 28x36 custom monster graphic from the custom sheets
|
||||
PIC_CUSTOM_DLOG = 104, ///< 36x36 dialog graphic drawn from two 18x26 halves in the custom sheets
|
||||
PIC_CUSTOM_TALK = 105, ///< 32x32 talking portrait drawn from two 16x32 halves in the custom sheets
|
||||
PIC_CUSTOM_SCEN = 106, ///< 32x32 scenario portrait loading from scenname.exr/scenario.png
|
||||
PIC_CUSTOM_ITEM = 107, ///< 28x36 custom item graphic from the custom sheets
|
||||
PIC_CUSTOM_FULL = 111, ///< entire sheet graphic, drawn from scenname.exr/sheetxxx.png where xxx is the number
|
||||
PIC_CUSTOM_MISSILE = 112, ///< 18x18 missile graphic drawn from the the custom sheets
|
||||
PIC_CUSTOM_DLOG_LG = 113, ///< 72x72 dialog graphic from the custom sheet, taken from 8 successive slots
|
||||
PIC_CUSTOM_TER_MAP = 115, ///< 12x12 map graphic (should it be 6x6?) taken from the custom sheet
|
||||
PIC_CUSTOM_MONST_WIDE = 123,///< 56x36 monster graphic from the custom sheets, resized to fit and centred in a 28x36 space
|
||||
PIC_CUSTOM_MONST_TALL = 143,///< 28x72 monster graphic from the custom sheets, resized to fit and centred in a 28x36 space
|
||||
PIC_CUSTOM_MONST_LG = 163, ///< 56x72 monster graphic from the custom sheets, resized to fit in a 28x36 space
|
||||
PIC_PARTY_MONST = 203, ///< 28x36 monster graphic drawn from the savegame sheet
|
||||
PIC_PARTY_SCEN = 206, ///< 32x32 graphic drawn from the scenario headers sheet
|
||||
PIC_PARTY_ITEM = 207, ///< 28x36 item graphic drawn from the savegame sheet
|
||||
PIC_PARTY_PC = 208, ///< 28x36 PC graphic drawn from the savegame sheet
|
||||
PIC_PARTY_MONST_WIDE = 223, ///< 56x36 monster graphic from the savegame sheet, resized to fit and centred in a 28x36 space
|
||||
PIC_PARTY_MONST_TALL = 243, ///< 28x72 monster graphic from the savegame sheet, resized to fit and centred in a 28x36 space
|
||||
PIC_PARTY_MONST_LG = 263, ///< 56x72 monster graphic from the savegame sheet, resized to fit in a 28x36 space
|
||||
NUM_PIC_TYPES
|
||||
};
|
||||
|
||||
/// Flags that modify icon types.
|
||||
/// Can be added to or subtracted from ePicType enums, returning an ePicType.
|
||||
enum ePicTypeMod {
|
||||
// Can be added to or subtracted from ePicType enums, returning an ePicType.
|
||||
PIC_PRESET = 0, // just for good measure
|
||||
PIC_WIDE = 20, // if applied to any derivative of PIC_MONST, makes the x-dimension 2 instead of 1
|
||||
PIC_TALL = 40, // if applied to any derivative of PIC_MONST, makes the y-dimension 2 instead of 1
|
||||
PIC_LARGE = PIC_WIDE + PIC_TALL,
|
||||
PIC_CUSTOM = 100, // if applied to any customizable graphic, makes it custom instead of preset
|
||||
PIC_PARTY = 200, // similar to above
|
||||
PIC_PRESET = 0, ///< No mod, included just for good measure; can be added to cancel out all mods.
|
||||
PIC_WIDE = 20, ///< If applied to any derivative of PIC_MONST, makes the x-dimension 2 instead of 1.
|
||||
PIC_TALL = 40, ///< If applied to any derivative of PIC_MONST, makes the y-dimension 2 instead of 1.
|
||||
PIC_LARGE = PIC_WIDE + PIC_TALL, ///< A combination of PIC_WIDE and PIC_TALL.
|
||||
PIC_CUSTOM = 100, ///< If applied to any customizable graphic, makes it custom instead of preset.
|
||||
PIC_PARTY = 200, ///< If applies to any exportable graphic, makes it exported instead of preset.
|
||||
};
|
||||
|
||||
/// Specifies a graphics sheet that icons are drawn from.
|
||||
enum eSheetType {
|
||||
SHEET_TER,
|
||||
SHEET_TER_ANIM,
|
||||
SHEET_MONST,
|
||||
SHEET_DLOG,
|
||||
SHEET_TALK,
|
||||
SHEET_SCEN,
|
||||
SHEET_SCEN_LG,
|
||||
SHEET_ITEM,
|
||||
SHEET_TINY_ITEM,
|
||||
SHEET_PC,
|
||||
SHEET_FIELD,
|
||||
SHEET_BOOM,
|
||||
SHEET_MISSILE,
|
||||
SHEET_PARTY,
|
||||
SHEET_HEADER,
|
||||
SHEET_TER_MAP,
|
||||
SHEET_FULL,
|
||||
SHEET_STATUS,
|
||||
SHEET_CUSTOM,
|
||||
SHEET_TER, ///< The preset terrain sheets, terX.png
|
||||
SHEET_TER_ANIM, ///< The animated terrains sheet, teranim.png
|
||||
SHEET_MONST, ///< The preset monster sheets, monstX.png
|
||||
SHEET_DLOG, ///< The preset dialog icons sheet, dlogpics.png
|
||||
SHEET_TALK, ///< The preset talk icons sheet, talkportraits.png
|
||||
SHEET_SCEN, ///< The preset scenario icons sheet, scenpics.png
|
||||
SHEET_SCEN_LG, ///< The large scenario icons sheet, bigscenpics.png
|
||||
SHEET_ITEM, ///< The preset large items sheet, objects.png
|
||||
SHEET_TINY_ITEM,///< The small itesm sheet, tinyobj.png
|
||||
SHEET_PC, ///< The PC graphics sheet, pcs.png
|
||||
SHEET_FIELD, ///< The fields and objects sheet, fields.png
|
||||
SHEET_BOOM, ///< The special effects sheet, booms.png
|
||||
SHEET_MISSILE, ///< The missile animations sheet, missles.png
|
||||
SHEET_PARTY, ///< The exported graphics sheet stored in the saved game
|
||||
SHEET_HEADER, ///< The scenario header sheet
|
||||
SHEET_TER_MAP, ///< The terrain map icons sheet, termap.png
|
||||
SHEET_FULL, ///< Any full sheet
|
||||
SHEET_STATUS, ///< The status icons sheet, staticons.png
|
||||
SHEET_CUSTOM, ///< Any custom graphics sheet
|
||||
// TODO: Vehicle sheet is missing.
|
||||
// TODO: Documentation of full, custom, header, and exported sheets is still lacking.
|
||||
NUM_SHEET_TYPES
|
||||
};
|
||||
|
||||
/// A simple icon.
|
||||
/// This control can also be made clickable.
|
||||
class cPict : public cControl {
|
||||
public:
|
||||
/// @copydoc cDialog::init()
|
||||
static void init();
|
||||
void attachClickHandler(click_callback_t f) throw();
|
||||
void attachFocusHandler(focus_callback_t f) throw(xHandlerNotSupported);
|
||||
@@ -104,16 +115,40 @@ public:
|
||||
short getFormat(eFormat prop) throw(xUnsupportedProp);
|
||||
void setColour(sf::Color clr) throw(xUnsupportedProp);
|
||||
sf::Color getColour() throw(xUnsupportedProp);
|
||||
/// @copydoc setPict(pic_num_t)
|
||||
/// @param type The type of the new icon
|
||||
/// @note If you change to a type with a different bounding rect,
|
||||
/// you will need to separately update the bounding rect.
|
||||
/// (The bounding rect is mostly ignored when drawing, so if the icon is opaque, the control is not clickable,
|
||||
/// and there is no frame, you can usually safely skip this step.)
|
||||
void setPict(pic_num_t num, ePicType type);
|
||||
/// Set the pict's icon.
|
||||
/// @param num The new icon index.
|
||||
void setPict(pic_num_t num);
|
||||
/// Get the current icon.
|
||||
/// @return The number of the current icon.
|
||||
pic_num_t getPicNum();
|
||||
/// Get the current icon's type.
|
||||
/// @return The type of the current icon.
|
||||
ePicType getPicType();
|
||||
/// Create a new icon.
|
||||
/// @param parent The parent dialog.
|
||||
explicit cPict(cDialog& parent);
|
||||
/// Create a new icon without a parent dialog.
|
||||
/// @param parent The parent window.
|
||||
explicit cPict(sf::RenderWindow& parent);
|
||||
bool isClickable();
|
||||
/// Advance the current animation frame.
|
||||
/// Should be called at predictable intervals if the dialog might contain an animated graphic.
|
||||
static void advanceAnim();
|
||||
virtual ~cPict();
|
||||
void draw();
|
||||
/// A utility function to draw an icon into an arbitrary window.
|
||||
/// @param win The window to draw in.
|
||||
/// @param dest The bounding rect to draw in (ignored for drawing the actual, but used for background fill and framing)
|
||||
/// @param which_g The icon to draw.
|
||||
/// @param type_g The type of icon to draw.
|
||||
/// @param framed Whether to draw a frame around the icon.
|
||||
static void drawAt(sf::RenderWindow& win, RECT dest, pic_num_t which_g, ePicType type_g, bool framed);
|
||||
cPict& operator=(cPict& other) = delete;
|
||||
cPict(cPict& other) = delete;
|
||||
@@ -165,12 +200,43 @@ private:
|
||||
click_callback_t onClick;
|
||||
};
|
||||
|
||||
/// Apply a modifier to an icon type.
|
||||
/// @param lhs The base icon type to modify.
|
||||
/// @param rhs The modifier to apply.
|
||||
/// @return The modified icon type.
|
||||
/// @note As a special case, adding PIC_PRESET removes all modifiers.
|
||||
ePicType operator + (ePicType lhs, ePicTypeMod rhs);
|
||||
/// Remove a modifier from an icon type.
|
||||
/// @param lhs The base icon type to modify.
|
||||
/// @param rhs The modifier to remove.
|
||||
/// @return The modified icon type.
|
||||
ePicType operator - (ePicType lhs, ePicTypeMod rhs);
|
||||
/// Apply a modifier to an icon type.
|
||||
/// @param lhs The modifier to apply.
|
||||
/// @param rhs The base icon type to modify.
|
||||
/// @return The modified icon type.
|
||||
/// @note As a special case, adding PIC_PRESET removes all modifiers.
|
||||
ePicType operator + (ePicTypeMod lhs, ePicType rhs);
|
||||
/// Remove a modifier from an icon type.
|
||||
/// @param lhs The modifier to remove.
|
||||
/// @param rhs The base icon type to modify.
|
||||
/// @return The modified icon type.
|
||||
ePicType operator - (ePicTypeMod lhs, ePicType rhs);
|
||||
/// Apply a modifier to an icon type.
|
||||
/// @param lhs The base icon type to modify.
|
||||
/// @param rhs The modifier to apply.
|
||||
/// @return lhs, now modified.
|
||||
/// @note As a special case, adding PIC_PRESET removes all modifiers.
|
||||
ePicType&operator +=(ePicType&lhs, ePicTypeMod rhs);
|
||||
/// Remove a modifier from an icon type.
|
||||
/// @param lhs The base icon type to modify.
|
||||
/// @param rhs The modifier to remove.
|
||||
/// @return lhs, now modified.
|
||||
ePicType&operator -=(ePicType&lhs, ePicTypeMod rhs);
|
||||
/// Check if an icon type has a modifier applied.
|
||||
/// @param lhs The icon type to check.
|
||||
/// @param rhs The modifier type to test for.
|
||||
/// @return true if the modifier is present.
|
||||
bool operator& (ePicType lhs, ePicTypeMod rhs);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,8 +9,14 @@
|
||||
#ifndef BoE_scrollbar_h
|
||||
#define BoE_scrollbar_h
|
||||
|
||||
/// @file
|
||||
/// Scrollbar-related classes and types.
|
||||
|
||||
#include "control.h"
|
||||
|
||||
/// A simple vertical scrollbar.
|
||||
/// This has no coupling with scrollable data; that must be handled externally by
|
||||
/// using the methods to get the scrollbar's position.
|
||||
class cScrollbar : public cControl {
|
||||
int pos, max, pgsz;
|
||||
enum {
|
||||
@@ -23,8 +29,13 @@ class cScrollbar : public cControl {
|
||||
click_callback_t onClick;
|
||||
static sf::Texture scroll_gw;
|
||||
public:
|
||||
/// @copydoc cDialog::init()
|
||||
static void init();
|
||||
/// Create a new scrollbar without a parent dialog.
|
||||
/// @param parent The parent window.
|
||||
explicit cScrollbar(sf::RenderWindow& parent);
|
||||
/// Create a new scrollbar.
|
||||
/// @param parent The parent dialog.
|
||||
explicit cScrollbar(cDialog& parent);
|
||||
void attachClickHandler(click_callback_t f) throw(xHandlerNotSupported);
|
||||
void attachFocusHandler(focus_callback_t f) throw(xHandlerNotSupported);
|
||||
@@ -35,11 +46,29 @@ public:
|
||||
void setColour(sf::Color clr) throw(xUnsupportedProp);
|
||||
sf::Color getColour() throw(xUnsupportedProp);
|
||||
bool isClickable();
|
||||
/// Get the scrollbar thumb's current position.
|
||||
/// @return The current position.
|
||||
long getPosition();
|
||||
/// Get the scrollbar thumb's maximum value.
|
||||
/// @return The maximum value.
|
||||
long getMaximum();
|
||||
/// Get the scrollbar thumb's page size.
|
||||
/// @return The page size.
|
||||
///
|
||||
/// The page size is the number of steps scrolled when a click is received
|
||||
/// in the area between the arrow buttons and the scrollbar thumb.
|
||||
long getPageSize();
|
||||
/// Set the scrollbar thumb's current position.
|
||||
/// @param to The current position.
|
||||
void setPosition(long to);
|
||||
/// Set the scrollbar thumb's maximum value.
|
||||
/// @param to The maximum value.
|
||||
void setMaximum(long to);
|
||||
/// Set the scrollbar thumb's page size.
|
||||
/// @param to The page size.
|
||||
///
|
||||
/// The page size is the number of steps scrolled when a click is received
|
||||
/// in the area between the arrow buttons and the scrollbar thumb.
|
||||
void setPageSize(long to);
|
||||
void draw();
|
||||
cScrollbar& operator=(cScrollbar& other) = delete;
|
||||
|
||||
1
osx/doxy/.gitignore
vendored
Normal file
1
osx/doxy/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
html/
|
||||
2325
osx/doxy/Doxyfile
Normal file
2325
osx/doxy/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
290
osx/doxy/mainpage.md
Normal file
290
osx/doxy/mainpage.md
Normal file
@@ -0,0 +1,290 @@
|
||||
|
||||
Blades of Exile Documentation {#mainpage}
|
||||
=============================
|
||||
|
||||
This is the documentation for parts of the Blades of Exile source code.
|
||||
Currently it covers only the dialog engine.
|
||||
|
||||
Defining a Dialog
|
||||
=================
|
||||
|
||||
Creating a new dialog consists of two basic steps: first, you have to
|
||||
create the XML dialog definition, and then you need to write the code to
|
||||
set it up and implement all the required callbacks.
|
||||
|
||||
The format of the XML dialog files is defined by the schema in
|
||||
_rsrc/schemas/dialog.xsd_, but this document will cover what you need to
|
||||
know in a more readable manner. A dialog definition consists of a
|
||||
`<dialog>` tag containing any number of tags representing various dialog
|
||||
controls. Each tag will be documented in some detail below.
|
||||
|
||||
Common Attributes
|
||||
-----------------
|
||||
|
||||
The following attributes are allowed on all or most elements:
|
||||
|
||||
* `top`, `left`, `width`, `height` - Specifies the location and bounding
|
||||
rect of the control within the dialog. All non-container controls
|
||||
support these attributes, and in fact the `top` and `left` attributes
|
||||
are required. Some controls may ignore the `width` and `height`
|
||||
attributes.
|
||||
* `def-key`, `key-mod` - Specifies the default keyboard shortcut for the
|
||||
control. See **Keyboard Shortcuts** below for more information on the
|
||||
format of these attributes.
|
||||
* `font`, `size`, `color`, `colour` - Specifies text attributes of the
|
||||
control. See **Text Formatting** below for details on accepted values.
|
||||
* `name` - Give the control a unique identifier which you can use to
|
||||
refer to it from the code. If omitted, the code will generate a random
|
||||
identifier. All controls support this attribute.
|
||||
* `fromlist` - Currently unused, but the intended use is to look up the
|
||||
control's text value in a string list (in _rsrc/strings_)
|
||||
|
||||
The `<dialog>` tag
|
||||
------------------
|
||||
|
||||
The `<dialog>` tag accepts the following attributes:
|
||||
|
||||
* `skin` - Specify the dialog's background pattern. Currently only
|
||||
accepts `dark` or `light`. If omitted, a default is used which depends
|
||||
on whether the dialog is used in the game or the scenario editor. As
|
||||
such, this attribute should be omitted for most dialogs.
|
||||
* `debug` - This attribute is completely ignored by the game, but if set
|
||||
to `true`, the XSL stylesheet will draw the bounding rects of LEDs and
|
||||
other debug information.
|
||||
* `fore` - The default text colour. Generally this shouldn't be needed.
|
||||
* `defbtn` - The ID (`name` attribute) of the default button. This is an
|
||||
IDREF, so it must exist in the dialog.
|
||||
|
||||
The `<text>` tag
|
||||
----------------
|
||||
|
||||
The `<text>` tag can be used either for a non-editable text message or
|
||||
for a frame to group elements. Within a `<text>` tag, you can use a
|
||||
`<br>` tag to insert a line break. See **Whitespace** for an explanation
|
||||
of the intended whitespace collapsing behaviour.
|
||||
|
||||
The `<text>` tag accepts the following attributes:
|
||||
|
||||
* `framed` - Specifies whether a frame is drawn around the text. Can be
|
||||
either `true` or `false`; defaults to `false`.
|
||||
* `clickable` - Specifies that the text is clickable. This attribute is
|
||||
useless, as clickability is determined solely by having a click handler
|
||||
set in the code.
|
||||
* `fromlist`, `font`, `size`, `color`, `colour`, `def-key`, `key-mod` -
|
||||
See **Common Attributes** above.
|
||||
|
||||
The `<button>` tag
|
||||
------------------
|
||||
|
||||
The `<button>` tag decribes a non-LED button. It can contain label text
|
||||
as well as an optional empty `<key>` element. It does not support the
|
||||
`<br>` tag. The `<key>` element was intended as a way of inserting a
|
||||
readable form of the button's keyboard shortcut, but at present this is
|
||||
unimplemented.
|
||||
|
||||
The `<button>` tag accepts the following attributes:
|
||||
|
||||
* `name` - This attribute is required on the `<button>` tag. See
|
||||
**Common Attributes** above.
|
||||
* `type` - Specifies the type of button. This attribute is required.
|
||||
* `wrap` - Specifies whether to wrap the text on the button. Can be
|
||||
either `true` or `false`; defaults to `false`.
|
||||
* `fromlist`, `def-key`, `key-mod` - See **Common Attributes** above.
|
||||
|
||||
The possible values for the `type` attribute are:
|
||||
|
||||
* `small` - A small 23x23 button.
|
||||
* `regular` - A normal-sized 63x23 button.
|
||||
* `large` - A large 102x23 button.
|
||||
* `help` - A small 16x13 help button - a white bubble with a ? mark.
|
||||
* `left` - A normal-sized 63x23 button with a left-pointing arrow.
|
||||
* `right` - A normal-sized 63x23 button with a right-pointing arrow.
|
||||
* `up` - A normal-sized 63x23 button with an up-pointing arrow.
|
||||
* `down` - A normal-sized 63x23 button with a down-pointing arrow.
|
||||
* `tiny` - A tiny 14x10 button, same size as an LED.
|
||||
* `done` - A normal-sized 63x23 button with "Done" on it.
|
||||
* `tall` - A tall 63x40 button.
|
||||
* `trait` - A tall 63x40 button with "Race Good/Bad Traits" on it.
|
||||
* `push` - A round red 30x30 push button.
|
||||
|
||||
(Naturally, they correspond perfectly with the values of the eBtnType
|
||||
enumeration.)
|
||||
|
||||
The `<led>` tag
|
||||
---------------
|
||||
|
||||
The `<led>` tag descripts an LED button. It can contain label text,
|
||||
which is drawn to the right of the button graphic. This differs from
|
||||
normal practice in the original Blades of Exile dialog engine, where LED
|
||||
labels were typically left-aligned to the _left_ of their associated
|
||||
LED. I've chosen to make this change because I feel it is easier to see
|
||||
which LED a label is associated to, and because the behaviour is more
|
||||
similar to the checkboxes and radio buttons found in normal GUIs.
|
||||
|
||||
The `<led>` tag accepts the following attributes:
|
||||
|
||||
* `name` - This attribute is required on the `<led>` tag. See **Common
|
||||
Attributes** above.
|
||||
* `state` - Specifies the starting state of the LED. Can be one of
|
||||
`red`, `green`, or `off`; defaults to `off`.
|
||||
* `font`, `size`, `color`, `colour` - See **Common Attributes** above.
|
||||
|
||||
The `<group>` tag
|
||||
-----------------
|
||||
|
||||
The `<group>` tag defines an LED group, a collection of LEDs that behave
|
||||
like radio buttons rather than checkboxes. The tag can contain any
|
||||
number of `<led>` elements.
|
||||
|
||||
The `<group>` tag accepts the following attributes:
|
||||
|
||||
* `fromlist` - See **Common Attributes** above. I don't remember exactly
|
||||
how this would have applied to an LED group though; perhaps it would use
|
||||
the string list to assign labels to its component LEDs in order of
|
||||
declaration?
|
||||
|
||||
The `<pict>` tag
|
||||
----------------
|
||||
|
||||
The `<pict>` tag defines a dialog picture. This covers a wide range of
|
||||
things, from large pictures to small icons.
|
||||
|
||||
The `<pict>` tag accepts the following attributes:
|
||||
|
||||
* `type` - Specifies the type of graphic. This attribute is required.
|
||||
* `num` - Specifies the graphic number. This attribute is required.
|
||||
* `clickable` - Specifies that the picture is clickable. This attribute
|
||||
is useless, as clickability is determined solely by having a click
|
||||
handler set in the code.
|
||||
* `custom` - Specifies whether the picture is custom or preset. Can be
|
||||
either `true` or `false`; defaults to `false`.
|
||||
* `framed` - Specifies whether a frame is drawn around the picture. Can
|
||||
be either `true` or `false`; defaults to `true`.
|
||||
* `size` - For certain types of graphics, this provides an additional
|
||||
hint. Can be one of `small`, `wide`, `tall`, or `large`.
|
||||
* `def-key`, `key-mod` - See **Common Attributes** above.
|
||||
|
||||
The possible values for the `type` attribute are:
|
||||
|
||||
* `blank` - Draw no graphic, just fill the bounding rect with black.
|
||||
* `ter` - A terrain graphic.
|
||||
* `teranim` - An animated terrain graphic.
|
||||
* `monst` - A monster graphic. The `size` attribute can be set to any of
|
||||
its four accepted values to indicate the size of the monster.
|
||||
* `dlog` - A dialog graphic. The `size` attribute can be `small` (the
|
||||
default) or `large`.
|
||||
* `talk` - A conversation graphic.
|
||||
* `scen` - A scenario icon. The `size` attribute can be `small` (the
|
||||
default) or `large`.
|
||||
* `item` - An item graphic.
|
||||
* `pc` - A PC graphic.
|
||||
* `field` - A field graphic.
|
||||
* `boom` - A boom graphic.
|
||||
* `missile` - A missile graphic.
|
||||
* `map` - A map graphic.
|
||||
* `status` - A status icon.
|
||||
* `full` - A full sheet. With this value and with `custom` left at
|
||||
`false`, the `num` parameter must be one of the following:
|
||||
* 1100 - The inventory help frame.
|
||||
* 1200 - The stats area help frame.
|
||||
* 1300 - The action points help fram.
|
||||
* 1400 - The outdoor toolbar help frame.
|
||||
* 1401 - The combat toolbar help frame.
|
||||
* 1402 - The town toolbar help frame.
|
||||
* 1500 - The stat icons help frame.
|
||||
|
||||
The `<field>` tag
|
||||
-----------------
|
||||
|
||||
The `<field>` tag defines an editable text field. It can contain default
|
||||
text as its contents, but does not support the `<br>` tag.
|
||||
|
||||
The `<field>` tag accepts the following attributes:
|
||||
|
||||
* `type` - Specifies the input type of the field. Can be one of `text`,
|
||||
`int`, `uint`, or `real`; defaults to `text`.
|
||||
* `tab-order` - Specifies the tab order of the field. This must be an
|
||||
integer that is unique in the dialog.
|
||||
|
||||
The `<stack>` tag
|
||||
-----------------
|
||||
|
||||
The `<stack>` tag is currently unimplemented. Trying to load a dialog
|
||||
that contains it will crash the game.
|
||||
|
||||
Keyboard Shortcuts
|
||||
------------------
|
||||
|
||||
Keyboard shortcuts are specified with a pair of attributes.
|
||||
|
||||
The `def-key` attribute specifies the main key that triggers the
|
||||
control. It can take any of the following values:
|
||||
|
||||
* A single digit
|
||||
* A lowercase letter
|
||||
* One of the following special characters:
|
||||
|
||||
` - = [ ] \ ; ' , . /
|
||||
* `left` - The left arrow key
|
||||
* `right` - The right arrow key
|
||||
* `up` - The up arrow key
|
||||
* `down` - The down arrow key
|
||||
* `esc` - The escape key
|
||||
* `enter` - The enter key.
|
||||
* `return` - The enter key. (Note: Theoretically, `enter` should be
|
||||
numpad enter while this is normal enter; I don't think this distinction
|
||||
is implemented though.)
|
||||
* `tab` - The tab key.
|
||||
* `help` - The help key (on keyboards that have one) or the F1 key.
|
||||
* `space` - The space key.
|
||||
* `none` - No key shortcut (the default).
|
||||
|
||||
The `key-mod` attribute contains a space-separated list of any of the
|
||||
following values:
|
||||
|
||||
* `ctrl` - The primary accelerator key (either control or command).
|
||||
* `shift` - The shift key
|
||||
* `alt` - The alt or option key
|
||||
|
||||
Text Formatting
|
||||
---------------
|
||||
|
||||
Text formatting options in dialogs are actually quite limited. There are
|
||||
only three possible attributes, with a very limited number of possible
|
||||
values.
|
||||
|
||||
* `font` - This attribute can take one of the following values: `plain`,
|
||||
`bold`, `dungeon`, `maidenword`. It defaults to `bold`. The latter two
|
||||
options are fantasy-style scripts such as that used for the conversation
|
||||
screen.
|
||||
* `size` - Although the dialog engine supports any font size, the XML
|
||||
specification simplifies it to three keywords: `small`, `large`, and
|
||||
`title`, representing 10pt, 12pt, and 18pt font, respectively.
|
||||
* `color` or `colour` - This is the only truly unrestricted attribute,
|
||||
accepting any HTML colour code. It understands three-digit hex codes (eg
|
||||
`#333`, which is equivalent to `#333333`), six-digit hex codes, and the
|
||||
sixteen standard HTML colour names. Both the British and American
|
||||
spelling are supported for the attribute name.
|
||||
|
||||
Whitespace
|
||||
----------
|
||||
|
||||
Whitespace collapse rules within Dialog XML elements are a little weird.
|
||||
All tabs are stripped out, and then runs of newlines are replaced with a
|
||||
single space, but runs of spaces are left as-is.
|
||||
|
||||
Note: Currently, the runs of newlines are simply removed rather than
|
||||
replaced with a space. This needs to be fixed.
|
||||
|
||||
Implementing a Dialog
|
||||
=====================
|
||||
|
||||
Once the dialog is defined, it needs to be implemented! This consists of
|
||||
a few steps - construct the dialog, attach handlers, possibly populate
|
||||
the dialog's fields and other dynamic elements according to whatever the
|
||||
dialog is supposed to display, and then run the dialog.
|
||||
|
||||
Use of `std::bind` for attaching the handlers is encouraged, and can be
|
||||
used in conjunction with `std::ref` to provide state for the dialog.
|
||||
Lambda expressions may also be useful for some of the simpler handlers.
|
||||
Use of `dynamic_cast` will be required when dealing with LEDs or icons.
|
||||
Reference in New Issue
Block a user