Files
MagicSetEditor2/src/gui/control/gallery_list.hpp
T
GenevensiS 436c437189 add compiler directives
add compiler directives
2025-12-30 01:18:04 +01:00

139 lines
5.3 KiB
C++

//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make card games |
//| Copyright: (C) Twan van Laarhoven and the other MSE developers |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#pragma once
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <util/real_point.hpp>
// ----------------------------------------------------------------------------- : Events
DECLARE_LOCAL_EVENT_TYPE(EVENT_GALLERY_SELECT, <not used>)
DECLARE_LOCAL_EVENT_TYPE(EVENT_GALLERY_ACTIVATE, <not used>)
/// Handle EVENT_GALLERY_SELECT events
#define EVT_GALLERY_SELECT( id, handler) EVT_COMMAND(id, EVENT_GALLERY_SELECT, handler)
/// Handle EVENT_GALLERY_ACTIVATE events
#define EVT_GALLERY_ACTIVATE(id, handler) EVT_COMMAND(id, EVENT_GALLERY_ACTIVATE, handler)
// ----------------------------------------------------------------------------- : GalleryList
/// A list of items with custom drawing
/** A derived class should implement the abstract members to determine how the items look.
*/
class GalleryList : public wxPanel {
public:
GalleryList(Window* parent, int id, int direction = wxHORIZONTAL, bool always_focused = true);
/// Select the given column
void selectSubColumn(size_t subcol);
/// Select the given item in the given column (or in the active column)
void select(size_t item, size_t subcol = NO_SELECTION, bool event = true);
/// Is there an item selected?
inline bool hasSelection(size_t subcol = 0) const { return subcolumns[subcol].selection < itemCount(); }
/// Get the id of the selected item, throws if there is no selection
inline size_t getSelectionId(size_t subcol = 0) const {
if (!hasSelection(subcol)) throw Error(_("No selection"));
return subcolumns[subcol].selection;
}
/// Is the given item selected?
inline bool isSelected(size_t item, size_t subcol = 0) const {
return subcol < subcolumns.size() && subcolumns[subcol].selection == item;
}
/// Redraw only the selected items
void RefreshSelection();
protected:
static const size_t NO_SELECTION = (size_t)-1;
size_t active_subcolumn; ///< The active subcolumn
wxSize item_size; ///< The total size of a single item (over all columns)
int direction; ///< Direction of the list, can be wxHORIZONTAL or wxVERTICAL
size_t column_count; ///< Number of major level columns (if vertical) or rows (if horizontal)
bool always_focused; ///< Always draw as if focused
/// Redraw the list after changing the selection or the number of items
void update();
/// Return how many items there are in the list
virtual size_t itemCount() const = 0;
/// Draw an item
virtual void drawItem(DC& dc, int x, int y, size_t item) = 0;
/// How 'salient' should the selection in the given subcolumn be?
virtual double subcolumnActivity(size_t col) const { return 0.7; }
/// Filter calls to select, or apply some extra operaions
virtual void onSelect(size_t item, size_t col, bool& changes) {}
/// Return the desired size of control
wxSize DoGetBestSize() const override;
/// Information on the subcolumns. These are columns inside items
struct SubColumn {
wxPoint offset;
wxSize size;
bool can_select;
size_t selection;
};
vector<SubColumn> subcolumns;
private:
DECLARE_EVENT_TABLE();
void onLeftDown (wxMouseEvent& ev);
void onLeftDClick(wxMouseEvent& ev);
void onMouseWheel(wxMouseEvent& ev);
void onChar(wxKeyEvent& ev);
void onFocus(wxFocusEvent&);
void onPaint(wxPaintEvent&);
void onSize(wxSizeEvent&);
void onScroll(wxScrollWinEvent&);
void OnDraw(DC& dc);
/// Find the item corresponding to the given location
size_t findItem(const wxMouseEvent&) const;
/// Find the coordinates of an item
wxPoint itemPos(size_t item) const;
/// Scroll to the given position (note: 'top' can also mean 'left')
void scrollTo(int top, bool update_scrollbar = true);
/// Update the scrollbar(s)
void updateScrollbar();
/// Redraw just a single item
void RefreshItem(size_t item);
/// First visible pixel position
int visible_start;
/// First no-longer-visible pixel position
inline int visibleEnd() const {
return visible_start + mainSize(GetClientSize());
}
/// Pixel position of an item
inline int itemStart(size_t item) const {
return (int)(item / column_count) * (mainSize(item_size) + SPACING);
}
inline int itemEnd(size_t item) const {
return (int)(item / column_count + 1) * (mainSize(item_size) + SPACING) + MARGIN;
}
/// Main component of a size (i.e. in the direction of this list)
inline int mainSize(wxSize s) const {
return direction == wxHORIZONTAL ? s.x : s.y;
}
public:
typedef SubColumn SubColumn_for_typeof;
protected:
/// Send an event
void sendEvent(WXTYPE type);
static const int MARGIN = 1; // margin between items (excluding border)
static const int BORDER = 0; // border around items
static const int SPACING = MARGIN + 2*BORDER; // distance between items
};