mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 21:06:59 -04:00
Conversion to new ScriptableImage complete, this affected quite a bit, including the evil thumbnail thread;
Added StyleListener, so style changes are only propagated to interested viewers. git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@329 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
#include <data/field/information.hpp>
|
||||
#include <util/error.hpp>
|
||||
|
||||
DECLARE_TYPEOF_COLLECTION(StyleListener*);
|
||||
|
||||
// ----------------------------------------------------------------------------- : Field
|
||||
|
||||
Field::Field()
|
||||
@@ -120,6 +122,35 @@ void Style::initDependencies(Context& ctx, const Dependency& dep) const {
|
||||
// visible.initDependencies(ctx,dep);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : StyleListener
|
||||
|
||||
void Style::addListener(StyleListener* listener) {
|
||||
listeners.push_back(listener);
|
||||
}
|
||||
void Style::removeListener(StyleListener* listener) {
|
||||
listeners.erase(
|
||||
std::remove(
|
||||
listeners.begin(),
|
||||
listeners.end(),
|
||||
listener
|
||||
),
|
||||
listeners.end()
|
||||
);
|
||||
}
|
||||
void Style::tellListeners() {
|
||||
FOR_EACH(l, listeners) l->onStyleChange();
|
||||
}
|
||||
|
||||
StyleListener::StyleListener(const StyleP& style)
|
||||
: styleP(style)
|
||||
{
|
||||
style->addListener(this);
|
||||
}
|
||||
StyleListener::~StyleListener() {
|
||||
styleP->removeListener(this);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- : Value
|
||||
|
||||
Value::~Value() {}
|
||||
|
||||
+27
-2
@@ -22,6 +22,7 @@ DECLARE_POINTER_TYPE(Value);
|
||||
class Context;
|
||||
class Dependency;
|
||||
class Action;
|
||||
class StyleListener;
|
||||
|
||||
// for DataViewer/editor
|
||||
class DataViewer; class DataEditor;
|
||||
@@ -103,16 +104,26 @@ class Style {
|
||||
/** thisP is a smart pointer to this */
|
||||
virtual ValueViewerP makeEditor(DataEditor& parent, const StyleP& thisP) = 0;
|
||||
|
||||
/// Update scripted values of this style, return true if anything has changed
|
||||
/// Update scripted values of this style, return true if anything has changed.
|
||||
/** The caller should tellListeners() */
|
||||
virtual bool update(Context&);
|
||||
/// Add the given dependency to the dependent_scripts list for the variables this style depends on
|
||||
/** Only use for things that need invalidate() */
|
||||
virtual void initDependencies(Context&, const Dependency&) const;
|
||||
/// Invalidate scripted images for this style
|
||||
virtual void invalidate() {}
|
||||
virtual void invalidate(Context&) {}
|
||||
|
||||
/// Add a StyleListener
|
||||
void addListener(StyleListener*);
|
||||
/// Remove a StyleListener
|
||||
void removeListener(StyleListener*);
|
||||
/// Tell the StyleListeners that this style has changed
|
||||
void tellListeners();
|
||||
|
||||
private:
|
||||
DECLARE_REFLECTION_VIRTUAL();
|
||||
/// Things that are listening to changes in this style
|
||||
vector<StyleListener*> listeners;
|
||||
};
|
||||
|
||||
void init_object(const FieldP&, StyleP&);
|
||||
@@ -120,6 +131,20 @@ inline const FieldP& get_key (const StyleP& s) { return s->fieldP; }
|
||||
inline const String& get_key_name(const StyleP& s) { return s->fieldP->name; }
|
||||
template <> StyleP read_new<Style>(Reader&);
|
||||
|
||||
// ----------------------------------------------------------------------------- : StyleListener
|
||||
|
||||
/// An object that can respond when a style changes;
|
||||
class StyleListener {
|
||||
public:
|
||||
StyleListener(const StyleP& style);
|
||||
virtual ~StyleListener();
|
||||
|
||||
/// Called when a (scripted) property of the viewed style has changed
|
||||
virtual void onStyleChange() {}
|
||||
protected:
|
||||
const StyleP styleP; ///< The style we are listening to
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Value
|
||||
|
||||
/// A specific value 'in' a Field.
|
||||
|
||||
@@ -35,8 +35,10 @@ BooleanStyle::BooleanStyle(const ChoiceFieldP& field)
|
||||
: ChoiceStyle(field)
|
||||
{
|
||||
render_style = RENDER_BOTH;
|
||||
choice_images[_("yes")] = ScriptableImage(_("buildin_image(\"bool_yes\")"));
|
||||
choice_images[_("no")] = ScriptableImage(_("buildin_image(\"bool_no\")"));
|
||||
//%%choice_images[_("yes")] = ScriptableImage(_("buildin_image(\"bool_yes\")"));
|
||||
//%%choice_images[_("no")] = ScriptableImage(_("buildin_image(\"bool_no\")"));
|
||||
choice_images[_("yes")] = ScriptableImage(new_intrusive1<BuiltInImage>(_("bool_yes")));
|
||||
choice_images[_("no")] = ScriptableImage(new_intrusive1<BuiltInImage>(_("bool_no")));
|
||||
}
|
||||
|
||||
IMPLEMENT_REFLECTION(BooleanStyle) {
|
||||
|
||||
+23
-14
@@ -167,8 +167,6 @@ ChoiceStyle::ChoiceStyle(const ChoiceFieldP& field)
|
||||
, alignment(ALIGN_STRETCH)
|
||||
, angle(0)
|
||||
, thumbnails(nullptr)
|
||||
, thumbnail_age(1) // thumbnails were made before the beginning of time
|
||||
, invalidated_images(false)
|
||||
{}
|
||||
|
||||
ChoiceStyle::~ChoiceStyle() {
|
||||
@@ -178,8 +176,15 @@ ChoiceStyle::~ChoiceStyle() {
|
||||
|
||||
bool ChoiceStyle::update(Context& ctx) {
|
||||
// Don't update the choice images, leave that to invalidate()
|
||||
return Style ::update(ctx)
|
||||
| mask_filename.update(ctx);
|
||||
bool change = Style ::update(ctx)
|
||||
| mask_filename.update(ctx);
|
||||
FOR_EACH(ci, choice_images) {
|
||||
if (ci.second.update(ctx)) {
|
||||
change = true;
|
||||
// TODO : remove this thumbnail
|
||||
}
|
||||
}
|
||||
return change;
|
||||
}
|
||||
void ChoiceStyle::initDependencies(Context& ctx, const Dependency& dep) const {
|
||||
Style::initDependencies(ctx, dep);
|
||||
@@ -187,17 +192,21 @@ void ChoiceStyle::initDependencies(Context& ctx, const Dependency& dep) const {
|
||||
ci.second.initDependencies(ctx, dep);
|
||||
}
|
||||
}
|
||||
void ChoiceStyle::invalidate() {
|
||||
// rebuild choice images
|
||||
// TODO: Don't use this; rely on upToDate() instead
|
||||
FOR_EACH(ci, choice_images) {
|
||||
// TODO : only invalidate images that actually have dependencies
|
||||
ci.second.invalidate();
|
||||
void ChoiceStyle::invalidate(Context& ctx) {
|
||||
// TODO : this is also done in update(), once should be enough
|
||||
// Update choice images and thumbnails
|
||||
bool change = false;
|
||||
int end = field().choices->lastId();
|
||||
thumbnails_status.resize(end, THUMB_NOT_MADE);
|
||||
for (int i = 0 ; i < end ; ++i) {
|
||||
String name = cannocial_name_form(field().choices->choiceName(i));
|
||||
ScriptableImage& img = choice_images[name];
|
||||
if (img.update(ctx)) {
|
||||
change = true;
|
||||
thumbnails_status[i] = THUMB_CHANGED;
|
||||
}
|
||||
}
|
||||
if (thumbnails) {
|
||||
thumbnails->RemoveAll();
|
||||
}
|
||||
invalidated_images = true;
|
||||
if (change) tellListeners();
|
||||
}
|
||||
|
||||
void ChoiceStyle::loadMask(Package& pkg) {
|
||||
|
||||
@@ -114,6 +114,12 @@ enum ChoiceRenderStyle
|
||||
, RENDER_BOTH_CHECKLIST = RENDER_CHECKLIST | RENDER_BOTH
|
||||
};
|
||||
|
||||
enum ThumbnailStatus
|
||||
{ THUMB_NOT_MADE
|
||||
, THUMB_OK
|
||||
, THUMB_CHANGED
|
||||
};
|
||||
|
||||
/// The Style for a ChoiceField
|
||||
class ChoiceStyle : public Style {
|
||||
public:
|
||||
@@ -133,15 +139,14 @@ class ChoiceStyle : public Style {
|
||||
Image mask; ///< The actual mask image
|
||||
int angle; ///< Angle by which the images are rotated
|
||||
wxImageList* thumbnails; ///< Thumbnails for the choices
|
||||
Age thumbnail_age; ///< Age the thumbnails were generated
|
||||
bool invalidated_images; ///< Have the images been invalidated?
|
||||
vector<ThumbnailStatus> thumbnails_status; ///< Which thumbnails are up to date?
|
||||
|
||||
/// Load the mask image, if it's not already done
|
||||
void loadMask(Package& pkg);
|
||||
|
||||
virtual bool update(Context&);
|
||||
virtual void initDependencies(Context&, const Dependency&) const;
|
||||
virtual void invalidate();
|
||||
virtual void invalidate(Context&);
|
||||
|
||||
private:
|
||||
DECLARE_REFLECTION();
|
||||
|
||||
@@ -39,7 +39,7 @@ class ImageStyle : public Style {
|
||||
DECLARE_STYLE_TYPE(Image);
|
||||
|
||||
Scriptable<String> mask_filename; ///< Filename for a mask image
|
||||
ScriptableImage2 default_image; ///< Placeholder
|
||||
ScriptableImage default_image; ///< Placeholder
|
||||
|
||||
virtual bool update(Context&);
|
||||
|
||||
|
||||
+40
-43
@@ -75,14 +75,14 @@ class SymbolInFont {
|
||||
SymbolInFont();
|
||||
|
||||
/// Get a shrunk, zoomed bitmap
|
||||
Bitmap getBitmap(Context& ctx, Package& pkg, double size);
|
||||
Bitmap getBitmap(Package& pkg, double size);
|
||||
|
||||
/// Get a bitmap with the given size
|
||||
Bitmap getBitmap(Context& ctx, Package& pkg, wxSize size);
|
||||
Bitmap getBitmap(Package& pkg, wxSize 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, Package& pkg, double size);
|
||||
RealSize size(Package& pkg, double size);
|
||||
|
||||
void update(Context& ctx);
|
||||
|
||||
@@ -107,15 +107,15 @@ SymbolInFont::SymbolInFont()
|
||||
if (img_size <= 0) img_size = 1;
|
||||
}
|
||||
|
||||
Bitmap SymbolInFont::getBitmap(Context& ctx, Package& pkg, double size) {
|
||||
Bitmap SymbolInFont::getBitmap(Package& pkg, double size) {
|
||||
// is this bitmap already loaded/generated?
|
||||
Bitmap& bmp = bitmaps[size];
|
||||
if (!bmp.Ok()) {
|
||||
// generate new bitmap
|
||||
if (!image) {
|
||||
if (!image.isReady()) {
|
||||
throw Error(_("No image specified for symbol with code '") + code + _("' in symbol font."));
|
||||
}
|
||||
Image img = image.generate(ctx, pkg)->image;
|
||||
Image img = image.generate(GeneratedImage::Options(0, 0, &pkg));
|
||||
actual_size = wxSize(img.GetWidth(), img.GetHeight());
|
||||
// scale to match expected size
|
||||
Image resampled_image((int) (actual_size.GetWidth() * size / img_size),
|
||||
@@ -127,28 +127,24 @@ Bitmap SymbolInFont::getBitmap(Context& ctx, Package& pkg, double size) {
|
||||
}
|
||||
return bmp;
|
||||
}
|
||||
Bitmap SymbolInFont::getBitmap(Context& ctx, Package& pkg, wxSize size) {
|
||||
Bitmap SymbolInFont::getBitmap(Package& pkg, wxSize size) {
|
||||
// generate new bitmap
|
||||
if (!image) {
|
||||
if (!image.isReady()) {
|
||||
throw Error(_("No image specified for symbol with code '") + code + _("' in symbol font."));
|
||||
}
|
||||
Image img = image.generate(ctx, pkg)->image;
|
||||
actual_size = wxSize(img.GetWidth(), img.GetHeight());
|
||||
// scale to match expected size
|
||||
Image resampled_image(size.GetWidth(), size.GetHeight(), false);
|
||||
resample_preserve_aspect(img, resampled_image);
|
||||
return Bitmap(resampled_image);
|
||||
return Bitmap( image.generate(GeneratedImage::Options(size.x, size.y, &pkg, nullptr, ASPECT_BORDER)) );
|
||||
}
|
||||
|
||||
RealSize SymbolInFont::size(Context& ctx, Package& pkg, double size) {
|
||||
RealSize SymbolInFont::size(Package& pkg, double size) {
|
||||
if (actual_size.GetWidth() == 0) {
|
||||
// we don't know what size the image will be
|
||||
getBitmap(ctx, pkg, size);
|
||||
getBitmap(pkg, size);
|
||||
}
|
||||
return wxSize(actual_size * (int) (size) / (int) (img_size));
|
||||
}
|
||||
|
||||
void SymbolInFont::update(Context& ctx) {
|
||||
image.update(ctx);
|
||||
enabled.update(ctx);
|
||||
}
|
||||
void SymbolFont::update(Context& ctx) const {
|
||||
@@ -180,8 +176,7 @@ class SymbolFont::DrawableSymbol {
|
||||
SymbolInFont* symbol; ///< Symbol to draw, if nullptr, use the default symbol and draw the text
|
||||
};
|
||||
|
||||
void SymbolFont::split(const String& text, Context& ctx, SplitSymbols& out) const {
|
||||
update(ctx);
|
||||
void SymbolFont::split(const String& text, SplitSymbols& out) const {
|
||||
// read a single symbol until we are done with the text
|
||||
for (size_t pos = 0 ; pos < text.size() ; ) {
|
||||
// 1. check merged numbers
|
||||
@@ -220,37 +215,38 @@ SymbolInFont* SymbolFont::defaultSymbol() const {
|
||||
|
||||
void SymbolFont::draw(RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, const String& text) {
|
||||
SplitSymbols symbols;
|
||||
split(text, ctx, symbols);
|
||||
draw(dc, ctx, rect, font_size, align, symbols);
|
||||
update(ctx);
|
||||
split(text, symbols);
|
||||
draw(dc, rect, font_size, align, symbols);
|
||||
}
|
||||
|
||||
void SymbolFont::draw(RotatedDC& dc, Context& ctx, RealRect rect, double font_size, const Alignment& align, const SplitSymbols& text) {
|
||||
void SymbolFont::draw(RotatedDC& dc, RealRect rect, double font_size, const Alignment& align, const SplitSymbols& text) {
|
||||
FOR_EACH_CONST(sym, text) {
|
||||
RealSize size = dc.trInvS(symbolSize(ctx, dc.trS(font_size), sym));
|
||||
RealSize size = dc.trInvS(symbolSize(dc.trS(font_size), sym));
|
||||
RealRect sym_rect = split_left(rect, size);
|
||||
if (sym.symbol) {
|
||||
drawSymbol( dc, ctx, sym_rect, font_size, align, *sym.symbol);
|
||||
drawSymbol( dc, sym_rect, font_size, align, *sym.symbol);
|
||||
} else {
|
||||
drawWithText(dc, ctx, sym_rect, font_size, align, sym.text);
|
||||
drawWithText(dc, sym_rect, font_size, align, sym.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolFont::drawSymbol (RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, SymbolInFont& sym) {
|
||||
void SymbolFont::drawSymbol (RotatedDC& dc, const RealRect& rect, double font_size, const Alignment& align, SymbolInFont& sym) {
|
||||
// find bitmap
|
||||
Bitmap bmp = sym.getBitmap(ctx, *this, dc.trS(font_size));
|
||||
Bitmap bmp = sym.getBitmap(*this, dc.trS(font_size));
|
||||
// draw aligned in the rectangle
|
||||
dc.DrawBitmap(bmp, align_in_rect(align, dc.trInvS(RealSize(bmp.GetWidth(), bmp.GetHeight())), rect));
|
||||
}
|
||||
|
||||
void SymbolFont::drawWithText(RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, const String& text) {
|
||||
void SymbolFont::drawWithText(RotatedDC& dc, const RealRect& rect, double font_size, const Alignment& align, const String& text) {
|
||||
// 1. draw background bitmap
|
||||
// Size and position of symbol
|
||||
RealRect sym_rect = rect;
|
||||
// find and draw background bitmap
|
||||
SymbolInFont* def = defaultSymbol();
|
||||
if (def) {
|
||||
Bitmap bmp = def->getBitmap(ctx, *this, dc.trS(font_size));
|
||||
Bitmap bmp = def->getBitmap(*this, dc.trS(font_size));
|
||||
// align symbol
|
||||
sym_rect.size() = dc.trInvS(RealSize(bmp.GetWidth(), bmp.GetHeight()));
|
||||
sym_rect.position() = align_in_rect(align, sym_rect.size(), rect);
|
||||
@@ -295,14 +291,15 @@ void SymbolFont::drawWithText(RotatedDC& dc, Context& ctx, const RealRect& rect,
|
||||
|
||||
void SymbolFont::getCharInfo(RotatedDC& dc, Context& ctx, double font_size, const String& text, vector<CharInfo>& out) {
|
||||
SplitSymbols symbols;
|
||||
split(text, ctx, symbols);
|
||||
getCharInfo(dc, ctx, font_size, symbols, out);
|
||||
update(ctx);
|
||||
split(text, symbols);
|
||||
getCharInfo(dc, font_size, symbols, out);
|
||||
}
|
||||
|
||||
void SymbolFont::getCharInfo(RotatedDC& dc, Context& ctx, double font_size, const SplitSymbols& text, vector<CharInfo>& out) {
|
||||
void SymbolFont::getCharInfo(RotatedDC& dc, double font_size, const SplitSymbols& text, vector<CharInfo>& out) {
|
||||
FOR_EACH_CONST(sym, text) {
|
||||
size_t count = sym.text.size();
|
||||
RealSize size = dc.trInvS(symbolSize(ctx, dc.trS(font_size), sym));
|
||||
RealSize size = dc.trInvS(symbolSize(dc.trS(font_size), sym));
|
||||
size.width /= count; // divide into count parts
|
||||
for (size_t i = 0 ; i < count ; ++i) {
|
||||
out.push_back(CharInfo(size, i == count - 1 ? BREAK_MAYBE : BREAK_NO));
|
||||
@@ -310,18 +307,18 @@ void SymbolFont::getCharInfo(RotatedDC& dc, Context& ctx, double font_size, cons
|
||||
}
|
||||
}
|
||||
|
||||
RealSize SymbolFont::symbolSize(Context& ctx, double font_size, const DrawableSymbol& sym) {
|
||||
RealSize SymbolFont::symbolSize(double font_size, const DrawableSymbol& sym) {
|
||||
if (sym.symbol) {
|
||||
return add_diagonal(sym.symbol->size(ctx, *this, font_size), spacing);
|
||||
return add_diagonal(sym.symbol->size(*this, font_size), spacing);
|
||||
} else {
|
||||
return defaultSymbolSize(ctx, font_size);
|
||||
return defaultSymbolSize(font_size);
|
||||
}
|
||||
}
|
||||
|
||||
RealSize SymbolFont::defaultSymbolSize(Context& ctx, double font_size) {
|
||||
RealSize SymbolFont::defaultSymbolSize(double font_size) {
|
||||
SymbolInFont* def = defaultSymbol();
|
||||
if (def) {
|
||||
return add_diagonal(def->size(ctx, *this, font_size), spacing);
|
||||
return add_diagonal(def->size(*this, font_size), spacing);
|
||||
} else {
|
||||
return add_diagonal(RealSize(1,1), spacing);
|
||||
}
|
||||
@@ -334,7 +331,7 @@ wxMenu* SymbolFont::insertSymbolMenu(Context& ctx) {
|
||||
if (!processed_insert_symbol_menu && insert_symbol_menu) {
|
||||
update(ctx);
|
||||
// Make menu
|
||||
processed_insert_symbol_menu = insert_symbol_menu->makeMenu(ID_INSERT_SYMBOL_MENU_MIN, ctx, *this);
|
||||
processed_insert_symbol_menu = insert_symbol_menu->makeMenu(ID_INSERT_SYMBOL_MENU_MIN, *this);
|
||||
}
|
||||
return processed_insert_symbol_menu;
|
||||
}
|
||||
@@ -384,22 +381,22 @@ String InsertSymbolMenu::getCode(int id, const SymbolFont& font) const {
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
wxMenu* InsertSymbolMenu::makeMenu(int id, Context& ctx, SymbolFont& font) const {
|
||||
wxMenu* InsertSymbolMenu::makeMenu(int id, SymbolFont& font) const {
|
||||
if (type == ITEM_SUBMENU) {
|
||||
wxMenu* menu = new wxMenu();
|
||||
FOR_EACH_CONST(i, items) {
|
||||
menu->Append(i->makeMenuItem(menu, id, ctx, font));
|
||||
menu->Append(i->makeMenuItem(menu, id, font));
|
||||
id += i->size();
|
||||
}
|
||||
return menu;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
wxMenuItem* InsertSymbolMenu::makeMenuItem(wxMenu* parent, int first_id, Context& ctx, SymbolFont& font) const {
|
||||
wxMenuItem* InsertSymbolMenu::makeMenuItem(wxMenu* parent, int first_id, SymbolFont& font) const {
|
||||
if (type == ITEM_SUBMENU) {
|
||||
wxMenuItem* item = new wxMenuItem(parent, wxID_ANY, tr(font, _("menu item ") + name, name),
|
||||
wxEmptyString, wxITEM_NORMAL,
|
||||
makeMenu(first_id, ctx, font));
|
||||
makeMenu(first_id, font));
|
||||
item->SetBitmap(wxNullBitmap);
|
||||
return item;
|
||||
} else if (type == ITEM_LINE) {
|
||||
@@ -420,7 +417,7 @@ wxMenuItem* InsertSymbolMenu::makeMenuItem(wxMenu* parent, int first_id, Context
|
||||
}
|
||||
}
|
||||
if (symbol) {
|
||||
item->SetBitmap(symbol->getBitmap(ctx, font, wxSize(16,16)));
|
||||
item->SetBitmap(symbol->getBitmap(font, wxSize(16,16)));
|
||||
} else {
|
||||
item->SetBitmap(wxNullBitmap);
|
||||
}
|
||||
|
||||
+13
-13
@@ -32,10 +32,13 @@ class SymbolFont : public Packaged {
|
||||
/// Loads the symbol font with a given name, for example "magic-mana-large"
|
||||
static SymbolFontP byName(const String& name);
|
||||
|
||||
// Script update
|
||||
void update(Context& ctx) const;
|
||||
|
||||
class DrawableSymbol;
|
||||
typedef vector<DrawableSymbol> SplitSymbols;
|
||||
/// Split a string into separate symbols for drawing and for determining their size
|
||||
void split(const String& text, Context& ctx, SplitSymbols& out) const;
|
||||
void split(const String& text, SplitSymbols& out) const;
|
||||
|
||||
/// Draw a piece of text prepared using split
|
||||
void draw(RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, const String& text);
|
||||
@@ -43,9 +46,9 @@ class SymbolFont : public Packaged {
|
||||
void getCharInfo(RotatedDC& dc, Context& ctx, double font_size, const String& text, vector<CharInfo>& out);
|
||||
|
||||
/// Draw a piece of text prepared using split
|
||||
void draw(RotatedDC& dc, Context& ctx, RealRect rect, double font_size, const Alignment& align, const SplitSymbols& text);
|
||||
void draw(RotatedDC& dc, RealRect rect, double font_size, const Alignment& align, const SplitSymbols& text);
|
||||
/// Get information on characters in a string
|
||||
void getCharInfo(RotatedDC& dc, Context& ctx, double font_size, const SplitSymbols& text, vector<CharInfo>& out);
|
||||
void getCharInfo(RotatedDC& dc, double font_size, const SplitSymbols& text, vector<CharInfo>& out);
|
||||
|
||||
static String typeNameStatic();
|
||||
virtual String typeName() const;
|
||||
@@ -79,24 +82,21 @@ class SymbolFont : public Packaged {
|
||||
friend class SymbolInFont;
|
||||
friend class InsertSymbolMenu;
|
||||
vector<SymbolInFontP> symbols; ///< The individual symbols
|
||||
|
||||
// Script update
|
||||
void update(Context& ctx) const;
|
||||
|
||||
|
||||
/// Find the default symbol
|
||||
/** may return nullptr */
|
||||
SymbolInFont* defaultSymbol() const;
|
||||
|
||||
/// Draws a single symbol inside the given rectangle
|
||||
void drawSymbol (RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, SymbolInFont& sym);
|
||||
void drawSymbol (RotatedDC& dc, const RealRect& rect, double font_size, const Alignment& align, SymbolInFont& sym);
|
||||
/// Draw the default bitmap to a dc and overlay a string of text
|
||||
void drawWithText(RotatedDC& dc, Context& ctx, const RealRect& rect, double font_size, const Alignment& align, const String& text);
|
||||
void drawWithText(RotatedDC& dc, const RealRect& rect, double font_size, const Alignment& align, const String& text);
|
||||
|
||||
/// Size of a single symbol
|
||||
RealSize symbolSize (Context& ctx, double font_size, const DrawableSymbol& sym);
|
||||
RealSize symbolSize (double font_size, const DrawableSymbol& sym);
|
||||
public:
|
||||
/// Size of the default symbol
|
||||
RealSize defaultSymbolSize(Context& ctx, double font_size);
|
||||
RealSize defaultSymbolSize(double font_size);
|
||||
|
||||
DECLARE_REFLECTION();
|
||||
};
|
||||
@@ -124,9 +124,9 @@ class InsertSymbolMenu {
|
||||
/// Get the code for an item, id relative to the start of this menu
|
||||
String getCode(int id, const SymbolFont& font) const;
|
||||
/// Make an actual menu
|
||||
wxMenu* makeMenu(int first_id, Context& ctx, SymbolFont& font) const;
|
||||
wxMenu* makeMenu(int first_id, SymbolFont& font) const;
|
||||
/// Make an actual menu item
|
||||
wxMenuItem* makeMenuItem(wxMenu* parent, int first_id, Context& ctx, SymbolFont& font) const;
|
||||
wxMenuItem* makeMenuItem(wxMenu* parent, int first_id, SymbolFont& font) const;
|
||||
|
||||
DECLARE_REFLECTION();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user