mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-13 05:57:00 -04:00
Added GraphControl; FilteredCardList; ValueEditor
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@74 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -65,6 +65,7 @@ class Set : public Packaged {
|
|||||||
void updateFor(const CardP& card);
|
void updateFor(const CardP& card);
|
||||||
|
|
||||||
/// Stylesheet to use for a particular card
|
/// Stylesheet to use for a particular card
|
||||||
|
/** card may be null */
|
||||||
StyleSheetP stylesheetFor(const CardP& card);
|
StyleSheetP stylesheetFor(const CardP& card);
|
||||||
|
|
||||||
/// Styling information for a particular stylesheet
|
/// Styling information for a particular stylesheet
|
||||||
|
|||||||
@@ -7,8 +7,96 @@
|
|||||||
// ----------------------------------------------------------------------------- : Includes
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
#include <data/symbol_font.hpp>
|
#include <data/symbol_font.hpp>
|
||||||
|
#include <util/dynamic_arg.hpp>
|
||||||
|
#include <util/io/package_manager.hpp>
|
||||||
|
#include <script/image.hpp>
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : SymbolFont
|
// ----------------------------------------------------------------------------- : SymbolFont
|
||||||
|
|
||||||
|
// SymbolFont that is used for SymbolInFonts constructed with the default constructor
|
||||||
|
DECLARE_DYNAMIC_ARG(SymbolFont*, symbol_font_for_reading);
|
||||||
|
IMPLEMENT_DYNAMIC_ARG(SymbolFont*, symbol_font_for_reading, nullptr);
|
||||||
|
|
||||||
|
SymbolFont::SymbolFont()
|
||||||
|
: img_size(12), min_size(1)
|
||||||
|
, spacing(1,1)
|
||||||
|
, scale_text(false)
|
||||||
|
, text_margin_left(0), text_margin_right(0)
|
||||||
|
, text_margin_top(0), text_margin_bottom(0)
|
||||||
|
, text_alignment(ALIGN_MIDDLE_CENTER)
|
||||||
|
, merge_numbers(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
String SymbolFont::typeNameStatic() { return _("symbol-font"); }
|
||||||
|
String SymbolFont::typeName() const { return _("symbol-font"); }
|
||||||
|
|
||||||
|
SymbolFontP SymbolFont::byName(const String& name) {
|
||||||
|
return packages.open<SymbolFont>(name + _(".mse-symbol-font"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SymbolFont::split(const String& text, SplitSymbols& out) {
|
||||||
|
for (size_t pos = 0 ; pos < text.size() ; ) {
|
||||||
|
// read a single symbol
|
||||||
|
pos = pos + 1; // TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_REFLECTION(SymbolFont) {
|
||||||
|
tag.addAlias(300, _("text align"), _("text alignment"));
|
||||||
|
|
||||||
|
REFLECT_N("image font size", img_size);
|
||||||
|
REFLECT_N("scale down to", min_size);
|
||||||
|
REFLECT_N("horizontal space", spacing.width);
|
||||||
|
REFLECT_N("vertical space", spacing.height);
|
||||||
|
WITH_DYNAMIC_ARG(symbol_font_for_reading, this);
|
||||||
|
REFLECT(symbols);
|
||||||
|
REFLECT(text_font);
|
||||||
|
REFLECT(scale_text);
|
||||||
|
REFLECT(merge_numbers);
|
||||||
|
REFLECT(text_margin_left);
|
||||||
|
REFLECT(text_margin_right);
|
||||||
|
REFLECT(text_margin_top);
|
||||||
|
REFLECT(text_margin_bottom);
|
||||||
|
REFLECT(text_alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : SymbolFont::Symbol
|
||||||
|
|
||||||
|
/// A symbol in a symbol font
|
||||||
|
class SymbolInFont {
|
||||||
|
public:
|
||||||
|
SymbolInFont();
|
||||||
|
|
||||||
|
/// Get a shrunk, zoomed bitmap
|
||||||
|
Bitmap getBitmap(Context& ctx, double size);
|
||||||
|
|
||||||
|
/// Size of a (zoomed) bitmap
|
||||||
|
/** This is the size of the resulting image, it does NOT convert back to internal coordinates */
|
||||||
|
RealSize size(Context& ctx, double size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
String code; ///< Code for this symbol
|
||||||
|
ScriptableImage image; ///< The image for this symbol
|
||||||
|
UInt img_size; ///< Font size used by the image
|
||||||
|
wxSize actual_size; ///< Actual image size, only known after loading the image
|
||||||
|
/// Cached bitmaps for different sizes
|
||||||
|
map<double, Bitmap> bitmaps;
|
||||||
|
|
||||||
|
DECLARE_REFLECTION();
|
||||||
|
};
|
||||||
|
|
||||||
|
SymbolInFont::SymbolInFont()
|
||||||
|
{
|
||||||
|
assert(symbol_font_for_reading());
|
||||||
|
img_size = symbol_font_for_reading()->img_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_REFLECTION(SymbolInFont) {
|
||||||
|
REFLECT(code);
|
||||||
|
REFLECT(image);
|
||||||
|
REFLECT_N("image font size", img_size);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : SymbolFontRef
|
// ----------------------------------------------------------------------------- : SymbolFontRef
|
||||||
|
|
||||||
SymbolFontRef::SymbolFontRef()
|
SymbolFontRef::SymbolFontRef()
|
||||||
@@ -17,6 +105,11 @@ SymbolFontRef::SymbolFontRef()
|
|||||||
, alignment(ALIGN_MIDDLE_CENTER)
|
, alignment(ALIGN_MIDDLE_CENTER)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
bool SymbolFontRef::valid() const {
|
||||||
|
return !!font; //TODO: does this make sense?
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
IMPLEMENT_REFLECTION(SymbolFontRef) {
|
IMPLEMENT_REFLECTION(SymbolFontRef) {
|
||||||
REFLECT(name);
|
REFLECT(name);
|
||||||
REFLECT(size);
|
REFLECT(size);
|
||||||
|
|||||||
@@ -17,32 +17,51 @@
|
|||||||
DECLARE_POINTER_TYPE(Font);
|
DECLARE_POINTER_TYPE(Font);
|
||||||
DECLARE_POINTER_TYPE(SymbolFont);
|
DECLARE_POINTER_TYPE(SymbolFont);
|
||||||
DECLARE_POINTER_TYPE(SymbolInFont);
|
DECLARE_POINTER_TYPE(SymbolInFont);
|
||||||
|
class RotatedDC;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : SymbolFont
|
// ----------------------------------------------------------------------------- : SymbolFont
|
||||||
|
|
||||||
// A font that is drawn using images
|
// A font that is drawn using images
|
||||||
class SymbolFont : Packaged {
|
class SymbolFont : public Packaged {
|
||||||
public:
|
public:
|
||||||
|
SymbolFont();
|
||||||
|
|
||||||
/// Loads the symbol font with a given name, for example "magic-mana-large"
|
/// Loads the symbol font with a given name, for example "magic-mana-large"
|
||||||
static SymbolFontP byName(const String& name);
|
static SymbolFontP byName(const String& name);
|
||||||
|
|
||||||
|
class DrawableSymbol {
|
||||||
|
public:
|
||||||
|
// TODO: anything?
|
||||||
|
private:
|
||||||
|
String text; ///< Original text
|
||||||
|
SymbolInFont* symbol; ///< Symbol to draw, if nullptr, use the default symbol and draw the text
|
||||||
|
};
|
||||||
|
typedef vector<DrawableSymbol> SplitSymbols;
|
||||||
|
|
||||||
|
/// Split a string into separate symbols for drawing and for determining their size
|
||||||
|
void split(const String& text, SplitSymbols& out);
|
||||||
|
|
||||||
|
/// Draw a piece of text prepared using split
|
||||||
|
void draw(RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, const SplitSymbols& text);
|
||||||
|
|
||||||
|
static String typeNameStatic();
|
||||||
|
virtual String typeName() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UInt imgSize; ///< Font size that the images use
|
UInt img_size; ///< Font size that the images use
|
||||||
UInt minSize; ///< Minimum font size
|
UInt min_size; ///< Minimum font size
|
||||||
RealSize spacing; ///< Spacing between sybmols (for the default font size)
|
RealSize spacing; ///< Spacing between sybmols (for the default font size)
|
||||||
// writing text
|
// writing text
|
||||||
bool scale_text; ///< Should text be scaled down to fit in a symbol?
|
bool scale_text; ///< Should text be scaled down to fit in a symbol?
|
||||||
FontP text_font; ///< Font to use for missing symbols
|
FontP text_font; ///< Font to use for missing symbols
|
||||||
double text_margin_left;
|
double text_margin_left;
|
||||||
double text_margin_right;
|
double text_margin_right;
|
||||||
double text_margin_rop;
|
double text_margin_top;
|
||||||
double text_margin_bottom;
|
double text_margin_bottom;
|
||||||
Alignment text_align;
|
Alignment text_alignment;
|
||||||
bool merge_numbers; ///< Merge numbers? e.g. "11" is a single symbol ('1' must not exist as a symbol)
|
bool merge_numbers; ///< Merge numbers? e.g. "11" is a single symbol ('1' must not exist as a symbol)
|
||||||
|
|
||||||
public:
|
friend class SymbolInFont;
|
||||||
class Symbol;
|
|
||||||
private:
|
|
||||||
vector<SymbolInFontP> symbols; ///< The individual symbols
|
vector<SymbolInFontP> symbols; ///< The individual symbols
|
||||||
|
|
||||||
DECLARE_REFLECTION();
|
DECLARE_REFLECTION();
|
||||||
@@ -60,7 +79,7 @@ class SymbolFontRef {
|
|||||||
void initDependencies(Context&, Dependency& dep);
|
void initDependencies(Context&, Dependency& dep);
|
||||||
|
|
||||||
/// Is a font loaded?
|
/// Is a font loaded?
|
||||||
bool valid();
|
bool valid() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Scriptable<String> name; ///< Font package name, can be changed with script
|
Scriptable<String> name; ///< Font package name, can be changed with script
|
||||||
|
|||||||
@@ -7,13 +7,22 @@
|
|||||||
// ----------------------------------------------------------------------------- : Includes
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
#include <gui/control/card_editor.hpp>
|
#include <gui/control/card_editor.hpp>
|
||||||
|
#include <gui/value/editor.hpp>
|
||||||
|
#include <data/field.hpp>
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : DataEditor
|
// ----------------------------------------------------------------------------- : DataEditor
|
||||||
|
|
||||||
|
#define FOR_EACH_EDITOR \
|
||||||
|
FOR_EACH(v, viewers) \
|
||||||
|
if (ValueEditorP = static_pointer_cast<ValueEditor>(v))
|
||||||
|
|
||||||
DataEditor::DataEditor(Window* parent, int id, long style)
|
DataEditor::DataEditor(Window* parent, int id, long style)
|
||||||
: CardViewer(parent, id, style)
|
: CardViewer(parent, id, style)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
ValueViewerP DataEditor::makeViewer(const StyleP& style) {
|
||||||
|
return style->makeEditor(*this, style);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Event table
|
// ----------------------------------------------------------------------------- : Event table
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,11 @@
|
|||||||
class DataEditor : public CardViewer {
|
class DataEditor : public CardViewer {
|
||||||
public:
|
public:
|
||||||
DataEditor(Window* parent, int id, long style = 0);
|
DataEditor(Window* parent, int id, long style = 0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Create an editor for the given style (as opposed to a normal viewer)
|
||||||
|
virtual ValueViewerP makeViewer(const StyleP&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_EVENT_TABLE();
|
DECLARE_EVENT_TABLE();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ void CardListBase::onAction(const Action& action, bool undone) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<CardP>& CardListBase::getCards() const {
|
const vector<CardP>& CardListBase::getCards() const {
|
||||||
return set->cards;
|
return set->cards;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ struct CardListBase::CardComparer {
|
|||||||
|
|
||||||
void CardListBase::sortList() {
|
void CardListBase::sortList() {
|
||||||
sorted_card_list.clear();
|
sorted_card_list.clear();
|
||||||
FOR_EACH(card, getCards()) {
|
FOR_EACH_CONST(card, getCards()) {
|
||||||
sorted_card_list.push_back(card);
|
sorted_card_list.push_back(card);
|
||||||
}
|
}
|
||||||
if (sort_criterium) {
|
if (sort_criterium) {
|
||||||
@@ -198,6 +198,7 @@ void CardListBase::rebuild() {
|
|||||||
ClearAll();
|
ClearAll();
|
||||||
column_fields.clear();
|
column_fields.clear();
|
||||||
selected_card_pos = -1;
|
selected_card_pos = -1;
|
||||||
|
onRebuild();
|
||||||
// determine column order
|
// determine column order
|
||||||
map<int,FieldP> new_column_fields;
|
map<int,FieldP> new_column_fields;
|
||||||
FOR_EACH(f, set->game->card_fields) {
|
FOR_EACH(f, set->game->card_fields) {
|
||||||
|
|||||||
@@ -82,7 +82,12 @@ class CardListBase : public wxListView, public SetView {
|
|||||||
// --------------------------------------------------- : The cards
|
// --------------------------------------------------- : The cards
|
||||||
protected:
|
protected:
|
||||||
/// What cards should be shown?
|
/// What cards should be shown?
|
||||||
virtual vector<CardP>& getCards() const;
|
virtual const vector<CardP>& getCards() const;
|
||||||
|
|
||||||
|
/// Rebuild the card list (clear all vectors and fill them again)
|
||||||
|
void rebuild();
|
||||||
|
/// Do some additional updating before rebuilding the list
|
||||||
|
virtual void onRebuild() {}
|
||||||
|
|
||||||
// --------------------------------------------------- : Item 'events'
|
// --------------------------------------------------- : Item 'events'
|
||||||
|
|
||||||
@@ -109,9 +114,6 @@ class CardListBase : public wxListView, public SetView {
|
|||||||
|
|
||||||
mutable wxListItemAttr item_attr; // for OnGetItemAttr
|
mutable wxListItemAttr item_attr; // for OnGetItemAttr
|
||||||
|
|
||||||
// /// Get a card by position
|
|
||||||
// void getCard(long pos);
|
|
||||||
|
|
||||||
/// Select a card, send an event to the parent
|
/// Select a card, send an event to the parent
|
||||||
/** If focus then the card is also focused and selected in the actual control.
|
/** If focus then the card is also focused and selected in the actual control.
|
||||||
* This should abviously not be done when the card is selected because it was selected (leading to a loop).
|
* This should abviously not be done when the card is selected because it was selected (leading to a loop).
|
||||||
@@ -127,8 +129,6 @@ class CardListBase : public wxListView, public SetView {
|
|||||||
/// Sorts the list by the current sorting criterium
|
/// Sorts the list by the current sorting criterium
|
||||||
void sortList();
|
void sortList();
|
||||||
struct CardComparer; // for comparing cards
|
struct CardComparer; // for comparing cards
|
||||||
/// Rebuild the card list (clear all vectors and fill them again)
|
|
||||||
void rebuild();
|
|
||||||
/// Refresh the card list (resort, refresh and reselect current item)
|
/// Refresh the card list (resort, refresh and reselect current item)
|
||||||
void refreshList();
|
void refreshList();
|
||||||
/// Find the field that determines the color, if any.
|
/// Find the field that determines the color, if any.
|
||||||
|
|||||||
@@ -18,11 +18,13 @@ CardViewer::CardViewer(Window* parent, int id, long style)
|
|||||||
|
|
||||||
wxSize CardViewer::DoGetBestSize() const {
|
wxSize CardViewer::DoGetBestSize() const {
|
||||||
wxSize ws = GetSize(), cs = GetClientSize();
|
wxSize ws = GetSize(), cs = GetClientSize();
|
||||||
if (set && set->stylesheet) {
|
if (set) {
|
||||||
return wxSize(set->stylesheet->card_width, set->stylesheet->card_height) + ws - cs;
|
StyleSheetP stylesheet = set->stylesheetFor(card);
|
||||||
} else {
|
if (stylesheet) {
|
||||||
return cs;
|
return wxSize(stylesheet->card_width, stylesheet->card_height) + ws - cs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardViewer::onChange() {
|
void CardViewer::onChange() {
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||||
|
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
|
||||||
|
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
|
#include <gui/control/filtered_card_list.hpp>
|
||||||
|
|
||||||
|
DECLARE_TYPEOF_COLLECTION(CardP);
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : FilteredCardList
|
||||||
|
|
||||||
|
FilteredCardList::FilteredCardList(Window* parent, int id, int style)
|
||||||
|
: CardListBase(parent, id, style)
|
||||||
|
{}
|
||||||
|
|
||||||
|
const vector<CardP>& FilteredCardList::getCards() const {
|
||||||
|
return cards;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilteredCardList::setFilter(const CardListFilterP& filter_) {
|
||||||
|
filter = filter_;
|
||||||
|
rebuild();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FilteredCardList::onRebuild() {
|
||||||
|
cards.clear();
|
||||||
|
if (filter) {
|
||||||
|
FOR_EACH(c, set->cards) {
|
||||||
|
if (filter->keep(c)) {
|
||||||
|
cards.push_back(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||||
|
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
|
||||||
|
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
#ifndef HEADER_GUI_CONTROL_FILTERED_CARD_LIST
|
||||||
|
#define HEADER_GUI_CONTROL_FILTERED_CARD_LIST
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
|
#include <util/prec.hpp>
|
||||||
|
#include <gui/control/card_list.hpp>
|
||||||
|
|
||||||
|
DECLARE_POINTER_TYPE(CardListFilter);
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : CardListFilter
|
||||||
|
|
||||||
|
/// A filter function to determine which items are shown in a card list
|
||||||
|
class CardListFilter {
|
||||||
|
public:
|
||||||
|
virtual ~CardListFilter() {}
|
||||||
|
/// Should a card be shown in the list?
|
||||||
|
virtual bool keep(const CardP& card) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : FilteredCardList
|
||||||
|
|
||||||
|
/// A card list that lists a subset of the cards in the set
|
||||||
|
class FilteredCardList : public CardListBase {
|
||||||
|
public:
|
||||||
|
FilteredCardList(Window* parent, int id, int style = 0);
|
||||||
|
|
||||||
|
/// Change the filter to use
|
||||||
|
void setFilter(const CardListFilterP& filter_);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Get only the subset of the cards
|
||||||
|
virtual const vector<CardP>& getCards() const;
|
||||||
|
/// Rebuild the filtered card list
|
||||||
|
virtual void onRebuild();
|
||||||
|
// /// Don't reorder
|
||||||
|
// virtual void onDrag(wxMouseEvent& e);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CardListFilterP filter; ///< Filter with which this.cards is made
|
||||||
|
vector<CardP> cards; ///< The cards that are shown
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
|
#endif
|
||||||
@@ -30,6 +30,9 @@ class GalleryList : public wxScrolledWindow {
|
|||||||
public:
|
public:
|
||||||
GalleryList(Window* parent, int id, int direction = wxHORIZONTAL);
|
GalleryList(Window* parent, int id, int direction = wxHORIZONTAL);
|
||||||
|
|
||||||
|
/// Is there an item selected?
|
||||||
|
inline bool hasSelection() const { return selection < itemCount(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const size_t NO_SELECTION = (size_t)-1;
|
static const size_t NO_SELECTION = (size_t)-1;
|
||||||
size_t selection; ///< The selected item, or NO_SELECTION if there is no selection
|
size_t selection; ///< The selected item, or NO_SELECTION if there is no selection
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||||
|
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
|
||||||
|
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
|
#include <gui/control/graph.hpp>
|
||||||
|
#include <wx/dcbuffer.h>
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Graph
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : GraphControl
|
||||||
|
|
||||||
|
GraphControl::GraphControl(Window* parent, int id)
|
||||||
|
: wxControl(parent, id)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void GraphControl::onPaint(wxPaintEvent&) {
|
||||||
|
wxBufferedPaintDC dc(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphControl::onSize(wxSizeEvent&) {
|
||||||
|
Refresh(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphControl::onMouseDown(wxMouseEvent& ev) {
|
||||||
|
if (!graph) return;
|
||||||
|
wxSize cs = GetClientSize();
|
||||||
|
graph->findItem(RealPoint((double)ev.GetX()/cs.GetWidth(), (double)ev.GetY()/cs.GetHeight()), current_item);
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE(GraphControl, wxControl)
|
||||||
|
EVT_PAINT (GraphControl::onPaint)
|
||||||
|
EVT_SIZE (GraphControl::onSize)
|
||||||
|
EVT_LEFT_DOWN (GraphControl::onMouseDown)
|
||||||
|
END_EVENT_TABLE ()
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||||
|
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
|
||||||
|
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
#ifndef HEADER_GUI_CONTROL_GRAPH
|
||||||
|
#define HEADER_GUI_CONTROL_GRAPH
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
|
#include <util/prec.hpp>
|
||||||
|
#include <util/rotation.hpp>
|
||||||
|
|
||||||
|
DECLARE_POINTER_TYPE(GraphAxis);
|
||||||
|
DECLARE_POINTER_TYPE(GraphElement);
|
||||||
|
DECLARE_POINTER_TYPE(GraphData);
|
||||||
|
DECLARE_POINTER_TYPE(Graph);
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Graph data
|
||||||
|
|
||||||
|
/// A group in a table or graph
|
||||||
|
/** A group is rendered as a single bar or pie slice */
|
||||||
|
class GraphGroup {
|
||||||
|
public:
|
||||||
|
String name; ///< Name of this position
|
||||||
|
Color color; ///< Associated color
|
||||||
|
int size; ///< Number of elements in this group
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An axis in a graph, consists of a list of groups
|
||||||
|
/** The sum of groups.sum = sum of all elements in the data */
|
||||||
|
class GraphAxis {
|
||||||
|
public:
|
||||||
|
String name; ///< Name/label of this axis
|
||||||
|
bool auto_color; ///< Automatically assign colors to the groups on this axis
|
||||||
|
vector<GraphGroup> groups; ///< Groups along this axis
|
||||||
|
int max; ///< Maximum size of the groups
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A single data point of a graph
|
||||||
|
class GraphElement {
|
||||||
|
public:
|
||||||
|
vector<String> axis_groups; ///< Group name for each axis
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Data to be displayed in a graph, not processed yet
|
||||||
|
class GraphDataPre {
|
||||||
|
public:
|
||||||
|
vector<GraphAxisP> axes;
|
||||||
|
vector<GraphElementP> elements;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Data to be displayed in a graph
|
||||||
|
class GraphData {
|
||||||
|
public:
|
||||||
|
GraphData(GraphDataPre);
|
||||||
|
|
||||||
|
vector<GraphAxisP> axes; ///< The axes in the data
|
||||||
|
vector<int> values; ///< Multi dimensional (dim = axes.size()) array of values
|
||||||
|
int size; ///< Total number of elements
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Graph
|
||||||
|
|
||||||
|
/// A type of graph
|
||||||
|
/** It is rendered into a sub-rectangle of the screen */
|
||||||
|
class Graph {
|
||||||
|
public:
|
||||||
|
/// Draw this graph, filling the internalRect() of the dc.
|
||||||
|
virtual void draw(RotatedDC& dc) = 0;
|
||||||
|
/// Find the item at the given position, position is normalized to [0..1)
|
||||||
|
virtual bool findItem(const RealPoint& pos, vector<int>& out) const { return false; }
|
||||||
|
/// Change the data
|
||||||
|
virtual void setData(const GraphDataP& d) { data = d; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// Data of the graph
|
||||||
|
GraphDataP data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Base class for 1 dimensional graph components
|
||||||
|
class Graph1D : public Graph {
|
||||||
|
public:
|
||||||
|
inline Graph1D(size_t axis) : axis(axis) {}
|
||||||
|
virtual bool findItem(const RealPoint& pos, vector<int>& out) const { return false; }
|
||||||
|
protected:
|
||||||
|
size_t axis;
|
||||||
|
/// Find an item, return the position along the axis, or -1 if not found
|
||||||
|
virtual int findItem(const RealPoint& pos) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A bar graph
|
||||||
|
class BarGraph : public Graph1D {
|
||||||
|
public:
|
||||||
|
inline BarGraph(size_t axis) : Graph1D(axis) {}
|
||||||
|
virtual void draw(RotatedDC& dc) const;
|
||||||
|
virtual int findItem(const RealPoint& pos) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
//class BarGraph2D {
|
||||||
|
//};
|
||||||
|
|
||||||
|
/// A pie graph
|
||||||
|
class PieGraph : public Graph1D {
|
||||||
|
public:
|
||||||
|
inline PieGraph(size_t axis) : Graph1D(axis) {}
|
||||||
|
virtual void draw(RotatedDC& dc) const;
|
||||||
|
virtual int findItem(const RealPoint& pos) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The legend, used for pie graphs
|
||||||
|
class GraphLegend : public Graph1D {
|
||||||
|
public:
|
||||||
|
inline GraphLegend(size_t axis) : Graph1D(axis) {}
|
||||||
|
virtual void draw(RotatedDC& dc) const;
|
||||||
|
virtual int findItem(const RealPoint& pos) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
//class GraphTable {
|
||||||
|
//};
|
||||||
|
|
||||||
|
//class GraphAxis : public Graph1D {
|
||||||
|
// virtual void draw(RotatedDC& dc) const;
|
||||||
|
//};
|
||||||
|
|
||||||
|
//class GraphValueAxis {
|
||||||
|
// virtual void draw(RotatedDC& dc) const;
|
||||||
|
//};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Graph control
|
||||||
|
|
||||||
|
/// A control showing statistics in a graphical form
|
||||||
|
class GraphControl : public wxControl {
|
||||||
|
public:
|
||||||
|
/// Create a graph control
|
||||||
|
GraphControl(Window* parent, int id);
|
||||||
|
|
||||||
|
/// Update the data in the graph
|
||||||
|
void setData(const GraphDataPre& data);
|
||||||
|
/// Update the data in the graph
|
||||||
|
void setData(const GraphDataP& data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Graph object
|
||||||
|
GraphP graph;
|
||||||
|
/// The selected item per axis, or an empty vector if there is no selection
|
||||||
|
/** If the value for an axis is -1, then all groups on that axis are selected */
|
||||||
|
vector<int> current_item;
|
||||||
|
|
||||||
|
DECLARE_EVENT_TABLE();
|
||||||
|
|
||||||
|
void onPaint(wxPaintEvent&);
|
||||||
|
void onSize (wxSizeEvent&);
|
||||||
|
void onMouseDown(wxMouseEvent& ev);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
|
#endif
|
||||||
@@ -33,9 +33,6 @@ class PackageList : public GalleryList {
|
|||||||
/// Clears this list
|
/// Clears this list
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
/// Is there a package selected?
|
|
||||||
inline bool hasSelection() const { return selection < itemCount(); }
|
|
||||||
|
|
||||||
/// Get the selected package, T should be the same type used for showData
|
/// Get the selected package, T should be the same type used for showData
|
||||||
/** @pre hasSelection()
|
/** @pre hasSelection()
|
||||||
* Throws if the selection is not of type T */
|
* Throws if the selection is not of type T */
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ CardsPanel::CardsPanel(Window* parent, int id)
|
|||||||
wxSizer* s = new wxBoxSizer(wxHORIZONTAL);
|
wxSizer* s = new wxBoxSizer(wxHORIZONTAL);
|
||||||
s->Add(editor, 0, wxRIGHT, 2);
|
s->Add(editor, 0, wxRIGHT, 2);
|
||||||
s->Add(card_list, 1, wxEXPAND);
|
s->Add(card_list, 1, wxEXPAND);
|
||||||
|
s->SetSizeHints(this);
|
||||||
SetSizer(s);
|
SetSizer(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,8 +38,6 @@ class CardsPanel : public SetWindowPanel {
|
|||||||
virtual bool wantsToHandle(const Action&, bool undone) const;
|
virtual bool wantsToHandle(const Action&, bool undone) const;
|
||||||
virtual void onAction(const Action&, bool undone);
|
virtual void onAction(const Action&, bool undone);
|
||||||
virtual void onRenderSettingsChange();
|
virtual void onRenderSettingsChange();
|
||||||
private:
|
|
||||||
void updateSize();
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// --------------------------------------------------- : Clipboard
|
// --------------------------------------------------- : Clipboard
|
||||||
|
|||||||
@@ -8,4 +8,9 @@
|
|||||||
|
|
||||||
#include <gui/set/set_info_panel.hpp>
|
#include <gui/set/set_info_panel.hpp>
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- :
|
// ----------------------------------------------------------------------------- : SetInfoPanel
|
||||||
|
|
||||||
|
SetInfoPanel::SetInfoPanel(Window* parent, int id)
|
||||||
|
: SetWindowPanel(parent, id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,9 +7,54 @@
|
|||||||
// ----------------------------------------------------------------------------- : Includes
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
#include <gui/set/stats_panel.hpp>
|
#include <gui/set/stats_panel.hpp>
|
||||||
|
#include <gui/control/graph.hpp>
|
||||||
|
#include <gui/control/gallery_list.hpp>
|
||||||
|
#include <gui/control/filtered_card_list.hpp>
|
||||||
|
#include <wx/splitter.h>
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : StatFieldList
|
||||||
|
|
||||||
|
/// A list of fields of which the statistics can be shown
|
||||||
|
class StatFieldList : public GalleryList {
|
||||||
|
public:
|
||||||
|
StatFieldList(Window* parent, int id)
|
||||||
|
: GalleryList(parent, id, wxVERTICAL)
|
||||||
|
{
|
||||||
|
item_size = wxSize(100, 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual size_t itemCount() const;
|
||||||
|
virtual void drawItem(DC& dc, int x, int y, size_t item, bool selected);
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t StatFieldList::itemCount() const {
|
||||||
|
return 0; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatFieldList::drawItem(DC& dc, int x, int y, size_t item, bool selected) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : StatsPanel
|
// ----------------------------------------------------------------------------- : StatsPanel
|
||||||
|
|
||||||
StatsPanel::StatsPanel(Window* parent, int id)
|
StatsPanel::StatsPanel(Window* parent, int id)
|
||||||
: SetWindowPanel(parent, id)
|
: SetWindowPanel(parent, id)
|
||||||
{}
|
{
|
||||||
|
// init controls
|
||||||
|
wxSplitterWindow* splitter;
|
||||||
|
fields = new StatFieldList (this, wxID_ANY);
|
||||||
|
splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
|
||||||
|
graph = new GraphControl (splitter, wxID_ANY);
|
||||||
|
card_list = new FilteredCardList(splitter, wxID_ANY);
|
||||||
|
// init splitter
|
||||||
|
splitter->SetMinimumPaneSize(100);
|
||||||
|
splitter->SetSashGravity(1.0);
|
||||||
|
splitter->SplitHorizontally(graph, card_list, -100);
|
||||||
|
// init sizer
|
||||||
|
wxSizer* s = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
s->Add(fields, 0, wxEXPAND | wxRIGHT, 2);
|
||||||
|
s->Add(splitter, 1, wxEXPAND);
|
||||||
|
s->SetSizeHints(this);
|
||||||
|
SetSizer(s);
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,13 +12,23 @@
|
|||||||
#include <util/prec.hpp>
|
#include <util/prec.hpp>
|
||||||
#include <gui/set/panel.hpp>
|
#include <gui/set/panel.hpp>
|
||||||
|
|
||||||
|
class StatFieldList;
|
||||||
|
class GraphControl;
|
||||||
|
class FilteredCardList;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : StatsPanel
|
// ----------------------------------------------------------------------------- : StatsPanel
|
||||||
|
|
||||||
class StatsPanel : public SetWindowPanel {
|
class StatsPanel : public SetWindowPanel {
|
||||||
public:
|
public:
|
||||||
StatsPanel(Window* parent, int id);
|
StatsPanel(Window* parent, int id);
|
||||||
|
|
||||||
|
// virtual void onUpdateUI(wxUpdateUIEvent& e);
|
||||||
|
// virtual void onCommand(int id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
StatFieldList* fields;
|
||||||
|
GraphControl* graph;
|
||||||
|
FilteredCardList* card_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : EOF
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
|
|||||||
@@ -199,7 +199,6 @@ void SetWindow::selectPanel(int id) {
|
|||||||
++wid;
|
++wid;
|
||||||
}
|
}
|
||||||
// fix sizer stuff
|
// fix sizer stuff
|
||||||
Layout();
|
|
||||||
fixMinWindowSize();
|
fixMinWindowSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,11 +256,13 @@ void SetWindow::onRenderSettingsChange() {
|
|||||||
FOR_EACH(p, panels) {
|
FOR_EACH(p, panels) {
|
||||||
p->onRenderSettingsChange();
|
p->onRenderSettingsChange();
|
||||||
}
|
}
|
||||||
Layout();
|
|
||||||
fixMinWindowSize();
|
fixMinWindowSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetWindow::fixMinWindowSize() {
|
void SetWindow::fixMinWindowSize() {
|
||||||
|
current_panel->Layout();
|
||||||
|
current_panel->SetMinSize(current_panel->GetSizer()->GetMinSize());
|
||||||
|
Layout();
|
||||||
wxSize s = GetSizer()->GetMinSize();
|
wxSize s = GetSizer()->GetMinSize();
|
||||||
wxSize ws = GetSize();
|
wxSize ws = GetSize();
|
||||||
wxSize cs = GetClientSize();
|
wxSize cs = GetClientSize();
|
||||||
@@ -269,6 +270,7 @@ void SetWindow::fixMinWindowSize() {
|
|||||||
if (ws.x < minSize.x) ws.x = minSize.x;
|
if (ws.x < minSize.x) ws.x = minSize.x;
|
||||||
if (ws.y < minSize.y) ws.y = minSize.y;
|
if (ws.y < minSize.y) ws.y = minSize.y;
|
||||||
SetSize(ws);
|
SetSize(ws);
|
||||||
|
SetMinSize(minSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||||
|
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
|
||||||
|
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
|
#include <gui/value/editor.hpp>
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : ValueEditor
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
||||||
|
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
|
||||||
|
//| License: GNU General Public License 2 or later (see file COPYING) |
|
||||||
|
//+----------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
#ifndef HEADER_GUI_VALUE_EDITOR
|
||||||
|
#define HEADER_GUI_VALUE_EDITOR
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
|
#include <util/prec.hpp>
|
||||||
|
#include <render/value/viewer.hpp>
|
||||||
|
|
||||||
|
class DataEditor;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : ValueEditor
|
||||||
|
|
||||||
|
/// An editor 'control' for a single value on a card
|
||||||
|
/** The inheritance diagram for derived editors looks like:
|
||||||
|
* ValueViewer
|
||||||
|
* ^ ^
|
||||||
|
* / .
|
||||||
|
* / .
|
||||||
|
* SomeViewer ValueEditor
|
||||||
|
* ^ ^
|
||||||
|
* \ /
|
||||||
|
* \ /
|
||||||
|
* SomeEditor
|
||||||
|
*
|
||||||
|
* Where ... is virtual inheritance and -- is normal inheritance.
|
||||||
|
* This is slightly different from the usual virtual inheritance recipe, but it should still work.
|
||||||
|
*/
|
||||||
|
class ValueEditor : public virtual ValueViewer {
|
||||||
|
public:
|
||||||
|
/// Construct a ValueEditor, set the value at a later time
|
||||||
|
ValueEditor(DataEditor& parent, const StyleP& style);
|
||||||
|
|
||||||
|
// --------------------------------------------------- : Events
|
||||||
|
|
||||||
|
/// This editor gains focus
|
||||||
|
virtual void onFocus() {}
|
||||||
|
/// This editor loses focus
|
||||||
|
virtual void onLoseFocus() {}
|
||||||
|
|
||||||
|
/// Handle mouse events
|
||||||
|
virtual void onMouseLeftDown (RealPoint pos, wxMouseEvent& ev) {}
|
||||||
|
virtual void onMouseLeftUp (RealPoint pos, wxMouseEvent& ev) {}
|
||||||
|
virtual void onMouseDClick (RealPoint pos, wxMouseEvent& ev) {}
|
||||||
|
virtual void onMouseRightDown(RealPoint pos, wxMouseEvent& ev) {}
|
||||||
|
virtual void onMouseMove (RealPoint pos, wxMouseEvent& ev) {}
|
||||||
|
virtual void onMouseWheel (RealPoint pos, wxMouseEvent& ev) {}
|
||||||
|
|
||||||
|
/// Key events
|
||||||
|
virtual void onChar(wxKeyEvent ev);
|
||||||
|
|
||||||
|
/// A menu item was selected
|
||||||
|
virtual void onMenu(wxCommandEvent& ev) { ev.Skip(); }
|
||||||
|
/// a context menu is requested, add extra items to the menu m
|
||||||
|
/** return false to suppress menu */
|
||||||
|
virtual bool onContextMenu(wxMenu& m, wxContextMenuEvent& ev) { return true; }
|
||||||
|
|
||||||
|
// --------------------------------------------------- : Clipboard
|
||||||
|
|
||||||
|
/// This editor can be copied from right now
|
||||||
|
virtual bool canCopy() const { return false; }
|
||||||
|
/// This editor can be cut from right now
|
||||||
|
virtual bool canCut() const { return canCopy(); }
|
||||||
|
/// This editor can be pasted to right now
|
||||||
|
/** this function should also check the data on the clipboard has the right format */
|
||||||
|
virtual bool canPaste() const { return false; }
|
||||||
|
// Copies from this field editor, returns success
|
||||||
|
virtual bool doCopy() { return false; }
|
||||||
|
// Deletes the selection from this field editor, cut = copy + delete, returns success
|
||||||
|
virtual bool doDelete() { return false; }
|
||||||
|
// Cuts the selection from this field editor
|
||||||
|
bool doCut() { return doCopy() && doDelete(); }
|
||||||
|
/// Initiate pasting in this field editor,
|
||||||
|
/** should again check if pasting is possible and fail silently if not, returns success */
|
||||||
|
virtual bool doPaste() { return false; }
|
||||||
|
|
||||||
|
// --------------------------------------------------- : Formating
|
||||||
|
|
||||||
|
/// Is the given type of formatting change supported?
|
||||||
|
virtual bool canFormat(int type) const { return false; }
|
||||||
|
/// Is the given type of formatting enabled for the current selection?
|
||||||
|
virtual bool hasFormat(int type) const { return false; }
|
||||||
|
/// Toggle the given type of formatting for the current selection
|
||||||
|
virtual void doFormat(int type) { assert(false); }
|
||||||
|
|
||||||
|
// --------------------------------------------------- : Selection
|
||||||
|
|
||||||
|
/// Select the specified range (if it makes sense)
|
||||||
|
virtual void select(size_t start, size_t end) {}
|
||||||
|
/// Determine the selected range
|
||||||
|
virtual size_t selectionStart() const { return 0; }
|
||||||
|
virtual size_t selectionEnd() const { return 0; }
|
||||||
|
|
||||||
|
// --------------------------------------------------- : Other
|
||||||
|
|
||||||
|
/// The cursor type to use when the mouse is over this control
|
||||||
|
virtual wxCursor cursor() const { return wxCursor(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
|
#endif
|
||||||
+18
-4
@@ -374,18 +374,36 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\gui\control\card_list.hpp">
|
RelativePath=".\gui\control\card_list.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\gui\control\card_list_column_select.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\gui\control\card_list_column_select.hpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\gui\control\card_viewer.cpp">
|
RelativePath=".\gui\control\card_viewer.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\gui\control\card_viewer.hpp">
|
RelativePath=".\gui\control\card_viewer.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\gui\control\filtered_card_list.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\gui\control\filtered_card_list.hpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\gui\control\gallery_list.cpp">
|
RelativePath=".\gui\control\gallery_list.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\gui\control\gallery_list.hpp">
|
RelativePath=".\gui\control\gallery_list.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\gui\control\graph.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\gui\control\graph.hpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\gui\control\package_list.cpp">
|
RelativePath=".\gui\control\package_list.cpp">
|
||||||
</File>
|
</File>
|
||||||
@@ -393,10 +411,6 @@
|
|||||||
RelativePath=".\gui\control\package_list.hpp">
|
RelativePath=".\gui\control\package_list.hpp">
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
|
||||||
Name="editor"
|
|
||||||
Filter="">
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
<Filter
|
||||||
Name="symbol"
|
Name="symbol"
|
||||||
Filter="">
|
Filter="">
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ class DataViewer : public SetView {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
vector<ValueViewerP> viewers; ///< The viewers for the different values in the data
|
vector<ValueViewerP> viewers; ///< The viewers for the different values in the data
|
||||||
|
protected:
|
||||||
CardP card; ///< The card that is currently displayed, if any
|
CardP card; ///< The card that is currently displayed, if any
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+14
-25
@@ -14,12 +14,15 @@ DECLARE_TYPEOF_COLLECTION(TextElementP);
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : TextElements
|
// ----------------------------------------------------------------------------- : TextElements
|
||||||
|
|
||||||
void TextElements::draw(RotatedDC& dc, double scale, const RealRect& rect, DrawWhat what, size_t start, size_t end) const {
|
void TextElements::draw(RotatedDC& dc, double scale, const RealRect& rect, double* xs, DrawWhat what, size_t start, size_t end) const {
|
||||||
FOR_EACH_CONST(e, elements) {
|
FOR_EACH_CONST(e, elements) {
|
||||||
size_t start_ = max(start, e->start);
|
size_t start_ = max(start, e->start);
|
||||||
size_t end_ = min(end, e->end);
|
size_t end_ = min(end, e->end);
|
||||||
if (start_ < end_) {
|
if (start_ < end_) {
|
||||||
e->draw(dc, scale, rect, what, start_, end_);
|
e->draw(dc, scale,
|
||||||
|
RealRect(rect.position.x + xs[start_-start], rect.position.y,
|
||||||
|
xs[end_-start] - xs[start_-start], rect.size.height),
|
||||||
|
xs + start_ - start, what, start_, end_);
|
||||||
}
|
}
|
||||||
if (end <= e->end) return; // nothing can be after this
|
if (end <= e->end) return; // nothing can be after this
|
||||||
}
|
}
|
||||||
@@ -28,38 +31,24 @@ void TextElements::draw(RotatedDC& dc, double scale, const RealRect& rect, DrawW
|
|||||||
void TextElements::getCharInfo(RotatedDC& dc, double scale, size_t start, size_t end, vector<CharInfo>& out) const {
|
void TextElements::getCharInfo(RotatedDC& dc, double scale, size_t start, size_t end, vector<CharInfo>& out) const {
|
||||||
FOR_EACH_CONST(e, elements) {
|
FOR_EACH_CONST(e, elements) {
|
||||||
// characters before this element, after the previous
|
// characters before this element, after the previous
|
||||||
for (size_t i = start ; i < e->start ; ++i) {
|
while (start + out.size() < e->start) {
|
||||||
out.push_back(CharInfo(RealSize(0,0), BREAK_NO));
|
out.push_back(CharInfo(RealSize(0,0), BREAK_NO));
|
||||||
}
|
}
|
||||||
e->getCharInfo(dc, scale, out);
|
e->getCharInfo(dc, scale, out);
|
||||||
start = min(end, e->end);
|
|
||||||
}
|
}
|
||||||
for (size_t i = start ; i < end ; ++i) {
|
while (start + out.size() < end) {
|
||||||
out.push_back(CharInfo(RealSize(0,0), BREAK_NO));
|
out.push_back(CharInfo(RealSize(0,0), BREAK_NO));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*//@@
|
double TextElements::minScale() const {
|
||||||
RealSize TextElements::charSize(const Rotation& rot, double scale, size_t index) const {
|
double m = 0.0001;
|
||||||
vector<TextElementP>::const_iterator e = findByIndex(index);
|
FOR_EACH_CONST(e, elements) {
|
||||||
if (e != elements.end()) {
|
m = max(m, e->minScale());
|
||||||
return (*e)->charSize(rot, scale, index);
|
|
||||||
} else {
|
|
||||||
return RealSize(0,0);
|
|
||||||
}
|
}
|
||||||
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ends_before_index(const TextElementP& e, size_t index) {
|
|
||||||
return index < e->end;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<TextElementP>::const_iterator TextElements::findByIndex(size_t index) const {
|
|
||||||
// Note: slightly abusing lower_bound, since typeof(index) != elements.element_type
|
|
||||||
vector<TextElementP>::const_iterator it = lower_bound(elements.begin(), elements.end(), index, ends_before_index);
|
|
||||||
if ((*it)->start <= index && (*it)->end > index) return it;
|
|
||||||
else return elements.end();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Helper class for TextElements::fromString, to allow persistent formating state accross recusive calls
|
// Helper class for TextElements::fromString, to allow persistent formating state accross recusive calls
|
||||||
struct TextElementsFromString {
|
struct TextElementsFromString {
|
||||||
// What formatting is enabled?
|
// What formatting is enabled?
|
||||||
@@ -114,8 +103,8 @@ struct TextElementsFromString {
|
|||||||
e->end = pos + 1; // just move the end, no need to make a new element
|
e->end = pos + 1; // just move the end, no need to make a new element
|
||||||
} else {
|
} else {
|
||||||
// add a new element for this text
|
// add a new element for this text
|
||||||
if (symbol > 0) {
|
if (symbol > 0 && style.symbol_font.valid()) {
|
||||||
te.elements.push_back(new_shared3<SymbolTextElement>(text, pos, pos + 1));
|
te.elements.push_back(new_shared4<SymbolTextElement>(text, pos, pos + 1, style.symbol_font));
|
||||||
} else {
|
} else {
|
||||||
te.elements.push_back(new_shared4<FontTextElement> (text, pos, pos + 1, style.font.make(bold > 0, italic > 0)));
|
te.elements.push_back(new_shared4<FontTextElement> (text, pos, pos + 1, style.font.make(bold > 0, italic > 0)));
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-14
@@ -17,6 +17,7 @@ DECLARE_POINTER_TYPE(TextElement);
|
|||||||
DECLARE_POINTER_TYPE(Font);
|
DECLARE_POINTER_TYPE(Font);
|
||||||
class TextStyle;
|
class TextStyle;
|
||||||
class Context;
|
class Context;
|
||||||
|
class SymbolFontRef;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : TextElement
|
// ----------------------------------------------------------------------------- : TextElement
|
||||||
|
|
||||||
@@ -56,14 +57,13 @@ class TextElement {
|
|||||||
virtual ~TextElement() {}
|
virtual ~TextElement() {}
|
||||||
|
|
||||||
/// Draw a subsection section of the text in the given rectangle
|
/// Draw a subsection section of the text in the given rectangle
|
||||||
/** this->start <= start < end <= this->end <= text.size() */
|
/** xs give the x coordinates for each character
|
||||||
virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, DrawWhat what, size_t start, size_t end) const = 0;
|
* this->start <= start < end <= this->end <= text.size() */
|
||||||
// /// The size of a single character at position index
|
virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, double* xs, DrawWhat what, size_t start, size_t end) const = 0;
|
||||||
// /** index is in the range [start..end) */
|
|
||||||
// virtual RealSize charSize(const Rotation& rot, double scale, size_t index) const = 0;
|
|
||||||
/// Get information on all characters in the range [start...end) and store them in out
|
/// Get information on all characters in the range [start...end) and store them in out
|
||||||
virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const = 0;
|
virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const = 0;
|
||||||
|
/// Return the minimum scale factor allowed (starts at 1)
|
||||||
|
virtual double minScale() const = 0;
|
||||||
/*
|
/*
|
||||||
// draw the section <start...end)
|
// draw the section <start...end)
|
||||||
// drawSeparators indicates what we should draw, separators or normal text
|
// drawSeparators indicates what we should draw, separators or normal text
|
||||||
@@ -96,10 +96,11 @@ class TextElement {
|
|||||||
class TextElements : public vector<TextElementP> {
|
class TextElements : public vector<TextElementP> {
|
||||||
public:
|
public:
|
||||||
/// Draw all the elements (as need to show the range start..end)
|
/// Draw all the elements (as need to show the range start..end)
|
||||||
void draw (RotatedDC& dc, double scale, const RealRect& rect, DrawWhat what, size_t start, size_t end) const;
|
void draw (RotatedDC& dc, double scale, const RealRect& rect, double* xs, DrawWhat what, size_t start, size_t end) const;
|
||||||
// RealSize charSize(const Rotation& rot, double scale, size_t index) const;
|
|
||||||
// Get information on all characters in the range [start...end) and store them in out
|
// Get information on all characters in the range [start...end) and store them in out
|
||||||
void getCharInfo(RotatedDC& dc, double scale, size_t start, size_t end, vector<CharInfo>& out) const;
|
void getCharInfo(RotatedDC& dc, double scale, size_t start, size_t end, vector<CharInfo>& out) const;
|
||||||
|
/// Return the minimum scale factor allowed by all elements
|
||||||
|
double minScale() const;
|
||||||
|
|
||||||
/// The actual elements
|
/// The actual elements
|
||||||
/** They must be in order of positions and not overlap, i.e.
|
/** They must be in order of positions and not overlap, i.e.
|
||||||
@@ -130,8 +131,9 @@ class FontTextElement : public SimpleTextElement {
|
|||||||
, font(font)
|
, font(font)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, DrawWhat what, size_t start, size_t end) const;
|
virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, double* xs, DrawWhat what, size_t start, size_t end) const;
|
||||||
virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const;
|
virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const;
|
||||||
|
virtual double minScale() const;
|
||||||
private:
|
private:
|
||||||
FontP font;
|
FontP font;
|
||||||
DrawWhat draw_as;
|
DrawWhat draw_as;
|
||||||
@@ -140,10 +142,16 @@ class FontTextElement : public SimpleTextElement {
|
|||||||
/// A text element that uses a symbol font
|
/// A text element that uses a symbol font
|
||||||
class SymbolTextElement : public SimpleTextElement {
|
class SymbolTextElement : public SimpleTextElement {
|
||||||
public:
|
public:
|
||||||
SymbolTextElement(const String& text, size_t start ,size_t end) : SimpleTextElement(text, start, end) {}
|
SymbolTextElement(const String& text, size_t start ,size_t end, const SymbolFontRef& font)
|
||||||
|
: SimpleTextElement(text, start, end)
|
||||||
|
, font(font)
|
||||||
|
{}
|
||||||
|
|
||||||
virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, DrawWhat what, size_t start, size_t end) const;
|
virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, double* xs, DrawWhat what, size_t start, size_t end) const;
|
||||||
virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const;
|
virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const;
|
||||||
|
virtual double minScale() const;
|
||||||
|
private:
|
||||||
|
const SymbolFontRef& font; // owned by TextStyle
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : CompoundTextElement
|
// ----------------------------------------------------------------------------- : CompoundTextElement
|
||||||
@@ -163,8 +171,9 @@ class HorizontalLineTextElement : public TextElement {
|
|||||||
public:
|
public:
|
||||||
HorizontalLineTextElement(const String& text, size_t start ,size_t end) : TextElement(text, start, end) {}
|
HorizontalLineTextElement(const String& text, size_t start ,size_t end) : TextElement(text, start, end) {}
|
||||||
|
|
||||||
virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, DrawWhat what, size_t start, size_t end) const;
|
virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, double* xs, DrawWhat what, size_t start, size_t end) const;
|
||||||
virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const;
|
virtual void getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const;
|
||||||
|
virtual double minScale() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -175,8 +184,8 @@ class CompoundTextElement : public TextElement {
|
|||||||
public:
|
public:
|
||||||
CompoundTextElement(const String& text, size_t start ,size_t end) : TextElement(text, start, end) {}
|
CompoundTextElement(const String& text, size_t start ,size_t end) : TextElement(text, start, end) {}
|
||||||
|
|
||||||
virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, DrawWhat what, size_t start, size_t end) const;
|
virtual void draw (RotatedDC& dc, double scale, const RealRect& rect, double* xs, DrawWhat what, size_t start, size_t end) const;
|
||||||
virtual RealSize charSize(RotatedDC& dc, double scale, size_t index) const;
|
virtual RealSize charSize(RotatedDC& dc, double scale, size_t index) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextElements elements;
|
TextElements elements;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : FontTextElement
|
// ----------------------------------------------------------------------------- : FontTextElement
|
||||||
|
|
||||||
void FontTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, DrawWhat what, size_t start, size_t end) const {
|
void FontTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, double* xs, DrawWhat what, size_t start, size_t end) const {
|
||||||
dc.SetFont(font->font, font->size * scale);
|
dc.SetFont(font->font, font->size * scale);
|
||||||
|
|
||||||
if (end != start && text.substr(end-1, 1) == _("\n")) end -= 1; // don't draw the newline character at the end
|
if (end != start && text.substr(end-1, 1) == _("\n")) end -= 1; // don't draw the newline character at the end
|
||||||
@@ -42,7 +42,7 @@ void FontTextElement::getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>&
|
|||||||
double prev_width = 0;
|
double prev_width = 0;
|
||||||
for (size_t i = start ; i < end ; ++i) {
|
for (size_t i = start ; i < end ; ++i) {
|
||||||
Char c = text.GetChar(i);
|
Char c = text.GetChar(i);
|
||||||
RealSize s = dc.GetTextExtent(text.substr(start, i - start));
|
RealSize s = dc.GetTextExtent(text.substr(start, i - start + 1));
|
||||||
out.push_back(CharInfo(RealSize(s.width - prev_width, s.height),
|
out.push_back(CharInfo(RealSize(s.width - prev_width, s.height),
|
||||||
c == _('\n') ? BREAK_HARD :
|
c == _('\n') ? BREAK_HARD :
|
||||||
c == _(' ') ? BREAK_SOFT : BREAK_NO
|
c == _(' ') ? BREAK_SOFT : BREAK_NO
|
||||||
@@ -50,3 +50,7 @@ void FontTextElement::getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>&
|
|||||||
prev_width = s.width;
|
prev_width = s.width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double FontTextElement::minScale() const {
|
||||||
|
return 1; // TODO
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,10 +10,15 @@
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : HorizontalLineTextElement
|
// ----------------------------------------------------------------------------- : HorizontalLineTextElement
|
||||||
|
|
||||||
void HorizontalLineTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, DrawWhat what, size_t start, size_t end) const {
|
void HorizontalLineTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, double* xs, DrawWhat what, size_t start, size_t end) const {
|
||||||
// TODO
|
// handled by TextViewer
|
||||||
}
|
}
|
||||||
|
|
||||||
void HorizontalLineTextElement::getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const {
|
void HorizontalLineTextElement::getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const {
|
||||||
// TODO
|
out.push_back(CharInfo(RealSize(0,0), BREAK_LINE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double HorizontalLineTextElement::minScale() const {
|
||||||
|
return 0; // we don't care about scaling
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,14 @@
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : SymbolTextElement
|
// ----------------------------------------------------------------------------- : SymbolTextElement
|
||||||
|
|
||||||
void SymbolTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, DrawWhat what, size_t start, size_t end) const {
|
void SymbolTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, double* xs, DrawWhat what, size_t start, size_t end) const {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolTextElement::getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const {
|
void SymbolTextElement::getCharInfo(RotatedDC& dc, double scale, vector<CharInfo>& out) const {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double SymbolTextElement::minScale() const {
|
||||||
|
return 1; // TODO
|
||||||
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ void TextViewer::draw(RotatedDC& dc, const String& text, const TextStyle& style,
|
|||||||
FOR_EACH(l, lines) {
|
FOR_EACH(l, lines) {
|
||||||
if (l.visible(dc)) {
|
if (l.visible(dc)) {
|
||||||
RealRect rect(l.positions.front(), l.top, l.width(), l.line_height);
|
RealRect rect(l.positions.front(), l.top, l.width(), l.line_height);
|
||||||
elements.draw(dc, scale, rect, what, l.start, l.end());
|
elements.draw(dc, scale, rect, &*l.positions.begin(), what, l.start, l.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user