Commit 7cda5e66 authored by twanvl's avatar twanvl

make pack type labels clickable (based on HoverButton).

use set_help_text instead of the previous thing in SetWindow.
parent 18151ddf
......@@ -60,63 +60,47 @@ BEGIN_EVENT_TABLE(AboutWindow, wxDialog)
END_EVENT_TABLE ()
// ----------------------------------------------------------------------------- : Button with image and hover effect
// ----------------------------------------------------------------------------- : Button hover effect
HoverButton::HoverButton(Window* parent, int id, const String& name, const Color& background, bool accepts_focus)
HoverButtonBase::HoverButtonBase(Window* parent, int id, bool accepts_focus)
: wxControl(parent, id, wxDefaultPosition, wxDefaultSize, wxNO_BORDER )
, hover(false), focus(false), mouse_down(false), key_down(false)
, background(background)
, accepts_focus(accepts_focus)
, last_drawn(nullptr)
{
loadBitmaps(name);
SetSize(DoGetBestSize());
}
{}
void HoverButton::loadBitmaps(const String& name) {
if (bitmaps == name) return;
bitmaps = name;
bg_normal = Bitmap(load_resource_image(name + _("_normal")));
bg_hover = Bitmap(load_resource_image(name + _("_hover")));
bg_focus = Bitmap(load_resource_image(name + _("_focus")));
bg_down = Bitmap(load_resource_image(name + _("_down")));
Refresh(false);
}
void HoverButton::onMouseEnter(wxMouseEvent&) {
void HoverButtonBase::onMouseEnter(wxMouseEvent&) {
hover = true;
refreshIfNeeded();
if (!help_text.empty()) set_status_text(this,help_text);
}
void HoverButton::onMouseLeave(wxMouseEvent&) {
void HoverButtonBase::onMouseLeave(wxMouseEvent&) {
hover = false;
refreshIfNeeded();
if (!help_text.empty()) set_status_text(this,wxEmptyString);
}
void HoverButton::onFocus(wxFocusEvent&) {
void HoverButtonBase::onFocus(wxFocusEvent&) {
focus = true;
refreshIfNeeded();
}
void HoverButton::onKillFocus(wxFocusEvent&) {
void HoverButtonBase::onKillFocus(wxFocusEvent&) {
focus = false;
refreshIfNeeded();
}
void HoverButton::onLeftDown(wxMouseEvent&) {
void HoverButtonBase::onLeftDown(wxMouseEvent&) {
mouse_down = true;
SetFocus();
CaptureMouse();
refreshIfNeeded();
}
void HoverButton::onLeftUp(wxMouseEvent&) {
void HoverButtonBase::onLeftUp(wxMouseEvent&) {
if (HasCapture()) ReleaseMouse();
if (mouse_down && hover) {
mouse_down = false;
refreshIfNeeded();
wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
ProcessEvent(evt);
}
mouse_down = false;
refreshIfNeeded();
if (hover) {
onClick();
}
}
void HoverButton::onKeyDown(wxKeyEvent& ev) {
void HoverButtonBase::onKeyDown(wxKeyEvent& ev) {
int code = ev.GetKeyCode();
if (code == WXK_RETURN || code == WXK_SPACE) {
key_down = true;
......@@ -125,23 +109,72 @@ void HoverButton::onKeyDown(wxKeyEvent& ev) {
ev.Skip();
}
}
void HoverButton::onKeyUp(wxKeyEvent& ev) {
void HoverButtonBase::onKeyUp(wxKeyEvent& ev) {
int code = ev.GetKeyCode();
if (code == WXK_RETURN || code == WXK_SPACE) {
key_down = false;
refreshIfNeeded();
wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
ProcessEvent(evt);
onClick();
}
}
wxSize HoverButton::DoGetBestSize() const {
return wxSize(bg_normal.GetWidth(), bg_normal.GetHeight());
void HoverButtonBase::onClick() {
wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
evt.SetEventObject(this);
ProcessEvent(evt);
}
bool HoverButton::AcceptsFocus() const {
bool HoverButtonBase::AcceptsFocus() const {
return wxControl::AcceptsFocus() && accepts_focus;
}
void HoverButtonBase::refreshIfNeeded() {
Refresh(false);
}
void HoverButtonBase::onPaint(wxPaintEvent&) {
wxPaintDC dc(this);
draw(dc);
}
BEGIN_EVENT_TABLE(HoverButtonBase, wxControl)
EVT_ENTER_WINDOW (HoverButtonBase::onMouseEnter)
EVT_LEAVE_WINDOW (HoverButtonBase::onMouseLeave)
EVT_PAINT (HoverButtonBase::onPaint)
EVT_SET_FOCUS (HoverButtonBase::onFocus)
EVT_KILL_FOCUS (HoverButtonBase::onKillFocus)
EVT_LEFT_DOWN (HoverButtonBase::onLeftDown)
EVT_LEFT_UP (HoverButtonBase::onLeftUp)
EVT_KEY_DOWN (HoverButtonBase::onKeyDown)
EVT_KEY_UP (HoverButtonBase::onKeyUp)
END_EVENT_TABLE ()
// ----------------------------------------------------------------------------- : Button with image and hover effect
HoverButton::HoverButton(Window* parent, int id, const String& name, const Color& background, bool accepts_focus)
: HoverButtonBase(parent, id, accepts_focus)
, background(background)
, last_drawn(nullptr)
{
loadBitmaps(name);
SetSize(DoGetBestSize());
}
void HoverButton::loadBitmaps(const String& name) {
if (bitmaps == name) return;
bitmaps = name;
bg_normal = Bitmap(load_resource_image(name + _("_normal")));
bg_hover = Bitmap(load_resource_image(name + _("_hover")));
bg_focus = Bitmap(load_resource_image(name + _("_focus")));
bg_down = Bitmap(load_resource_image(name + _("_down")));
Refresh(false);
}
wxSize HoverButton::DoGetBestSize() const {
return wxSize(bg_normal.GetWidth(), bg_normal.GetHeight());
}
const Bitmap* HoverButton::toDraw() const {
return (mouse_down && hover) || key_down ? &bg_down
: hover ? &bg_hover
......@@ -152,10 +185,6 @@ void HoverButton::refreshIfNeeded() {
if (last_drawn != toDraw()) Refresh(false);
}
void HoverButton::onPaint(wxPaintEvent&) {
wxPaintDC dc(this);
draw(dc);
}
void HoverButton::draw(DC& dc) {
// clear background (for transparent button images)
wxSize ws = GetClientSize();
......@@ -169,15 +198,3 @@ void HoverButton::draw(DC& dc) {
int HoverButton::drawDelta() const {
return (mouse_down && hover) || key_down ? 2 : 0;
}
BEGIN_EVENT_TABLE(HoverButton, wxControl)
EVT_ENTER_WINDOW (HoverButton::onMouseEnter)
EVT_LEAVE_WINDOW (HoverButton::onMouseLeave)
EVT_PAINT (HoverButton::onPaint)
EVT_SET_FOCUS (HoverButton::onFocus)
EVT_KILL_FOCUS (HoverButton::onKillFocus)
EVT_LEFT_DOWN (HoverButton::onLeftDown)
EVT_LEFT_UP (HoverButton::onLeftUp)
EVT_KEY_DOWN (HoverButton::onKeyDown)
EVT_KEY_UP (HoverButton::onKeyUp)
END_EVENT_TABLE ()
......@@ -28,49 +28,68 @@ class AboutWindow : public wxDialog {
void draw(DC& dc);
};
// ----------------------------------------------------------------------------- : Button with image and hover effect
// ----------------------------------------------------------------------------- : Button with hover effect
/// A button that changes images on mouseenter/leave
class HoverButton : public wxControl {
class HoverButtonBase : public wxControl {
public:
/// Create a HoverButton, name is the resource name of the images to use
/** name+"_normal", name+"_hover", name+"_focus", name+"_down"
* are the resource names of the images used.
*/
HoverButton(Window* parent, int id, const String& name, const Color& background = Color(240,247,255), bool accepts_focus = true);
/// Load different bitmaps for this button
void loadBitmaps(const String& name);
HoverButtonBase(Window* parent, int id, bool accepts_focus = true);
virtual bool AcceptsFocus() const;
virtual void SetHelpText(const String& s) { help_text = s; }
private:
DECLARE_EVENT_TABLE();
String bitmaps; ///< Name of the loaded bitmaps
Bitmap bg_normal, bg_hover, bg_focus, bg_down; ///< Bitmaps for the states of the button
bool hover, focus, mouse_down, key_down;
Color background;
const bool accepts_focus;
void onMouseEnter(wxMouseEvent&);
void onMouseLeave(wxMouseEvent&);
void onFocus (wxFocusEvent& ev);
void onKillFocus (wxFocusEvent& ev);
void onPaint (wxPaintEvent&);
void onLeftUp (wxMouseEvent&);
void onLeftDown (wxMouseEvent&);
void onKeyDown (wxKeyEvent&);
void onKeyUp (wxKeyEvent&);
void onPaint (wxPaintEvent&);
protected:
bool hover, focus, mouse_down, key_down;
String help_text;
virtual void draw(DC& dc) = 0;
virtual void refreshIfNeeded();
virtual void onClick();
};
// ----------------------------------------------------------------------------- : Button with image and hover effect
/// A button that changes images on mouseenter/leave
class HoverButton : public HoverButtonBase {
public:
/// Create a HoverButton, name is the resource name of the images to use
/** name+"_normal", name+"_hover", name+"_focus", name+"_down"
* are the resource names of the images used.
*/
HoverButton(Window* parent, int id, const String& name, const Color& background = Color(240,247,255), bool accepts_focus = true);
/// Load different bitmaps for this button
void loadBitmaps(const String& name);
private:
String bitmaps; ///< Name of the loaded bitmaps
Bitmap bg_normal, bg_hover, bg_focus, bg_down; ///< Bitmaps for the states of the button
Color background;
virtual wxSize DoGetBestSize() const;
const Bitmap* last_drawn;
const Bitmap* toDraw() const;
void refreshIfNeeded();
protected:
virtual void draw(DC& dc);
int drawDelta() const;
virtual void refreshIfNeeded();
virtual void draw(DC& dc);
};
......
......@@ -8,7 +8,6 @@
#include <util/prec.hpp>
#include <gui/set/cards_panel.hpp>
#include <gui/set/window.hpp>
#include <gui/control/image_card_list.hpp>
#include <gui/control/card_editor.hpp>
#include <gui/control/text_ctrl.hpp>
......@@ -274,7 +273,7 @@ void CardsPanel::onUpdateUI(wxUpdateUIEvent& ev) {
case ID_COLLAPSE_NOTES: {
bool collapse = notes->GetSize().y > 0;
collapse_notes->loadBitmaps(collapse ? _("btn_collapse") : _("btn_expand"));
static_cast<SetWindow*>(GetParent())->setControlStatusText(collapse_notes, collapse ? _HELP_("collapse notes") : _HELP_("expand notes"));
collapse_notes->SetHelpText(collapse ? _HELP_("collapse notes") : _HELP_("expand notes"));
break;
}
case ID_INSERT_SYMBOL: {
......
......@@ -8,9 +8,10 @@
#include <util/prec.hpp>
#include <gui/set/random_pack_panel.hpp>
#include <gui/set/window.hpp>
#include <gui/control/card_viewer.hpp>
#include <gui/control/filtered_card_list.hpp>
#include <gui/util.hpp>
#include <gui/about_window.hpp> // HoverButtonBase
#include <data/game.hpp>
#include <data/pack.hpp>
#include <data/settings.hpp>
......@@ -210,15 +211,77 @@ BEGIN_EVENT_TABLE(PackTotalsPanel, wxPanel)
EVT_PAINT(PackTotalsPanel::onPaint)
END_EVENT_TABLE()
// ----------------------------------------------------------------------------- : SelectableLabel
class SelectableLabel : public HoverButtonBase {
public:
SelectableLabel(wxWindow* parent, int id, const String& label, bool interactive = true)
: HoverButtonBase(parent, id, false)
, label(label)
, interactive(interactive)
, buddy(nullptr)
{}
void draw(DC& dc) {
Color bg = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
Color fg = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT);
// clear background
dc.SetPen(*wxTRANSPARENT_PEN);
//dc.SetBrush(mouse_down ? wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT)
// : hover ? lerp(bg,fg,0.1) : bg);
//dc.SetTextForeground(mouse_down ? wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) : fg);
dc.SetBrush(interactive && hover ? lerp(bg,fg,0.1) : bg);
dc.SetTextForeground(fg);
wxSize size = dc.GetSize();
dc.DrawRectangle(0,0,size.x,size.y);
// draw label
dc.SetFont(*wxNORMAL_FONT);
int w,h;
wxSize s = dc.GetSize();
dc.GetTextExtent(label,&w,&h);
dc.DrawText(interactive && hover ? label + _("...") : label, 2, (s.y-h)/2);
}
wxSize DoGetBestSize() const {
int w,h;
wxClientDC dc(const_cast<SelectableLabel*>(this));
dc.SetFont(*wxNORMAL_FONT);
dc.GetTextExtent(label,&w,&h);
return wxSize(w+6,h);
}
void setBuddy(wxWindow* buddy) {
this->buddy = buddy;
}
virtual void onClick() {
if (buddy) buddy->SetFocus();
}
void onDoubleClick(wxMouseEvent&) {
if (interactive) HoverButtonBase::onClick();
}
private:
String label;
bool interactive;
wxWindow* buddy;
DECLARE_EVENT_TABLE();
};
BEGIN_EVENT_TABLE(SelectableLabel, HoverButtonBase)
EVT_LEFT_DCLICK(SelectableLabel::onDoubleClick)
END_EVENT_TABLE()
// ----------------------------------------------------------------------------- : PackAmountPicker
PackAmountPicker::PackAmountPicker(wxWindow* parent, wxFlexGridSizer* sizer, const PackTypeP& pack)
PackAmountPicker::PackAmountPicker(wxWindow* parent, wxFlexGridSizer* sizer, const PackTypeP& pack, bool active)
: pack(pack)
, label(new wxStaticText(parent, wxID_ANY, capitalize_sentence(pack->name)))
, label(new SelectableLabel(parent, ID_PACK_TYPE, capitalize_sentence(pack->name), active))
, value(new wxSpinCtrl(parent, ID_PACK_AMOUNT, _("0"), wxDefaultPosition, wxSize(50,-1)))
{
sizer->Add(label, 0, wxALIGN_CENTER_VERTICAL);
label->setBuddy(value);
sizer->Add(label, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL);
sizer->Add(value, 0, wxEXPAND | wxALIGN_CENTER);
if (active) {
label->SetHelpText(_("Double click to edit."));
}
set_help_text(value, _("The number of ") + pack->name + _("s to use."));
}
void PackAmountPicker::destroy(wxFlexGridSizer* sizer) {
......@@ -265,9 +328,10 @@ CustomPackDialog::CustomPackDialog(Window* parent, const SetP& set, const PackTy
s->Add(s2, 0, wxEXPAND | wxALL, 8);
wxSizer* s3 = new wxBoxSizer(wxHORIZONTAL);
wxSizer* s4 = new wxStaticBoxSizer(wxHORIZONTAL, this, _LABEL_("pack selection"));
wxFlexGridSizer* packsSizer = new wxFlexGridSizer(0, 2, 4, 8);
s4->AddSpacer(2);
wxFlexGridSizer* packsSizer = new wxFlexGridSizer(0, 2, 4, 4);
packsSizer->AddGrowableCol(0);
s4->Add(packsSizer, 1, wxEXPAND | wxALL & ~wxTOP, 4);
s4->Add(packsSizer, 1, wxEXPAND | wxALL & ~wxTOP & ~wxLEFT, 4);
s3->Add(s4, 1, wxEXPAND, 8);
wxSizer* s5 = new wxStaticBoxSizer(wxHORIZONTAL, this, _LABEL_("pack totals"));
s5->Add(totals, 1, wxEXPAND | wxALL, 4);
......@@ -277,7 +341,7 @@ CustomPackDialog::CustomPackDialog(Window* parent, const SetP& set, const PackTy
// add spin controls
FOR_EACH(pack, set->game->pack_types) {
if (pack->selectable) continue; // this pack is already selectable from the main UI
PackAmountPicker pick(this, packsSizer, pack);
PackAmountPicker pick(this, packsSizer, pack, false);
pickers.push_back(pick);
// set value if it is nonzero
if (edited_pack) {
......@@ -358,19 +422,21 @@ void RandomPackPanel::initControls() {
#else
totals = new PackTotalsPanel(this, wxID_ANY);
#endif
static_cast<SetWindow*>(GetParent())->setControlStatusText(seed_random, _HELP_("random seed"));
static_cast<SetWindow*>(GetParent())->setControlStatusText(seed_fixed, _HELP_("fixed seed"));
static_cast<SetWindow*>(GetParent())->setControlStatusText(seed, _HELP_("seed"));
set_help_text(seed_random, _HELP_("random seed"));
set_help_text(seed_fixed, _HELP_("fixed seed"));
set_help_text(seed, _HELP_("seed"));
// init sizer
wxSizer* s = new wxBoxSizer(wxHORIZONTAL);
s->Add(preview, 0, wxRIGHT, 2);
wxSizer* s2 = new wxBoxSizer(wxVERTICAL);
wxSizer* s3 = new wxBoxSizer(wxHORIZONTAL);
wxSizer* s4 = new wxStaticBoxSizer(wxHORIZONTAL, this, _LABEL_("pack selection"));
packsSizer = new wxFlexGridSizer(0, 2, 4, 8);
packsSizer->AddGrowableCol(0);
//s4->AddSpacer(2);
s4->Add(packsSizer, 1, wxEXPAND | wxALL & ~wxTOP, 4);
wxSizer* s4 = new wxStaticBoxSizer(wxVERTICAL, this, _LABEL_("pack selection"));
wxSizer* s4b = new wxBoxSizer(wxHORIZONTAL);
packsSizer = new wxFlexGridSizer(0, 2, 4, 4);
packsSizer->AddGrowableCol(0);
s4b->Add(packsSizer, 1, wxEXPAND | wxALL & ~wxTOP & ~wxBOTTOM & ~wxLEFT, 4);
s4->Add(s4b, 1, wxEXPAND | wxLEFT, 2);
s4->Add(new wxButton(this, ID_CUSTOM_PACK, _BUTTON_("custom pack")), 0, wxEXPAND | wxALL & ~wxTOP, 4);
s3->Add(s4, 1, wxEXPAND, 8);
wxSizer* s5 = new wxStaticBoxSizer(wxHORIZONTAL, this, _LABEL_("pack totals"));
s5->Add(totals, 1, wxEXPAND | wxALL, 4);
......@@ -386,7 +452,6 @@ void RandomPackPanel::initControls() {
//s6->AddStretchSpacer();
//s6->Add(generate_button, 0, wxTOP | wxALIGN_RIGHT, 8);
s6->Add(generate_button, 1, wxTOP | wxEXPAND, 8);
s6->Add(new wxButton(this, ID_CUSTOM_PACK, _BUTTON_("custom pack")), 1, wxTOP | wxEXPAND, 8);
s3->Add(s6, 0, wxEXPAND | wxLEFT, 8);
s2->Add(s3, 0, wxEXPAND | wxALL & ~wxTOP, 4);
s2->Add(card_list, 1, wxEXPAND);
......@@ -489,7 +554,21 @@ void RandomPackPanel::onCommand(int id) {
}
case ID_CUSTOM_PACK: {
CustomPackDialog dlg(this, set, PackTypeP());
dlg.ShowModal();
if (dlg.ShowModal() == wxID_OK) {
// TODO: add pack
}
break;
}
}
}
void RandomPackPanel::onPackTypeClick(wxCommandEvent& ev) {
FOR_EACH(pick,pickers) {
if (pick.label == ev.GetEventObject()) {
// edit this pack type
CustomPackDialog dlg(this, set, pick.pack);
if (dlg.ShowModal() == wxID_OK) {
// TODO: update pack
}
break;
}
}
......@@ -498,7 +577,9 @@ void RandomPackPanel::onCommand(int id) {
// ----------------------------------------------------------------------------- : Generating
void RandomPackPanel::updateTotals() {
#if !USE_NEW_PACK_SYSTEM
#if USE_NEW_PACK_SYSTEM
generator.gen.seed((unsigned)last_seed);
#else
totals->clear();
#endif
int total_packs = 0;
......@@ -595,6 +676,7 @@ void RandomPackPanel::selectionChoices(ExportCardSelectionChoices& out) {
BEGIN_EVENT_TABLE(RandomPackPanel, wxPanel)
EVT_CARD_SELECT(wxID_ANY, RandomPackPanel::onCardSelect)
EVT_BUTTON (ID_PACK_TYPE, RandomPackPanel::onPackTypeClick)
END_EVENT_TABLE ()
......
......@@ -17,6 +17,7 @@
class CardViewer;
class RandomCardList;
class PackTotalsPanel;
class SelectableLabel;
struct CardSelectEvent;
DECLARE_POINTER_TYPE(PackType);
......@@ -24,12 +25,12 @@ DECLARE_POINTER_TYPE(PackType);
// for lists of spin controls
struct PackAmountPicker {
PackTypeP pack;
wxStaticText* label;
wxSpinCtrl* value;
PackTypeP pack;
SelectableLabel* label;
wxSpinCtrl* value;
PackAmountPicker() {}
PackAmountPicker(wxWindow* parent, wxFlexGridSizer* sizer, const PackTypeP& pack);
PackAmountPicker(wxWindow* parent, wxFlexGridSizer* sizer, const PackTypeP& pack, bool active = true);
void destroy(wxFlexGridSizer* sizer);
};
......@@ -93,6 +94,7 @@ class RandomPackPanel : public SetWindowPanel {
void storeSettings();
void onCardSelect(CardSelectEvent& ev);
void onPackTypeClick(wxCommandEvent& ev);
public:
typedef PackItem PackItem_for_typeof;
};
......
......@@ -245,32 +245,6 @@ void SetWindow::selectPanel(int id) {
current_panel->SetFocus();
}
// ----------------------------------------------------------------------------- : Status text for controls
void SetWindow::setControlStatusText(wxWindow* control, const String& text) {
for (size_t i = 0 ; i < control_status_texts.size() ; ++i) {
if (control_status_texts[i].first == control) {
control_status_texts[i].second = text;
return;
}
}
control_status_texts.push_back(make_pair(control,text));
control->Connect(wxEVT_ENTER_WINDOW,wxMouseEventHandler(SetWindow::onControlEnter),nullptr,this);
control->Connect(wxEVT_LEAVE_WINDOW,wxMouseEventHandler(SetWindow::onControlLeave),nullptr,this);
}
void SetWindow::onControlEnter(wxMouseEvent& ev) {
for (size_t i = 0 ; i < control_status_texts.size() ; ++i) {
if (control_status_texts[i].first == ev.GetEventObject()) {
SetStatusText(control_status_texts[i].second);
}
}
ev.Skip();
}
void SetWindow::onControlLeave(wxMouseEvent& ev) {
SetStatusText(wxEmptyString);
ev.Skip();
}
// ----------------------------------------------------------------------------- : Window managment
vector<SetWindow*> SetWindow::set_windows;
......
......@@ -70,15 +70,6 @@ class SetWindow : public wxFrame, public SetView {
/// Switch this window to the new set, or open another window for it (depending on the settings)
void switchSet(const SetP& new_set);
// --------------------------------------------------- : Status text for controls
public:
/// Set the status text of a control
void setControlStatusText(wxWindow* control, const String& text);
private:
vector<pair<wxWindow*,String> > control_status_texts;
void onControlEnter(wxMouseEvent&);
void onControlLeave(wxMouseEvent&);
// --------------------------------------------------- : Action related
protected:
/// We want to respond to set changes
......
......@@ -198,6 +198,7 @@ enum ChildMenuID {
// Random pack panel
, ID_PACK_AMOUNT = 8111
, ID_PACK_TYPE
, ID_SEED_RANDOM
, ID_SEED_FIXED
, ID_GENERATE_PACK
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment