1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
/*
This file is part of Warzone 2100.
Copyright (C) 1999-2004 Eidos Interactive
Copyright (C) 2005-2020 Warzone 2100 Project
Warzone 2100 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Warzone 2100 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Warzone 2100; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/** @file
* Definitions for edit box functions.
*/
#ifndef __INCLUDED_LIB_WIDGET_BUTTON_H__
#define __INCLUDED_LIB_WIDGET_BUTTON_H__
#include "lib/ivis_opengl/ivisdef.h"
#include "widget.h"
#include "widgbase.h"
#include <map>
#include <functional>
#include <string>
class W_BUTTON : public WIDGET
{
public:
struct Images
{
Images() {}
Images(AtlasImage normal, AtlasImage down, AtlasImage highlighted, AtlasImage disabled = AtlasImage()) : normal(normal), down(down), highlighted(highlighted), disabled(disabled) {}
AtlasImage normal; ///< The image for the button.
AtlasImage down; ///< The image for the button, when down. Is overlaid over image.
AtlasImage highlighted; ///< The image for the button, when highlighted. Is overlaid over image.
AtlasImage disabled; ///< The image for the button, when disabled. Is overlaid over image.
};
public:
W_BUTTON(W_BUTINIT const *init);
W_BUTTON();
void clicked(W_CONTEXT *psContext, WIDGET_KEY key) override;
virtual bool clickHeld(W_CONTEXT *psContext, WIDGET_KEY key);
void released(W_CONTEXT *psContext, WIDGET_KEY key) override;
void highlight(W_CONTEXT *psContext) override;
void highlightLost() override;
void run(W_CONTEXT *psContext) override;
void display(int xOffset, int yOffset) override;
void displayRecursive(WidgetGraphicsContext const &context) override; // for handling progress border overlay
unsigned getState() const override;
void setState(unsigned state) override;
void setFlash(bool enable) override;
WzString getString() const override;
void setString(WzString string) override;
void setTip(std::string string) override;
void setHelp(optional<WidgetHelp> help) override;
void unlock();
void setImages(Images const &images);
void setImages(AtlasImage image, AtlasImage imageDown, AtlasImage imageHighlight, AtlasImage imageDisabled = AtlasImage());
using WIDGET::setString;
using WIDGET::setTip;
std::string getTip() override
{
return pTip;
}
WidgetHelp const * getHelp() const override
{
if (!help.has_value()) { return nullptr; }
return &(help.value());
}
/* The optional "onClick" callback function */
typedef std::function<void (W_BUTTON& button)> W_BUTTON_ONCLICK_FUNC;
void addOnClickHandler(const W_BUTTON_ONCLICK_FUNC& onClickFunc);
struct ProgressBorder
{
public:
struct BorderInset
{
BorderInset() { }
BorderInset(int left, int top, int right, int bottom)
: left(left), top(top), right(right), bottom(bottom)
{ }
int left = 0;
int top = 0;
int right = 0;
int bottom = 0;
};
private:
ProgressBorder(UDWORD interval, optional<float> factor, bool repeated, BorderInset inset = BorderInset()): m_inset(inset), m_interval(interval), m_factor(factor), m_repeated(repeated) { resetStartingTime(); }
public:
// Create an indeterminate ProgressBorder
static ProgressBorder indeterminate(BorderInset inset = BorderInset()) { return ProgressBorder(0, nullopt, true, inset); }
// Create a timed ProgressBorder which proceeds from 0 to 100% over the interval
static ProgressBorder timed(UDWORD interval, bool repeated = false, BorderInset inset = BorderInset()) { return ProgressBorder(interval, nullopt, repeated, inset); }
// Create a fixed factor ProgressBorder, where `factor` is expected to be a float from 0.0 to 1.0 (which corresponds to the percentage progress)
static ProgressBorder fixedFactor(float factor, BorderInset inset = BorderInset()) { return ProgressBorder(0, factor, false, inset); }
public:
void setInset(const BorderInset& newInset) { m_inset = newInset; }
void resetStartingTime();
const BorderInset& inset() const { return m_inset; }
UDWORD interval() const { return m_interval; }
UDWORD startingTime() const { return m_startingTime; }
optional<float> factor() const { return m_factor; }
bool repeated() const { return m_repeated; }
bool isIndeterminate() const { return !m_factor.has_value() && m_interval == 0; }
private:
BorderInset m_inset;
UDWORD m_interval = 0;
UDWORD m_startingTime = 0;
optional<float> m_factor = 0.0f;
bool m_repeated = false;
};
// Set the current ProgressBorder on the button, optionally specifying a color
// To disable a ProgressBorder, use `setProgressBorder(nullopt)`
void setProgressBorder(optional<ProgressBorder> progressBorder, optional<PIELIGHT> borderColour = nullopt);
// May be called from within W_BUTTON_ONCLICK_FUNC (onclick handler) to retrieve the button pressed
WIDGET_KEY getOnClickButtonPressed() const;
public:
bool isHighlighted() const;
private:
void drawProgressBorder(int xOffset, int yOffset);
public:
unsigned state; // The current button state
WzString pText; // The text for the button
Images images; ///< The images for the button.
std::string pTip; // The tool tip for the button
SWORD HilightAudioID; // Audio ID for form clicked sound
SWORD ClickedAudioID; // Audio ID for form hilighted sound
WIDGET_AUDIOCALLBACK AudioCallback; // Pointer to audio callback function
iV_fonts FontID;
UDWORD minClickInterval = 0;
private:
UDWORD lastClickTime = 0;
std::vector<W_BUTTON_ONCLICK_FUNC> onClickHandlers;
optional<ProgressBorder> progressBorder;
PIELIGHT progressBorderColour;
WIDGET_KEY lastClickButton = WKEY_NONE;
optional<WidgetHelp> help;
optional<std::chrono::steady_clock::time_point> clickDownStart; // the start time of click down on this button
optional<WIDGET_KEY> clickDownKey;
};
class MultipleChoiceButton : public W_BUTTON
{
public:
MultipleChoiceButton() : W_BUTTON(), choice(0) {}
void setChoice(unsigned newChoice);
void setTip(unsigned stateValue, std::string const &string);
void setTip(unsigned stateValue, char const *stringUtf8);
void setImages(unsigned stateValue, Images const &stateImages);
unsigned getChoice()
{
return choice;
}
using WIDGET::setTip;
private:
unsigned choice;
std::map<int, std::string> tips;
std::map<int, Images> imageSets;
};
std::shared_ptr<W_BUTTON> makeFormTransparentCornerButton(const char* text, int buttonPadding /* = TAB_BUTTONS_PADDING */, PIELIGHT buttonBackgroundFill /* = WZCOL_DEBUG_FILL_COLOR */);
struct PopoverMenuButtonDisplayCache
{
WzText text;
};
void PopoverMenuButtonDisplayFunc(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset);
#endif // __INCLUDED_LIB_WIDGET_BUTTON_H__
|