Change tabs to two spaces.

This commit is contained in:
Lymia Aluysia
2017-01-18 08:43:21 -06:00
parent d7f5f0dc3b
commit d2c635f739
329 changed files with 41307 additions and 41496 deletions
+199 -199
View File
@@ -20,290 +20,290 @@ DECLARE_TYPEOF_COLLECTION(ChoiceField::ChoiceP);
class ChoiceThumbnailRequest : public ThumbnailRequest {
public:
ChoiceThumbnailRequest(ValueViewer* cve, int id, bool from_disk, bool thread_safe);
virtual Image generate();
virtual void store(const Image&);
ChoiceThumbnailRequest(ValueViewer* cve, int id, bool from_disk, bool thread_safe);
virtual Image generate();
virtual void store(const Image&);
bool isThreadSafe;
virtual bool threadSafe() const {return isThreadSafe;}
bool isThreadSafe;
virtual bool threadSafe() const {return isThreadSafe;}
private:
int id;
inline ChoiceStyle& style() { return *static_cast<ChoiceStyle*>(viewer().getStyle().get()); }
inline ValueViewer& viewer() { return *static_cast<ValueViewer*>(owner); }
int id;
inline ChoiceStyle& style() { return *static_cast<ChoiceStyle*>(viewer().getStyle().get()); }
inline ValueViewer& viewer() { return *static_cast<ValueViewer*>(owner); }
};
ChoiceThumbnailRequest::ChoiceThumbnailRequest(ValueViewer* viewer, int id, bool from_disk, bool thread_safe)
: ThumbnailRequest(
static_cast<void*>(viewer),
viewer->getStylePackage().name() + _("/") + viewer->getField()->name + _("/") << id,
from_disk ? viewer->getStylePackage().lastModified()
: wxDateTime::Now()
)
, isThreadSafe(thread_safe)
, id(id)
: ThumbnailRequest(
static_cast<void*>(viewer),
viewer->getStylePackage().name() + _("/") + viewer->getField()->name + _("/") << id,
from_disk ? viewer->getStylePackage().lastModified()
: wxDateTime::Now()
)
, isThreadSafe(thread_safe)
, id(id)
{}
Image ChoiceThumbnailRequest::generate() {
ChoiceStyle& s = style();
String name = canonical_name_form(s.field().choices->choiceName(id));
ScriptableImage& img = s.choice_images[name];
return img.isReady()
? img.generate(GeneratedImage::Options(16,16, &viewer().getStylePackage(), &viewer().getLocalPackage(), ASPECT_BORDER, true))
: wxImage();
ChoiceStyle& s = style();
String name = canonical_name_form(s.field().choices->choiceName(id));
ScriptableImage& img = s.choice_images[name];
return img.isReady()
? img.generate(GeneratedImage::Options(16,16, &viewer().getStylePackage(), &viewer().getLocalPackage(), ASPECT_BORDER, true))
: wxImage();
}
void ChoiceThumbnailRequest::store(const Image& img) {
ChoiceStyle& s = style();
wxImageList* il = s.thumbnails;
while (id > il->GetImageCount()) {
il->Add(wxBitmap(16,16),*wxBLACK);
}
if (img.Ok()) {
#ifdef __WXMSW__
// for some reason windows doesn't like completely transparent images if they do not have a mask
// HACK:
if (img.HasAlpha() && img.GetWidth() == 16 && img.GetHeight() == 16) {
// is the image empty?
bool empty = true;
int* b = (int*)img.GetAlpha();
int* e = b + 16*16/sizeof(int);
while (b != e) {
if (*b++) {
empty = false;
break;
}
}
// if so, use a mask instead
if (empty) {
const_cast<Image&>(img).ConvertAlphaToMask();
}
}
// Hack ends here
#endif
if (id == il->GetImageCount()) {
il->Add(img);
} else {
il->Replace(id, img);
}
s.thumbnails_status[id] = THUMB_OK;
}
ChoiceStyle& s = style();
wxImageList* il = s.thumbnails;
while (id > il->GetImageCount()) {
il->Add(wxBitmap(16,16),*wxBLACK);
}
if (img.Ok()) {
#ifdef __WXMSW__
// for some reason windows doesn't like completely transparent images if they do not have a mask
// HACK:
if (img.HasAlpha() && img.GetWidth() == 16 && img.GetHeight() == 16) {
// is the image empty?
bool empty = true;
int* b = (int*)img.GetAlpha();
int* e = b + 16*16/sizeof(int);
while (b != e) {
if (*b++) {
empty = false;
break;
}
}
// if so, use a mask instead
if (empty) {
const_cast<Image&>(img).ConvertAlphaToMask();
}
}
// Hack ends here
#endif
if (id == il->GetImageCount()) {
il->Add(img);
} else {
il->Replace(id, img);
}
s.thumbnails_status[id] = THUMB_OK;
}
}
// ----------------------------------------------------------------------------- : DropDownChoiceListBase
DropDownChoiceListBase::DropDownChoiceListBase
(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group)
: DropDownList(parent, is_submenu, is_submenu ? nullptr : &cve)
, cve(cve)
, group(group)
(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group)
: DropDownList(parent, is_submenu, is_submenu ? nullptr : &cve)
, cve(cve)
, group(group)
{
icon_size.width = 16;
icon_size.height = 16;
item_size.height = max(16., item_size.height);
icon_size.width = 16;
icon_size.height = 16;
item_size.height = max(16., item_size.height);
}
void DropDownChoiceListBase::onShow() {
// update 'enabled'
Context& ctx = cve.viewer.getContext();
FOR_EACH(c, group->choices) {
c->enabled.update(ctx);
}
// update 'enabled'
Context& ctx = cve.viewer.getContext();
FOR_EACH(c, group->choices) {
c->enabled.update(ctx);
}
}
size_t DropDownChoiceListBase::itemCount() const {
return group->choices.size() + hasDefault();
return group->choices.size() + hasDefault();
}
ChoiceField::ChoiceP DropDownChoiceListBase::getChoice(size_t item) const {
if (isGroupDefault(item)) {
return group;
} else {
return group->choices[item - hasDefault()];
}
if (isGroupDefault(item)) {
return group;
} else {
return group->choices[item - hasDefault()];
}
}
String DropDownChoiceListBase::itemText(size_t item) const {
if (isFieldDefault(item)) {
return field().default_name;
} else if (isGroupDefault(item)) {
return group->default_name;
} else {
ChoiceField::ChoiceP choice = getChoice(item);
return choice->name;
}
if (isFieldDefault(item)) {
return field().default_name;
} else if (isGroupDefault(item)) {
return group->default_name;
} else {
ChoiceField::ChoiceP choice = getChoice(item);
return choice->name;
}
}
bool DropDownChoiceListBase::lineBelow(size_t item) const {
return isDefault(item) || getChoice(item)->line_below;
return isDefault(item) || getChoice(item)->line_below;
}
bool DropDownChoiceListBase::itemEnabled(size_t item) const {
return isDefault(item) || getChoice(item)->enabled;
return isDefault(item) || getChoice(item)->enabled;
}
DropDownList* DropDownChoiceListBase::submenu(size_t item) const {
if (isDefault(item)) return nullptr;
item -= hasDefault();
if (item >= submenus.size()) submenus.resize(item + 1);
if (submenus[item]) return submenus[item].get();
ChoiceField::ChoiceP choice = group->choices[item];
if (choice->isGroup()) {
// create submenu
submenus[item].reset(createSubMenu(choice));
}
return submenus[item].get();
if (isDefault(item)) return nullptr;
item -= hasDefault();
if (item >= submenus.size()) submenus.resize(item + 1);
if (submenus[item]) return submenus[item].get();
ChoiceField::ChoiceP choice = group->choices[item];
if (choice->isGroup()) {
// create submenu
submenus[item].reset(createSubMenu(choice));
}
return submenus[item].get();
}
void DropDownChoiceListBase::drawIcon(DC& dc, int x, int y, size_t item, bool selected) const {
// imagelist to use
wxImageList* il = style().thumbnails;
assert(il);
// find the image for the item
int image_id;
if (isFieldDefault(item)) {
image_id = default_id;
} else {
image_id = getChoice(item)->first_id;
}
// draw image
if (image_id < il->GetImageCount()) {
il->Draw(image_id, dc, x, y, itemEnabled(item) ? wxIMAGELIST_DRAW_NORMAL : wxIMAGELIST_DRAW_TRANSPARENT);
}
// imagelist to use
wxImageList* il = style().thumbnails;
assert(il);
// find the image for the item
int image_id;
if (isFieldDefault(item)) {
image_id = default_id;
} else {
image_id = getChoice(item)->first_id;
}
// draw image
if (image_id < il->GetImageCount()) {
il->Draw(image_id, dc, x, y, itemEnabled(item) ? wxIMAGELIST_DRAW_NORMAL : wxIMAGELIST_DRAW_TRANSPARENT);
}
}
void DropDownChoiceListBase::generateThumbnailImages() {
if (!isRoot()) return;
if (!style().thumbnails) {
style().thumbnails = new wxImageList(16,16);
}
int image_count = style().thumbnails->GetImageCount();
int end = group->lastId();
// init choice images
Context& ctx = cve.viewer.getContext();
if (style().choice_images.empty() && style().image.isScripted()) {
for (int i = 0 ; i < end ; ++i) {
try {
String name = canonical_name_form(field().choices->choiceName(i));
ctx.setVariable(_("input"), to_script(name));
GeneratedImageP img = image_from_script(style().image.getValidScriptP()->eval(ctx));
style().choice_images.insert(make_pair(name, ScriptableImage(img)));
} catch (const Error& e) {
handle_error(Error(e.what() + _("\n while generating choice images for drop down list")));
}
}
}
// request thumbnails
style().thumbnails_status.resize(end, THUMB_NOT_MADE);
for (int i = 0 ; i < end ; ++i) {
ThumbnailStatus& status = style().thumbnails_status[i];
if (i >= image_count || status != THUMB_OK) {
// update image
ChoiceStyle& s = style();
String name = canonical_name_form(s.field().choices->choiceName(i));
ScriptableImage& img = s.choice_images[name];
if (!img.update(ctx) && status == THUMB_CHANGED) {
status = THUMB_OK; // no need to rebuild
} else if (img.isReady()) {
// request this thumbnail
thumbnail_thread.request( intrusive(new ChoiceThumbnailRequest(
&cve, i, status == THUMB_NOT_MADE && !img.local(), img.threadSafe()
)));
}
}
}
if (!isRoot()) return;
if (!style().thumbnails) {
style().thumbnails = new wxImageList(16,16);
}
int image_count = style().thumbnails->GetImageCount();
int end = group->lastId();
// init choice images
Context& ctx = cve.viewer.getContext();
if (style().choice_images.empty() && style().image.isScripted()) {
for (int i = 0 ; i < end ; ++i) {
try {
String name = canonical_name_form(field().choices->choiceName(i));
ctx.setVariable(_("input"), to_script(name));
GeneratedImageP img = image_from_script(style().image.getValidScriptP()->eval(ctx));
style().choice_images.insert(make_pair(name, ScriptableImage(img)));
} catch (const Error& e) {
handle_error(Error(e.what() + _("\n while generating choice images for drop down list")));
}
}
}
// request thumbnails
style().thumbnails_status.resize(end, THUMB_NOT_MADE);
for (int i = 0 ; i < end ; ++i) {
ThumbnailStatus& status = style().thumbnails_status[i];
if (i >= image_count || status != THUMB_OK) {
// update image
ChoiceStyle& s = style();
String name = canonical_name_form(s.field().choices->choiceName(i));
ScriptableImage& img = s.choice_images[name];
if (!img.update(ctx) && status == THUMB_CHANGED) {
status = THUMB_OK; // no need to rebuild
} else if (img.isReady()) {
// request this thumbnail
thumbnail_thread.request( intrusive(new ChoiceThumbnailRequest(
&cve, i, status == THUMB_NOT_MADE && !img.local(), img.threadSafe()
)));
}
}
}
}
void DropDownChoiceListBase::onIdle(wxIdleEvent& ev) {
if (!isRoot()) return;
if (thumbnail_thread.done(&cve)) {
Refresh(false);
}
if (!isRoot()) return;
if (thumbnail_thread.done(&cve)) {
Refresh(false);
}
}
BEGIN_EVENT_TABLE(DropDownChoiceListBase, DropDownList)
EVT_IDLE(DropDownChoiceListBase::onIdle)
EVT_IDLE(DropDownChoiceListBase::onIdle)
END_EVENT_TABLE()
// ----------------------------------------------------------------------------- : DropDownChoiceList
DropDownChoiceList::DropDownChoiceList(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group)
: DropDownChoiceListBase(parent, is_submenu, cve, group)
: DropDownChoiceListBase(parent, is_submenu, cve, group)
{}
void DropDownChoiceList::onShow() {
DropDownChoiceListBase::onShow();
// we need thumbnail images soon
generateThumbnailImages();
DropDownChoiceListBase::onShow();
// we need thumbnail images soon
generateThumbnailImages();
}
void DropDownChoiceList::select(size_t item) {
if (isFieldDefault(item)) {
dynamic_cast<ChoiceValueEditor&>(cve).change( Defaultable<String>() );
} else {
ChoiceField::ChoiceP choice = getChoice(item);
dynamic_cast<ChoiceValueEditor&>(cve).change( field().choices->choiceName(choice->first_id) );
}
if (isFieldDefault(item)) {
dynamic_cast<ChoiceValueEditor&>(cve).change( Defaultable<String>() );
} else {
ChoiceField::ChoiceP choice = getChoice(item);
dynamic_cast<ChoiceValueEditor&>(cve).change( field().choices->choiceName(choice->first_id) );
}
}
size_t DropDownChoiceList::selection() const {
// selected item
const Defaultable<String>& value = dynamic_cast<ChoiceValueEditor&>(cve).value().value();
int id = field().choices->choiceId(value);
// id of default item
if (hasFieldDefault()) {
if (value.isDefault()) {
// default is selected
default_id = id;
return 0;
} else {
// run default script to find out what the default choice would be
String default_choice = *field().default_script.invoke( cve.viewer.getContext() );
default_id = group->choiceId(default_choice);
}
}
// item corresponding to id
size_t i = hasDefault();
FOR_EACH(c, group->choices) {
if (id >= c->first_id && id < c->lastId()) {
return i;
}
i++;
}
return NO_SELECTION;
// selected item
const Defaultable<String>& value = dynamic_cast<ChoiceValueEditor&>(cve).value().value();
int id = field().choices->choiceId(value);
// id of default item
if (hasFieldDefault()) {
if (value.isDefault()) {
// default is selected
default_id = id;
return 0;
} else {
// run default script to find out what the default choice would be
String default_choice = *field().default_script.invoke( cve.viewer.getContext() );
default_id = group->choiceId(default_choice);
}
}
// item corresponding to id
size_t i = hasDefault();
FOR_EACH(c, group->choices) {
if (id >= c->first_id && id < c->lastId()) {
return i;
}
i++;
}
return NO_SELECTION;
}
DropDownList* DropDownChoiceList::createSubMenu(ChoiceField::ChoiceP group) const {
return new DropDownChoiceList(static_cast<Window*>(const_cast<DropDownChoiceList*>(this)), true, cve, group);
return new DropDownChoiceList(static_cast<Window*>(const_cast<DropDownChoiceList*>(this)), true, cve, group);
}
// ----------------------------------------------------------------------------- : ChoiceValueEditor
IMPLEMENT_VALUE_EDITOR(Choice)
, drop_down(new DropDownChoiceList(&editor(), false, *this, field().choices))
, drop_down(new DropDownChoiceList(&editor(), false, *this, field().choices))
{}
ChoiceValueEditor::~ChoiceValueEditor() {
thumbnail_thread.abort(this);
thumbnail_thread.abort(this);
}
bool ChoiceValueEditor::onLeftDown(const RealPoint& pos, wxMouseEvent& ev) {
return drop_down->onMouseInParent(ev, style().popup_style == POPUP_DROPDOWN_IN_PLACE && !nativeLook());
return drop_down->onMouseInParent(ev, style().popup_style == POPUP_DROPDOWN_IN_PLACE && !nativeLook());
}
bool ChoiceValueEditor::onChar(wxKeyEvent& ev) {
return drop_down->onCharInParent(ev);
return drop_down->onCharInParent(ev);
}
void ChoiceValueEditor::onLoseFocus() {
drop_down->hide(false);
drop_down->hide(false);
}
void ChoiceValueEditor::draw(RotatedDC& dc) {
ChoiceValueViewer::draw(dc);
if (nativeLook()) {
draw_drop_down_arrow(&editor(), dc.getDC(), dc.trRectToBB(style().getInternalRect().grow(1)), drop_down->IsShown());
}
ChoiceValueViewer::draw(dc);
if (nativeLook()) {
draw_drop_down_arrow(&editor(), dc.getDC(), dc.trRectToBB(style().getInternalRect().grow(1)), drop_down->IsShown());
}
}
void ChoiceValueEditor::determineSize(bool) {
style().height = max(style().height(), 16.);
style().height = max(style().height(), 16.);
}
void ChoiceValueEditor::change(const Defaultable<String>& c) {
addAction(value_action(valueP(), c));
addAction(value_action(valueP(), c));
}
+56 -56
View File
@@ -22,22 +22,22 @@ DECLARE_POINTER_TYPE(ThumbnailRequest);
/// An editor 'control' for editing ChoiceValues
class ChoiceValueEditor : public ChoiceValueViewer, public ValueEditor {
public:
DECLARE_VALUE_EDITOR(Choice);
~ChoiceValueEditor();
// --------------------------------------------------- : Events
virtual bool onLeftDown(const RealPoint& pos, wxMouseEvent& ev);
virtual bool onChar(wxKeyEvent& ev);
virtual void onLoseFocus();
virtual void draw(RotatedDC& dc);
virtual void determineSize(bool);
DECLARE_VALUE_EDITOR(Choice);
~ChoiceValueEditor();
// --------------------------------------------------- : Events
virtual bool onLeftDown(const RealPoint& pos, wxMouseEvent& ev);
virtual bool onChar(wxKeyEvent& ev);
virtual void onLoseFocus();
virtual void draw(RotatedDC& dc);
virtual void determineSize(bool);
private:
DropDownListP drop_down;
friend class DropDownChoiceList;
/// Change the choice
void change(const Defaultable<String>& c);
DropDownListP drop_down;
friend class DropDownChoiceList;
/// Change the choice
void change(const Defaultable<String>& c);
};
// ----------------------------------------------------------------------------- : DropDownChoiceList
@@ -46,44 +46,44 @@ class ChoiceValueEditor : public ChoiceValueViewer, public ValueEditor {
/** This is a base class, used for single and multiple choice fields */
class DropDownChoiceListBase : public DropDownList {
public:
DropDownChoiceListBase(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group);
DropDownChoiceListBase(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group);
protected:
virtual void onShow();
virtual size_t itemCount() const;
virtual bool lineBelow(size_t item) const;
virtual bool itemEnabled(size_t item) const;
virtual String itemText(size_t item) const;
virtual void drawIcon(DC& dc, int x, int y, size_t item, bool selected) const;
virtual DropDownList* submenu(size_t item) const;
virtual void onShow();
virtual size_t itemCount() const;
virtual bool lineBelow(size_t item) const;
virtual bool itemEnabled(size_t item) const;
virtual String itemText(size_t item) const;
virtual void drawIcon(DC& dc, int x, int y, size_t item, bool selected) const;
virtual DropDownList* submenu(size_t item) const;
protected:
virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const = 0;
virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const = 0;
private:
DECLARE_EVENT_TABLE();
ValueViewer& cve; ///< Editor this list belongs to
ChoiceField::ChoiceP group; ///< Group this menu shows
mutable vector<DropDownListP> submenus;
mutable int default_id; ///< Item id for the default item (if !hasFieldDefault()) this is undefined)
inline ChoiceField& field() const { return static_cast<ChoiceField&>(*cve.getField()); }
inline ChoiceStyle& style() const { return static_cast<ChoiceStyle&>(*cve.getStyle()); }
inline bool isRoot() const { return group == field().choices; }
inline bool hasFieldDefault() const { return isRoot() && field().default_script; }
inline bool hasGroupDefault() const { return group->hasDefault(); }
virtual bool hasDefault() const { return hasFieldDefault() || hasGroupDefault(); }
inline bool isFieldDefault(size_t item) const { return item == 0 && hasFieldDefault(); }
inline bool isGroupDefault(size_t item) const { return item == 0 && hasGroupDefault(); }
inline bool isDefault (size_t item) const { return item == 0 && hasDefault(); }
// Find an item in the group of choices
ChoiceField::ChoiceP getChoice(size_t item) const;
/// Start generating thumbnail images
void generateThumbnailImages();
void onIdle(wxIdleEvent&);
DECLARE_EVENT_TABLE();
ValueViewer& cve; ///< Editor this list belongs to
ChoiceField::ChoiceP group; ///< Group this menu shows
mutable vector<DropDownListP> submenus;
mutable int default_id; ///< Item id for the default item (if !hasFieldDefault()) this is undefined)
inline ChoiceField& field() const { return static_cast<ChoiceField&>(*cve.getField()); }
inline ChoiceStyle& style() const { return static_cast<ChoiceStyle&>(*cve.getStyle()); }
inline bool isRoot() const { return group == field().choices; }
inline bool hasFieldDefault() const { return isRoot() && field().default_script; }
inline bool hasGroupDefault() const { return group->hasDefault(); }
virtual bool hasDefault() const { return hasFieldDefault() || hasGroupDefault(); }
inline bool isFieldDefault(size_t item) const { return item == 0 && hasFieldDefault(); }
inline bool isGroupDefault(size_t item) const { return item == 0 && hasGroupDefault(); }
inline bool isDefault (size_t item) const { return item == 0 && hasDefault(); }
// Find an item in the group of choices
ChoiceField::ChoiceP getChoice(size_t item) const;
/// Start generating thumbnail images
void generateThumbnailImages();
void onIdle(wxIdleEvent&);
};
// ----------------------------------------------------------------------------- : DropDownChoiceList
@@ -91,13 +91,13 @@ class DropDownChoiceListBase : public DropDownList {
/// A drop down list of choices
class DropDownChoiceList : public DropDownChoiceListBase {
public:
DropDownChoiceList(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group);
DropDownChoiceList(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group);
protected:
virtual void onShow();
virtual void select(size_t item);
virtual size_t selection() const;
virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const;
virtual void onShow();
virtual void select(size_t item);
virtual size_t selection() const;
virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const;
};
// ----------------------------------------------------------------------------- : EOF
+90 -90
View File
@@ -20,139 +20,139 @@ DECLARE_TYPEOF_COLLECTION(ColorField::ChoiceP);
// A drop down list of color choices
class DropDownColorList : public DropDownList {
public:
DropDownColorList(Window* parent, ColorValueEditor& cve);
protected:
virtual size_t itemCount() const;
virtual bool lineBelow(size_t item) const;
virtual String itemText(size_t item) const;
virtual void drawIcon(DC& dc, int x, int y, size_t item, bool selected) const;
virtual void select(size_t item);
virtual size_t selection() const;
DropDownColorList(Window* parent, ColorValueEditor& cve);
protected:
virtual size_t itemCount() const;
virtual bool lineBelow(size_t item) const;
virtual String itemText(size_t item) const;
virtual void drawIcon(DC& dc, int x, int y, size_t item, bool selected) const;
virtual void select(size_t item);
virtual size_t selection() const;
private:
ColorValueEditor& cve;
mutable Color default_color;
ColorValueEditor& cve;
mutable Color default_color;
inline const ColorField& field() const { return cve.field(); }
// default, custom item
bool hasDefault() const { return field().default_script; }
bool hasCustom() const { return field().allow_custom; }
bool isDefault(size_t item) const {
return item == 0 && hasDefault();
}
bool isCustom(size_t item) const {
return item == itemCount() - 1 && hasCustom();
}
inline const ColorField& field() const { return cve.field(); }
// default, custom item
bool hasDefault() const { return field().default_script; }
bool hasCustom() const { return field().allow_custom; }
bool isDefault(size_t item) const {
return item == 0 && hasDefault();
}
bool isCustom(size_t item) const {
return item == itemCount() - 1 && hasCustom();
}
};
DropDownColorList::DropDownColorList(Window* parent, ColorValueEditor& cve)
: DropDownList(parent, false, &cve)
, cve(cve)
: DropDownList(parent, false, &cve)
, cve(cve)
{
icon_size.width = 25;
if (item_size.height < 16) {
text_offset = (16 - (int)item_size.height) / 2;
item_size.height = 16;
}
icon_size.width = 25;
if (item_size.height < 16) {
text_offset = (16 - (int)item_size.height) / 2;
item_size.height = 16;
}
}
size_t DropDownColorList::itemCount() const {
return cve.field().choices.size() + hasDefault() + hasCustom();
return cve.field().choices.size() + hasDefault() + hasCustom();
}
bool DropDownColorList::lineBelow(size_t item) const {
return isDefault(item) || isCustom(item + 1); // below default item, above custom item
return isDefault(item) || isCustom(item + 1); // below default item, above custom item
}
String DropDownColorList::itemText(size_t item) const {
if (isDefault(item)) {
return field().default_name;
} else if (isCustom(item)) {
return _("Custom...");
} else {
return field().choices[item - hasDefault()]->name;
}
if (isDefault(item)) {
return field().default_name;
} else if (isCustom(item)) {
return _("Custom...");
} else {
return field().choices[item - hasDefault()]->name;
}
}
void DropDownColorList::drawIcon(DC& dc, int x, int y, size_t item, bool selected) const {
Color col;
if (isDefault(item)) {
col = default_color;
} else if (isCustom(item)) {
col = cve.value().value();
} else {
col = field().choices[item - hasDefault()]->color;
}
// draw a rectangle with the right color
dc.SetPen(wxSystemSettings::GetColour(selected ? wxSYS_COLOUR_HIGHLIGHTTEXT : wxSYS_COLOUR_WINDOWTEXT));
dc.SetBrush(col);
dc.DrawRectangle(x+1, y+1, (int)icon_size.width-2, (int)item_size.height-2);
Color col;
if (isDefault(item)) {
col = default_color;
} else if (isCustom(item)) {
col = cve.value().value();
} else {
col = field().choices[item - hasDefault()]->color;
}
// draw a rectangle with the right color
dc.SetPen(wxSystemSettings::GetColour(selected ? wxSYS_COLOUR_HIGHLIGHTTEXT : wxSYS_COLOUR_WINDOWTEXT));
dc.SetBrush(col);
dc.DrawRectangle(x+1, y+1, (int)icon_size.width-2, (int)item_size.height-2);
}
size_t DropDownColorList::selection() const {
// find selected color
size_t selection = hasCustom() ? itemCount() - 1 : NO_SELECTION;
size_t i = 0;
FOR_EACH_CONST(c, field().choices) {
if (c->color == cve.value().value()) {
selection = i + hasDefault();
break;
}
i++;
}
// has default item?
if (hasDefault() && cve.value().value.isDefault()) {
// default is selected
default_color = cve.value().value();
return 0;
} else if (hasDefault()) {
// evaluate script to find default color
default_color = *field().default_script.invoke(cve.viewer.getContext());
}
return selection;
// find selected color
size_t selection = hasCustom() ? itemCount() - 1 : NO_SELECTION;
size_t i = 0;
FOR_EACH_CONST(c, field().choices) {
if (c->color == cve.value().value()) {
selection = i + hasDefault();
break;
}
i++;
}
// has default item?
if (hasDefault() && cve.value().value.isDefault()) {
// default is selected
default_color = cve.value().value();
return 0;
} else if (hasDefault()) {
// evaluate script to find default color
default_color = *field().default_script.invoke(cve.viewer.getContext());
}
return selection;
}
void DropDownColorList::select(size_t item) {
if (isDefault(item)) {
cve.change( Defaultable<Color>());
} else if (isCustom(item)) {
cve.changeCustom();
} else {
cve.change(field().choices[item - hasDefault()]->color);
}
if (isDefault(item)) {
cve.change( Defaultable<Color>());
} else if (isCustom(item)) {
cve.changeCustom();
} else {
cve.change(field().choices[item - hasDefault()]->color);
}
}
// ----------------------------------------------------------------------------- : ColorValueEditor
IMPLEMENT_VALUE_EDITOR(Color)
, drop_down(new DropDownColorList(&editor(), *this))
, drop_down(new DropDownColorList(&editor(), *this))
{}
bool ColorValueEditor::onLeftDown(const RealPoint& pos, wxMouseEvent& ev) {
return drop_down->onMouseInParent(ev, !nativeLook());
return drop_down->onMouseInParent(ev, !nativeLook());
}
bool ColorValueEditor::onChar(wxKeyEvent& ev) {
return drop_down->onCharInParent(ev);
return drop_down->onCharInParent(ev);
}
void ColorValueEditor::onLoseFocus() {
drop_down->hide(false);
drop_down->hide(false);
}
void ColorValueEditor::draw(RotatedDC& dc) {
ColorValueViewer::draw(dc);
if (nativeLook()) {
draw_drop_down_arrow(&editor(), dc.getDC(), dc.trRectToBB(dc.getInternalRect().grow(1)), drop_down->IsShown());
}
ColorValueViewer::draw(dc);
if (nativeLook()) {
draw_drop_down_arrow(&editor(), dc.getDC(), dc.trRectToBB(dc.getInternalRect().grow(1)), drop_down->IsShown());
}
}
void ColorValueEditor::determineSize(bool) {
style().height = 20;
style().height = 20;
}
void ColorValueEditor::change(const Defaultable<Color>& c) {
addAction(value_action(valueP(), c));
addAction(value_action(valueP(), c));
}
void ColorValueEditor::changeCustom() {
Color c = wxGetColourFromUser(0, value().value());
if (c.Ok()) change(c);
Color c = wxGetColourFromUser(0, value().value());
if (c.Ok()) change(c);
}
+16 -16
View File
@@ -20,23 +20,23 @@ DECLARE_SHARED_POINTER_TYPE(DropDownList);
/// An editor 'control' for editing ColorValues
class ColorValueEditor : public ColorValueViewer, public ValueEditor {
public:
DECLARE_VALUE_EDITOR(Color);
// --------------------------------------------------- : Events
virtual bool onLeftDown(const RealPoint& pos, wxMouseEvent& ev);
virtual bool onChar(wxKeyEvent& ev);
virtual void onLoseFocus();
virtual void draw(RotatedDC& dc);
virtual void determineSize(bool);
DECLARE_VALUE_EDITOR(Color);
// --------------------------------------------------- : Events
virtual bool onLeftDown(const RealPoint& pos, wxMouseEvent& ev);
virtual bool onChar(wxKeyEvent& ev);
virtual void onLoseFocus();
virtual void draw(RotatedDC& dc);
virtual void determineSize(bool);
private:
DropDownListP drop_down;
friend class DropDownColorList;
/// Change the color
void change(const Defaultable<Color>& c);
/// Change to a custom color
void changeCustom();
DropDownListP drop_down;
friend class DropDownColorList;
/// Change the color
void change(const Defaultable<Color>& c);
/// Change to a custom color
void changeCustom();
};
// ----------------------------------------------------------------------------- : EOF
+4 -4
View File
@@ -13,8 +13,8 @@
// ----------------------------------------------------------------------------- : ValueEditor
void ValueEditor::addAction(ValueAction* a) {
if (a) {
a->isOnCard(editor().getCard().get());
editor().addAction(a);
}
if (a) {
a->isOnCard(editor().getCard().get());
editor().addAction(a);
}
}
+111 -111
View File
@@ -35,123 +35,123 @@ DECLARE_POINTER_TYPE(ValueActionPerformer);
*/
class ValueEditor {
public:
virtual ~ValueEditor() {}
// --------------------------------------------------- : Events
/// This editor gains focus
virtual void onFocus() {}
/// This editor loses focus
virtual void onLoseFocus() {}
/// Handle mouse events, return true if the event is used
virtual bool onLeftDown (const RealPoint& pos, wxMouseEvent& ev) { return false; }
virtual bool onLeftUp (const RealPoint& pos, wxMouseEvent& ev) { return false; }
virtual bool onLeftDClick (const RealPoint& pos, wxMouseEvent& ev) { return false; }
virtual bool onRightDown (const RealPoint& pos, wxMouseEvent& ev) { return false; }
virtual bool onMotion (const RealPoint& pos, wxMouseEvent& ev) { return false; }
virtual void onMouseLeave (const RealPoint& pos, wxMouseEvent& ev) {}
virtual bool onMouseWheel (const RealPoint& pos, wxMouseEvent& ev) { return false; }
/// Key events
virtual bool onChar(wxKeyEvent& ev) { return false; }
/// a context menu is requested, add extra items to the menu m
/** return false to suppress menu */
virtual bool onContextMenu(IconMenu& m, wxContextMenuEvent& ev) { return true; }
/// Get a special menu, events will be sent to onMenu
virtual wxMenu* getMenu(int type) const { return nullptr; }
/// A menu item was selected, return true if the command was processed
virtual bool onCommand(int id) { return false; }
// --------------------------------------------------- : 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; }
/// Insert the given text (replacing the current selection)
virtual void insert(const String& text, const String& action_name) {};
// --------------------------------------------------- : Search / replace
/// Do a search or replace action for the given FindInfo
/** If from_start == false: searches only from the current selection onward (or backward),
* excluding the sellection itself.
* If from_start == true: searches everything
*
* Returns true if we are done and searching should be ended.
*/
virtual bool search(FindInfo& find, bool from_start) { return false; }
// --------------------------------------------------- : Other
/// The cursor type to use when the mouse is over this control
virtual wxCursor cursor(const RealPoint& pos) const { return wxCursor(); }
/// Determines prefered size in the native look, update the style
virtual void determineSize(bool force_fit = false) {}
/// Should a label and control border be drawn in the native look?
virtual bool drawLabel() const { return true; }
/// The editor is shown or hidden
virtual void onShow(bool) {}
// --------------------------------------------------- : Helpers
virtual ~ValueEditor() {}
// --------------------------------------------------- : Events
/// This editor gains focus
virtual void onFocus() {}
/// This editor loses focus
virtual void onLoseFocus() {}
/// Handle mouse events, return true if the event is used
virtual bool onLeftDown (const RealPoint& pos, wxMouseEvent& ev) { return false; }
virtual bool onLeftUp (const RealPoint& pos, wxMouseEvent& ev) { return false; }
virtual bool onLeftDClick (const RealPoint& pos, wxMouseEvent& ev) { return false; }
virtual bool onRightDown (const RealPoint& pos, wxMouseEvent& ev) { return false; }
virtual bool onMotion (const RealPoint& pos, wxMouseEvent& ev) { return false; }
virtual void onMouseLeave (const RealPoint& pos, wxMouseEvent& ev) {}
virtual bool onMouseWheel (const RealPoint& pos, wxMouseEvent& ev) { return false; }
/// Key events
virtual bool onChar(wxKeyEvent& ev) { return false; }
/// a context menu is requested, add extra items to the menu m
/** return false to suppress menu */
virtual bool onContextMenu(IconMenu& m, wxContextMenuEvent& ev) { return true; }
/// Get a special menu, events will be sent to onMenu
virtual wxMenu* getMenu(int type) const { return nullptr; }
/// A menu item was selected, return true if the command was processed
virtual bool onCommand(int id) { return false; }
// --------------------------------------------------- : 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; }
/// Insert the given text (replacing the current selection)
virtual void insert(const String& text, const String& action_name) {};
// --------------------------------------------------- : Search / replace
/// Do a search or replace action for the given FindInfo
/** If from_start == false: searches only from the current selection onward (or backward),
* excluding the sellection itself.
* If from_start == true: searches everything
*
* Returns true if we are done and searching should be ended.
*/
virtual bool search(FindInfo& find, bool from_start) { return false; }
// --------------------------------------------------- : Other
/// The cursor type to use when the mouse is over this control
virtual wxCursor cursor(const RealPoint& pos) const { return wxCursor(); }
/// Determines prefered size in the native look, update the style
virtual void determineSize(bool force_fit = false) {}
/// Should a label and control border be drawn in the native look?
virtual bool drawLabel() const { return true; }
/// The editor is shown or hidden
virtual void onShow(bool) {}
// --------------------------------------------------- : Helpers
protected:
/// Retrieve the parent editor object
virtual DataEditor& editor() const = 0;
/// Perform an action
void addAction(ValueAction* a);
/// Retrieve the parent editor object
virtual DataEditor& editor() const = 0;
/// Perform an action
void addAction(ValueAction* a);
};
// ----------------------------------------------------------------------------- : Utility
#define DECLARE_VALUE_EDITOR(Type) \
Type##ValueEditor(DataEditor& parent, const Type##StyleP& style); \
virtual ValueEditor* getEditor() { return this; } \
private: \
/** Retrieve the parent editor object */ \
inline DataEditor& editor() const { \
return static_cast<DataEditor&>(viewer); \
} \
public:
#define DECLARE_VALUE_EDITOR(Type) \
Type##ValueEditor(DataEditor& parent, const Type##StyleP& style); \
virtual ValueEditor* getEditor() { return this; } \
private: \
/** Retrieve the parent editor object */ \
inline DataEditor& editor() const { \
return static_cast<DataEditor&>(viewer); \
} \
public:
#define IMPLEMENT_VALUE_EDITOR(Type) \
ValueViewerP Type##Style::makeEditor(DataEditor& parent, const StyleP& thisP) { \
assert(thisP.get() == this); \
return ValueViewerP(new Type##ValueEditor(parent, static_pointer_cast<Type##Style>(thisP))); \
} \
Type##ValueEditor::Type##ValueEditor(DataEditor& parent, const Type##StyleP& style) \
: Type##ValueViewer(parent, style)
#define IMPLEMENT_VALUE_EDITOR(Type) \
ValueViewerP Type##Style::makeEditor(DataEditor& parent, const StyleP& thisP) { \
assert(thisP.get() == this); \
return ValueViewerP(new Type##ValueEditor(parent, static_pointer_cast<Type##Style>(thisP))); \
} \
Type##ValueEditor::Type##ValueEditor(DataEditor& parent, const Type##StyleP& style) \
: Type##ValueViewer(parent, style)
// ----------------------------------------------------------------------------- : EOF
#endif
+54 -54
View File
@@ -18,82 +18,82 @@
IMPLEMENT_VALUE_EDITOR(Image) {}
bool ImageValueEditor::onLeftDClick(const RealPoint&, wxMouseEvent&) {
String filename = wxFileSelector(_("Open image file"), settings.default_image_dir, _(""), _(""),
_("All images|*.bmp;*.jpg;*.png;*.gif|Windows bitmaps (*.bmp)|*.bmp|JPEG images (*.jpg;*.jpeg)|*.jpg;*.jpeg|PNG images (*.png)|*.png|GIF images (*.gif)|*.gif|TIFF images (*.tif;*.tiff)|*.tif;*.tiff"),
wxOPEN, wxGetTopLevelParent(&editor()));
if (!filename.empty()) {
settings.default_image_dir = wxPathOnly(filename);
sliceImage(wxImage(filename));
}
return true;
String filename = wxFileSelector(_("Open image file"), settings.default_image_dir, _(""), _(""),
_("All images|*.bmp;*.jpg;*.png;*.gif|Windows bitmaps (*.bmp)|*.bmp|JPEG images (*.jpg;*.jpeg)|*.jpg;*.jpeg|PNG images (*.png)|*.png|GIF images (*.gif)|*.gif|TIFF images (*.tif;*.tiff)|*.tif;*.tiff"),
wxOPEN, wxGetTopLevelParent(&editor()));
if (!filename.empty()) {
settings.default_image_dir = wxPathOnly(filename);
sliceImage(wxImage(filename));
}
return true;
}
void ImageValueEditor::sliceImage(const Image& image) {
if (!image.Ok()) return;
// mask
GeneratedImage::Options options((int)style().width, (int)style().height, &viewer.getStylePackage(), &viewer.getLocalPackage());
AlphaMask mask;
style().mask.getNoCache(options,mask);
// slice
ImageSliceWindow s(wxGetTopLevelParent(&editor()), image, style().getSize(), mask);
// clicked ok?
if (s.ShowModal() == wxID_OK) {
// store the image into the set
FileName new_image_file = getLocalPackage().newFileName(field().name,_("")); // a new unique name in the package
Image img = s.getImage();
img.SaveFile(getLocalPackage().nameOut(new_image_file), wxBITMAP_TYPE_PNG); // always use PNG images, see #69. Disk space is cheap anyway.
addAction(value_action(valueP(), new_image_file));
}
if (!image.Ok()) return;
// mask
GeneratedImage::Options options((int)style().width, (int)style().height, &viewer.getStylePackage(), &viewer.getLocalPackage());
AlphaMask mask;
style().mask.getNoCache(options,mask);
// slice
ImageSliceWindow s(wxGetTopLevelParent(&editor()), image, style().getSize(), mask);
// clicked ok?
if (s.ShowModal() == wxID_OK) {
// store the image into the set
FileName new_image_file = getLocalPackage().newFileName(field().name,_("")); // a new unique name in the package
Image img = s.getImage();
img.SaveFile(getLocalPackage().nameOut(new_image_file), wxBITMAP_TYPE_PNG); // always use PNG images, see #69. Disk space is cheap anyway.
addAction(value_action(valueP(), new_image_file));
}
}
// ----------------------------------------------------------------------------- : Clipboard
bool ImageValueEditor::canCopy() const {
return !value().filename.empty();
return !value().filename.empty();
}
bool ImageValueEditor::canPaste() const {
return wxTheClipboard->IsSupported(wxDF_BITMAP) &&
!wxTheClipboard->IsSupported(CardsDataObject::format); // we don't want to (accidentally) paste card images
return wxTheClipboard->IsSupported(wxDF_BITMAP) &&
!wxTheClipboard->IsSupported(CardsDataObject::format); // we don't want to (accidentally) paste card images
}
bool ImageValueEditor::doCopy() {
// load image
InputStreamP image_file = getLocalPackage().openIn(value().filename);
Image image;
if (!image.LoadFile(*image_file)) return false;
// set data
if (!wxTheClipboard->Open()) return false;
bool ok = wxTheClipboard->SetData(new wxBitmapDataObject(image));
wxTheClipboard->Close();
return ok;
// load image
InputStreamP image_file = getLocalPackage().openIn(value().filename);
Image image;
if (!image.LoadFile(*image_file)) return false;
// set data
if (!wxTheClipboard->Open()) return false;
bool ok = wxTheClipboard->SetData(new wxBitmapDataObject(image));
wxTheClipboard->Close();
return ok;
}
bool ImageValueEditor::doPaste() {
// get bitmap
if (!wxTheClipboard->Open()) return false;
wxBitmapDataObject data;
bool ok = wxTheClipboard->GetData(data);
wxTheClipboard->Close();
if (!ok) return false;
// slice
sliceImage(data.GetBitmap().ConvertToImage());
return true;
// get bitmap
if (!wxTheClipboard->Open()) return false;
wxBitmapDataObject data;
bool ok = wxTheClipboard->GetData(data);
wxTheClipboard->Close();
if (!ok) return false;
// slice
sliceImage(data.GetBitmap().ConvertToImage());
return true;
}
bool ImageValueEditor::doDelete() {
addAction(value_action(valueP(), FileName()));
return true;
addAction(value_action(valueP(), FileName()));
return true;
}
bool ImageValueEditor::onChar(wxKeyEvent& ev) {
if (ev.AltDown() || ev.ShiftDown() || ev.ControlDown()) return false;
switch (ev.GetKeyCode()) {
case WXK_DELETE:
doDelete();
return true;
default:
return false;
}
if (ev.AltDown() || ev.ShiftDown() || ev.ControlDown()) return false;
switch (ev.GetKeyCode()) {
case WXK_DELETE:
doDelete();
return true;
default:
return false;
}
}
+16 -16
View File
@@ -18,23 +18,23 @@
/// An editor 'control' for editing ImageValues
class ImageValueEditor : public ImageValueViewer, public ValueEditor {
public:
DECLARE_VALUE_EDITOR(Image);
virtual bool onLeftDClick(const RealPoint&, wxMouseEvent&);
// --------------------------------------------------- : Clipboard
virtual bool canCopy() const;
virtual bool canPaste() const;
virtual bool doCopy();
virtual bool doPaste();
virtual bool doDelete();
virtual bool onChar(wxKeyEvent&);
DECLARE_VALUE_EDITOR(Image);
virtual bool onLeftDClick(const RealPoint&, wxMouseEvent&);
// --------------------------------------------------- : Clipboard
virtual bool canCopy() const;
virtual bool canPaste() const;
virtual bool doCopy();
virtual bool doPaste();
virtual bool doDelete();
virtual bool onChar(wxKeyEvent&);
private:
// Open the image slice window showing the give image
void sliceImage(const Image&);
// Open the image slice window showing the give image
void sliceImage(const Image&);
};
// ----------------------------------------------------------------------------- : EOF
+1 -1
View File
@@ -14,5 +14,5 @@
IMPLEMENT_VALUE_EDITOR(Info) {}
void InfoValueEditor::determineSize(bool) {
style().height = 26;
style().height = 26;
}
+4 -4
View File
@@ -18,10 +18,10 @@
/// An editor 'control' for editing InfoValues
class InfoValueEditor : public InfoValueViewer, public ValueEditor {
public:
DECLARE_VALUE_EDITOR(Info);
virtual void determineSize(bool);
virtual bool drawLabel() const { return false; }
DECLARE_VALUE_EDITOR(Info);
virtual void determineSize(bool);
virtual bool drawLabel() const { return false; }
};
// ----------------------------------------------------------------------------- : EOF
+116 -116
View File
@@ -17,73 +17,73 @@
/// A drop down list of color choices
class DropDownMultipleChoiceList : public DropDownChoiceListBase {
public:
DropDownMultipleChoiceList(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group);
DropDownMultipleChoiceList(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group);
protected:
virtual void onShow();
virtual void select(size_t item);
virtual size_t selection() const;
virtual bool stayOpen(size_t selection) const { return true; }
virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const;
virtual void drawIcon(DC& dc, int x, int y, size_t item, bool selected) const;
virtual void onShow();
virtual void select(size_t item);
virtual size_t selection() const;
virtual bool stayOpen(size_t selection) const { return true; }
virtual DropDownList* createSubMenu(ChoiceField::ChoiceP group) const;
virtual void drawIcon(DC& dc, int x, int y, size_t item, bool selected) const;
};
DropDownMultipleChoiceList::DropDownMultipleChoiceList
(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group)
: DropDownChoiceListBase(parent, is_submenu, cve, group)
(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group)
: DropDownChoiceListBase(parent, is_submenu, cve, group)
{
icon_size.width += 16;
icon_size.width += 16;
}
void DropDownMultipleChoiceList::select(size_t item) {
MultipleChoiceValueEditor& mcve = dynamic_cast<MultipleChoiceValueEditor&>(cve);
if (isFieldDefault(item)) {
mcve.toggleDefault();
} else {
ChoiceField::ChoiceP choice = getChoice(item);
mcve.toggle(choice->first_id);
}
// keep the box open
DropDownChoiceListBase::onShow(); // update 'enabled'
MultipleChoiceValueEditor& mcve = dynamic_cast<MultipleChoiceValueEditor&>(cve);
if (isFieldDefault(item)) {
mcve.toggleDefault();
} else {
ChoiceField::ChoiceP choice = getChoice(item);
mcve.toggle(choice->first_id);
}
// keep the box open
DropDownChoiceListBase::onShow(); // update 'enabled'
}
void DropDownMultipleChoiceList::drawIcon(DC& dc, int x, int y, size_t item, bool selected) const {
// is this item active/checked?
bool active = false;
bool radio = false;
if (!isFieldDefault(item)) {
ChoiceField::ChoiceP choice = getChoice(item);
active = dynamic_cast<MultipleChoiceValueEditor&>(cve).active[choice->first_id];
radio = choice->type == CHOICE_TYPE_RADIO;
} else {
active = dynamic_cast<MultipleChoiceValueEditor&>(cve).value().value.isDefault();
}
// draw checkbox
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
dc.DrawRectangle(x,y,16,16);
wxRect rect = RealRect(x+2,y+2,12,12);
if (radio) {
draw_radiobox(nullptr, dc, rect, active, itemEnabled(item));
} else {
draw_checkbox(nullptr, dc, rect, active, itemEnabled(item));
}
// draw icon
DropDownChoiceListBase::drawIcon(dc, x + 16, y, item, selected);
// is this item active/checked?
bool active = false;
bool radio = false;
if (!isFieldDefault(item)) {
ChoiceField::ChoiceP choice = getChoice(item);
active = dynamic_cast<MultipleChoiceValueEditor&>(cve).active[choice->first_id];
radio = choice->type == CHOICE_TYPE_RADIO;
} else {
active = dynamic_cast<MultipleChoiceValueEditor&>(cve).value().value.isDefault();
}
// draw checkbox
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
dc.DrawRectangle(x,y,16,16);
wxRect rect = RealRect(x+2,y+2,12,12);
if (radio) {
draw_radiobox(nullptr, dc, rect, active, itemEnabled(item));
} else {
draw_checkbox(nullptr, dc, rect, active, itemEnabled(item));
}
// draw icon
DropDownChoiceListBase::drawIcon(dc, x + 16, y, item, selected);
}
void DropDownMultipleChoiceList::onShow() {
DropDownChoiceListBase::onShow();
// we need thumbnail images soon
const_cast<DropDownMultipleChoiceList*>(this)->generateThumbnailImages();
DropDownChoiceListBase::onShow();
// we need thumbnail images soon
const_cast<DropDownMultipleChoiceList*>(this)->generateThumbnailImages();
}
size_t DropDownMultipleChoiceList::selection() const {
return NO_SELECTION; // we don't know the selection
return NO_SELECTION; // we don't know the selection
}
DropDownList* DropDownMultipleChoiceList::createSubMenu(ChoiceField::ChoiceP group) const {
return new DropDownMultipleChoiceList(static_cast<Window*>(const_cast<DropDownMultipleChoiceList*>(this)), true, cve, group);
return new DropDownMultipleChoiceList(static_cast<Window*>(const_cast<DropDownMultipleChoiceList*>(this)), true, cve, group);
}
// ----------------------------------------------------------------------------- : MultipleChoiceValueEditor
@@ -91,95 +91,95 @@ DropDownList* DropDownMultipleChoiceList::createSubMenu(ChoiceField::ChoiceP gro
IMPLEMENT_VALUE_EDITOR(MultipleChoice) {}
MultipleChoiceValueEditor::~MultipleChoiceValueEditor() {
thumbnail_thread.abort(this);
thumbnail_thread.abort(this);
}
DropDownList& MultipleChoiceValueEditor::initDropDown() {
if (!drop_down) {
drop_down.reset(new DropDownMultipleChoiceList(&editor(), false, *this, field().choices));
}
return *drop_down;
if (!drop_down) {
drop_down.reset(new DropDownMultipleChoiceList(&editor(), false, *this, field().choices));
}
return *drop_down;
}
void MultipleChoiceValueEditor::determineSize(bool force_fit) {
if (!nativeLook()) return;
// item height
item_height = 16;
// height depends on number of items and item height
int item_count = field().choices->lastId();
style().height = item_count * item_height;
if (!nativeLook()) return;
// item height
item_height = 16;
// height depends on number of items and item height
int item_count = field().choices->lastId();
style().height = item_count * item_height;
}
bool MultipleChoiceValueEditor::onLeftDown(const RealPoint& pos, wxMouseEvent& ev) {
// find item under cursor
if (style().render_style & RENDER_CHECKLIST) {
// TODO: determine actual item height
if (item_height == 0) item_height = 16;
int id = (int)(pos.y / item_height);
int end = field().choices->lastId();
if (id >= 0 && id < end) {
toggle(id);
return true;
}
} else {
// open a drop down menu
return initDropDown().onMouseInParent(ev, style().popup_style == POPUP_DROPDOWN_IN_PLACE && !nativeLook());
}
return false;
// find item under cursor
if (style().render_style & RENDER_CHECKLIST) {
// TODO: determine actual item height
if (item_height == 0) item_height = 16;
int id = (int)(pos.y / item_height);
int end = field().choices->lastId();
if (id >= 0 && id < end) {
toggle(id);
return true;
}
} else {
// open a drop down menu
return initDropDown().onMouseInParent(ev, style().popup_style == POPUP_DROPDOWN_IN_PLACE && !nativeLook());
}
return false;
}
bool MultipleChoiceValueEditor::onChar(wxKeyEvent& ev) {
if (style().render_style & RENDER_CHECKLIST) {
// todo;
return false;
} else {
return initDropDown().onCharInParent(ev);
}
if (style().render_style & RENDER_CHECKLIST) {
// todo;
return false;
} else {
return initDropDown().onCharInParent(ev);
}
}
void MultipleChoiceValueEditor::onLoseFocus() {
if (drop_down) drop_down->hide(false);
if (drop_down) drop_down->hide(false);
}
void MultipleChoiceValueEditor::onValueChange() {
MultipleChoiceValueViewer::onValueChange();
// determine active values
active.clear();
vector<String> selected;
value().get(selected);
vector<String>::iterator select_it = selected.begin();
// for each choice...
int end = field().choices->lastId();
for (int i = 0 ; i < end ; ++i) {
String choice = field().choices->choiceName(i);
bool is_active = select_it != selected.end() && *select_it == choice;
if (is_active) select_it++;
active.push_back(is_active);
}
MultipleChoiceValueViewer::onValueChange();
// determine active values
active.clear();
vector<String> selected;
value().get(selected);
vector<String>::iterator select_it = selected.begin();
// for each choice...
int end = field().choices->lastId();
for (int i = 0 ; i < end ; ++i) {
String choice = field().choices->choiceName(i);
bool is_active = select_it != selected.end() && *select_it == choice;
if (is_active) select_it++;
active.push_back(is_active);
}
}
void MultipleChoiceValueEditor::toggle(int id) {
String new_value;
String toggled_choice;
// old selection
vector<String> selected;
value().get(selected);
vector<String>::iterator select_it = selected.begin();
// copy selected choices to new value
int end = field().choices->lastId();
for (int i = 0 ; i < end ; ++i) {
String choice = field().choices->choiceName(i);
bool active = select_it != selected.end() && *select_it == choice;
if (active) select_it++;
if (active != (i == id)) {
if (!new_value.empty()) new_value += _(", ");
new_value += choice;
}
if (i == id) toggled_choice = choice;
}
// store value
addAction(value_action(valueP(), new_value, toggled_choice));
String new_value;
String toggled_choice;
// old selection
vector<String> selected;
value().get(selected);
vector<String>::iterator select_it = selected.begin();
// copy selected choices to new value
int end = field().choices->lastId();
for (int i = 0 ; i < end ; ++i) {
String choice = field().choices->choiceName(i);
bool active = select_it != selected.end() && *select_it == choice;
if (active) select_it++;
if (active != (i == id)) {
if (!new_value.empty()) new_value += _(", ");
new_value += choice;
}
if (i == id) toggled_choice = choice;
}
// store value
addAction(value_action(valueP(), new_value, toggled_choice));
}
void MultipleChoiceValueEditor::toggleDefault() {
addAction(value_action(valueP(), Defaultable<String>(value().value(), !value().value.isDefault()), _("")));
addAction(value_action(valueP(), Defaultable<String>(value().value(), !value().value.isDefault()), _("")));
}
+20 -20
View File
@@ -19,27 +19,27 @@
/// An editor 'control' for editing MultipleChoiceValues
class MultipleChoiceValueEditor : public MultipleChoiceValueViewer, public ValueEditor {
public:
DECLARE_VALUE_EDITOR(MultipleChoice);
~MultipleChoiceValueEditor();
virtual void onValueChange();
virtual void determineSize(bool force_fit);
virtual bool onLeftDown (const RealPoint& pos, wxMouseEvent& ev);
virtual bool onChar(wxKeyEvent& ev);
virtual void onLoseFocus();
DECLARE_VALUE_EDITOR(MultipleChoice);
~MultipleChoiceValueEditor();
virtual void onValueChange();
virtual void determineSize(bool force_fit);
virtual bool onLeftDown (const RealPoint& pos, wxMouseEvent& ev);
virtual bool onChar(wxKeyEvent& ev);
virtual void onLoseFocus();
private:
DropDownListP drop_down;
vector<int> active; ///< Which choices are active? (note: vector<bool> is evil)
friend class DropDownMultipleChoiceList;
/// Initialize the drop down list
DropDownList& initDropDown();
/// Toggle a choice or on or off
void toggle(int id);
/// Toggle defaultness or on or off
void toggleDefault();
DropDownListP drop_down;
vector<int> active; ///< Which choices are active? (note: vector<bool> is evil)
friend class DropDownMultipleChoiceList;
/// Initialize the drop down list
DropDownList& initDropDown();
/// Toggle a choice or on or off
void toggle(int id);
/// Toggle defaultness or on or off
void toggleDefault();
};
// ----------------------------------------------------------------------------- : EOF
+53 -53
View File
@@ -19,69 +19,69 @@ DECLARE_TYPEOF_COLLECTION(PackageChoiceValueViewer::Item);
/// A drop down list of color choices
class DropDownPackageChoiceList : public DropDownList {
public:
DropDownPackageChoiceList(Window* parent, PackageChoiceValueEditor* editor);
DropDownPackageChoiceList(Window* parent, PackageChoiceValueEditor* editor);
protected:
virtual size_t itemCount() const;
virtual String itemText(size_t item) const;
virtual bool lineBelow(size_t item) const;
virtual void drawIcon(DC& dc, int x, int y, size_t item, bool selected) const;
virtual void select(size_t selection);
virtual size_t selection() const;
virtual size_t itemCount() const;
virtual String itemText(size_t item) const;
virtual bool lineBelow(size_t item) const;
virtual void drawIcon(DC& dc, int x, int y, size_t item, bool selected) const;
virtual void select(size_t selection);
virtual size_t selection() const;
private:
PackageChoiceValueEditor& editor;
PackageChoiceValueEditor& editor;
};
DropDownPackageChoiceList::DropDownPackageChoiceList(Window* parent, PackageChoiceValueEditor* editor)
: DropDownList(parent, false, editor)
, editor(*editor)
: DropDownList(parent, false, editor)
, editor(*editor)
{
icon_size.width = 16;
icon_size.height = 16;
item_size.height = max(16., item_size.height);
icon_size.width = 16;
icon_size.height = 16;
item_size.height = max(16., item_size.height);
}
size_t DropDownPackageChoiceList::itemCount() const {
return editor.items.size() + (editor.field().required ? 0 : 1);
return editor.items.size() + (editor.field().required ? 0 : 1);
}
String DropDownPackageChoiceList::itemText(size_t item) const {
if (item == 0 && !editor.field().required) return editor.field().empty_name;
else {
size_t i = item - !editor.field().required;
return editor.items[i].name;
}
if (item == 0 && !editor.field().required) return editor.field().empty_name;
else {
size_t i = item - !editor.field().required;
return editor.items[i].name;
}
}
bool DropDownPackageChoiceList::lineBelow(size_t item) const {
return item == 0 && !editor.field().required;
return item == 0 && !editor.field().required;
}
void DropDownPackageChoiceList::drawIcon(DC& dc, int x, int y, size_t item, bool selected) const {
if (item == 0 && !editor.field().required) return;
size_t i = item - !editor.field().required;
const Bitmap& bmp = editor.items[i].image;
if (bmp.Ok()) dc.DrawBitmap(bmp, x, y);
if (item == 0 && !editor.field().required) return;
size_t i = item - !editor.field().required;
const Bitmap& bmp = editor.items[i].image;
if (bmp.Ok()) dc.DrawBitmap(bmp, x, y);
}
void DropDownPackageChoiceList::select(size_t item) {
String new_value;
if (item != 0 || editor.field().required) {
size_t i = item - !editor.field().required;
new_value = editor.items[i].package_name;
}
editor.change(new_value);
String new_value;
if (item != 0 || editor.field().required) {
size_t i = item - !editor.field().required;
new_value = editor.items[i].package_name;
}
editor.change(new_value);
}
size_t DropDownPackageChoiceList::selection() const {
size_t n = 0;
FOR_EACH(i, editor.items) {
if (editor.value().package_name == i.package_name) {
return n + !editor.field().required;
}
++n;
}
return editor.field().required ? NO_SELECTION : 0;
size_t n = 0;
FOR_EACH(i, editor.items) {
if (editor.value().package_name == i.package_name) {
return n + !editor.field().required;
}
++n;
}
return editor.field().required ? NO_SELECTION : 0;
}
// ----------------------------------------------------------------------------- : PackageChoiceValueEditor
@@ -89,32 +89,32 @@ size_t DropDownPackageChoiceList::selection() const {
IMPLEMENT_VALUE_EDITOR(PackageChoice) {}
bool PackageChoiceValueEditor::onLeftDown(const RealPoint& pos, wxMouseEvent& ev) {
if (!drop_down) initDropDown();
return drop_down->onMouseInParent(ev, false);
if (!drop_down) initDropDown();
return drop_down->onMouseInParent(ev, false);
}
bool PackageChoiceValueEditor::onChar(wxKeyEvent& ev) {
if (!drop_down) initDropDown();
return drop_down->onCharInParent(ev);
if (!drop_down) initDropDown();
return drop_down->onCharInParent(ev);
}
void PackageChoiceValueEditor::onLoseFocus() {
if (drop_down) drop_down->hide(false);
if (drop_down) drop_down->hide(false);
}
void PackageChoiceValueEditor::draw(RotatedDC& dc) {
PackageChoiceValueViewer::draw(dc);
if (nativeLook()) {
draw_drop_down_arrow(&editor(), dc.getDC(), dc.trRectToBB(style().getInternalRect().grow(1)), drop_down && drop_down->IsShown());
}
PackageChoiceValueViewer::draw(dc);
if (nativeLook()) {
draw_drop_down_arrow(&editor(), dc.getDC(), dc.trRectToBB(style().getInternalRect().grow(1)), drop_down && drop_down->IsShown());
}
}
void PackageChoiceValueEditor::determineSize(bool) {
style().height = max(style().height(), 16.);
style().height = max(style().height(), 16.);
}
void PackageChoiceValueEditor::change(const String& c) {
addAction(value_action(valueP(), c));
addAction(value_action(valueP(), c));
}
void PackageChoiceValueEditor::initDropDown() {
if (drop_down) return;
drop_down = shared(new DropDownPackageChoiceList(&editor(), this));
if (drop_down) return;
drop_down = shared(new DropDownPackageChoiceList(&editor(), this));
}
+14 -14
View File
@@ -20,21 +20,21 @@ DECLARE_SHARED_POINTER_TYPE(DropDownList);
/// An editor 'control' for editing PackageChoiceValues
class PackageChoiceValueEditor : public PackageChoiceValueViewer, public ValueEditor {
public:
DECLARE_VALUE_EDITOR(PackageChoice);
virtual void draw(RotatedDC& dc);
virtual void determineSize(bool force_fit);
virtual bool onLeftDown (const RealPoint& pos, wxMouseEvent& ev);
virtual bool onChar(wxKeyEvent& ev);
virtual void onLoseFocus();
DECLARE_VALUE_EDITOR(PackageChoice);
virtual void draw(RotatedDC& dc);
virtual void determineSize(bool force_fit);
virtual bool onLeftDown (const RealPoint& pos, wxMouseEvent& ev);
virtual bool onChar(wxKeyEvent& ev);
virtual void onLoseFocus();
private:
DropDownListP drop_down;
friend class DropDownPackageChoiceList;
/// Change the choice
void change(const String& c);
/// Initialize the drop down list
void initDropDown();
DropDownListP drop_down;
friend class DropDownPackageChoiceList;
/// Change the choice
void change(const String& c);
/// Initialize the drop down list
void initDropDown();
};
+73 -73
View File
@@ -15,107 +15,107 @@
// ----------------------------------------------------------------------------- : SymbolValueEditor
IMPLEMENT_VALUE_EDITOR(Symbol)
, button_down(-2)
, button_down(-2)
{
button_images[0] = Bitmap(load_resource_image(_("edit_symbol")));
button_images[0] = Bitmap(load_resource_image(_("edit_symbol")));
}
void SymbolValueEditor::draw(RotatedDC& dc) {
SymbolValueViewer::draw(dc);
// draw helper text if there are no symbols
if (symbols.empty()) {
dc.SetFont(wxFont(10,wxSWISS,wxNORMAL,wxNORMAL));
dc.SetTextForeground(*wxBLACK);
RealSize text_size = dc.GetTextExtent(_("double click to edit symbol"));
dc.DrawText(_("double click to edit symbol"), align_in_rect(ALIGN_MIDDLE_CENTER, text_size, style().getInternalRect()));
}
if (nativeLook()) {
// draw editor buttons
dc.SetFont(*wxNORMAL_FONT);
drawButton(dc, 0, _BUTTON_("edit symbol"));
//drawButton(dc, 1, _BUTTON_("symbol gallery"));
}
SymbolValueViewer::draw(dc);
// draw helper text if there are no symbols
if (symbols.empty()) {
dc.SetFont(wxFont(10,wxSWISS,wxNORMAL,wxNORMAL));
dc.SetTextForeground(*wxBLACK);
RealSize text_size = dc.GetTextExtent(_("double click to edit symbol"));
dc.DrawText(_("double click to edit symbol"), align_in_rect(ALIGN_MIDDLE_CENTER, text_size, style().getInternalRect()));
}
if (nativeLook()) {
// draw editor buttons
dc.SetFont(*wxNORMAL_FONT);
drawButton(dc, 0, _BUTTON_("edit symbol"));
//drawButton(dc, 1, _BUTTON_("symbol gallery"));
}
}
void SymbolValueEditor::drawButton(RotatedDC& dc, int button, const String& text) {
bool down = button == button_down;
double height = style().height;
double width = style().height + 2;
double x = style().width - width - (width + 1) * button;
double y = 0;
// draw button
draw_button(&editor(), dc.getDC(), dc.trRectToBB(RealRect(x,y,width,height)), false, down, true);
// draw text
RealSize text_size = dc.GetTextExtent(text);
dc.DrawText(text, align_in_rect((Alignment)(ALIGN_BOTTOM | ALIGN_CENTER), text_size, RealRect(x, y, width,height*0.9)));
// draw image
const Bitmap& bmp = button_images[button];
RealSize image_size(bmp.GetWidth(), bmp.GetHeight());
dc.DrawBitmap(bmp, align_in_rect(ALIGN_MIDDLE_CENTER, image_size, RealRect(x,y,width,height * 0.8)));
bool down = button == button_down;
double height = style().height;
double width = style().height + 2;
double x = style().width - width - (width + 1) * button;
double y = 0;
// draw button
draw_button(&editor(), dc.getDC(), dc.trRectToBB(RealRect(x,y,width,height)), false, down, true);
// draw text
RealSize text_size = dc.GetTextExtent(text);
dc.DrawText(text, align_in_rect((Alignment)(ALIGN_BOTTOM | ALIGN_CENTER), text_size, RealRect(x, y, width,height*0.9)));
// draw image
const Bitmap& bmp = button_images[button];
RealSize image_size(bmp.GetWidth(), bmp.GetHeight());
dc.DrawBitmap(bmp, align_in_rect(ALIGN_MIDDLE_CENTER, image_size, RealRect(x,y,width,height * 0.8)));
}
int SymbolValueEditor::findButton(const RealPoint& pos) {
if (pos.y < 0 || pos.y >= style().height) return -1;
int button = (int)floor( (style().width - pos.x) / (style().height + 3) );
if (button >= 0 && button <= 1) return button;
return -1;
if (pos.y < 0 || pos.y >= style().height) return -1;
int button = (int)floor( (style().width - pos.x) / (style().height + 3) );
if (button >= 0 && button <= 1) return button;
return -1;
}
bool SymbolValueEditor::onLeftDown(const RealPoint& pos, wxMouseEvent&) {
if (!nativeLook()) return false;
int button = findButton(pos);
if (button != button_down) {
button_down = button;
viewer.redraw(*this);
}
return true;
if (!nativeLook()) return false;
int button = findButton(pos);
if (button != button_down) {
button_down = button;
viewer.redraw(*this);
}
return true;
}
bool SymbolValueEditor::onMotion(const RealPoint& pos, wxMouseEvent& ev) {
if (button_down != -2) {
int button = findButton(pos);
if (button != button_down) {
button_down = button;
viewer.redraw(*this);
}
}
return true;
if (button_down != -2) {
int button = findButton(pos);
if (button != button_down) {
button_down = button;
viewer.redraw(*this);
}
}
return true;
}
bool SymbolValueEditor::onLeftUp(const RealPoint& pos, wxMouseEvent&) {
if (!nativeLook()) return false;
if (button_down == 0) {
// edit
button_down = -2;
viewer.redraw(*this);
editSymbol();
return true;
} else if (button_down == 1) {
// gallery
button_down = -2;
viewer.redraw(*this);
// TODO
return true;
} else {
button_down = -2;
return false;
}
if (!nativeLook()) return false;
if (button_down == 0) {
// edit
button_down = -2;
viewer.redraw(*this);
editSymbol();
return true;
} else if (button_down == 1) {
// gallery
button_down = -2;
viewer.redraw(*this);
// TODO
return true;
} else {
button_down = -2;
return false;
}
}
bool SymbolValueEditor::onLeftDClick(const RealPoint& pos, wxMouseEvent&) {
// Use SetWindow as parent? Maybe not, the symbol editor will stay open when mainwindow closes
editSymbol();
return true;
// Use SetWindow as parent? Maybe not, the symbol editor will stay open when mainwindow closes
editSymbol();
return true;
}
void SymbolValueEditor::determineSize(bool) {
style().height = 50;
style().height = 50;
}
void SymbolValueEditor::editSymbol() {
SymbolWindow* wnd = new SymbolWindow(nullptr, getActionPerformer());
wnd->Show();
SymbolWindow* wnd = new SymbolWindow(nullptr, getActionPerformer());
wnd->Show();
}
ValueActionPerformer* SymbolValueEditor::getActionPerformer() {
return new ValueActionPerformer(valueP(), editor().getCard().get(), editor().getSetForActions());
return new ValueActionPerformer(valueP(), editor().getCard().get(), editor().getSetForActions());
}
+20 -20
View File
@@ -20,27 +20,27 @@ class ValueActionPerformer;
/// An editor 'control' for editing SymbolValues
class SymbolValueEditor : public SymbolValueViewer, public ValueEditor {
public:
DECLARE_VALUE_EDITOR(Symbol);
virtual void draw(RotatedDC& dc);
virtual bool onLeftDown (const RealPoint& pos, wxMouseEvent&);
virtual bool onLeftUp (const RealPoint& pos, wxMouseEvent&);
virtual bool onLeftDClick(const RealPoint& pos, wxMouseEvent&);
virtual bool onMotion (const RealPoint& pos, wxMouseEvent&);
virtual void determineSize(bool);
DECLARE_VALUE_EDITOR(Symbol);
virtual void draw(RotatedDC& dc);
virtual bool onLeftDown (const RealPoint& pos, wxMouseEvent&);
virtual bool onLeftUp (const RealPoint& pos, wxMouseEvent&);
virtual bool onLeftDClick(const RealPoint& pos, wxMouseEvent&);
virtual bool onMotion (const RealPoint& pos, wxMouseEvent&);
virtual void determineSize(bool);
private:
/// Draw a button, buttons are numbered from the right
void drawButton(RotatedDC& dc, int button, const String& text);
/// Is there a button at the given position? returns the button index, or -1 if there is no button
int findButton(const RealPoint& pos);
/// Show the symbol editor
void editSymbol();
/// Get an object to perform actions for us
ValueActionPerformer* getActionPerformer();
// button, or -1 for mouse down, but not on button, or -2 for mouse not down
int button_down;
Bitmap button_images[1];
/// Draw a button, buttons are numbered from the right
void drawButton(RotatedDC& dc, int button, const String& text);
/// Is there a button at the given position? returns the button index, or -1 if there is no button
int findButton(const RealPoint& pos);
/// Show the symbol editor
void editSymbol();
/// Get an object to perform actions for us
ValueActionPerformer* getActionPerformer();
// button, or -1 for mouse down, but not on button, or -2 for mouse not down
int button_down;
Bitmap button_images[1];
};
// ----------------------------------------------------------------------------- : EOF
+1179 -1179
View File
File diff suppressed because it is too large Load Diff
+154 -154
View File
@@ -21,8 +21,8 @@ DECLARE_SHARED_POINTER_TYPE(DropDownWordList);
// ----------------------------------------------------------------------------- : TextValueEditor
enum IndexType
{ TYPE_CURSOR ///< Positions are cursor positions
, TYPE_INDEX ///< Positions are character indices
{ TYPE_CURSOR ///< Positions are cursor positions
, TYPE_INDEX ///< Positions are character indices
};
/// An editor 'control' for editing TextValues
@@ -30,161 +30,161 @@ enum IndexType
*/
class TextValueEditor : public TextValueViewer, public ValueEditor {
public:
DECLARE_VALUE_EDITOR(Text);
~TextValueEditor();
// --------------------------------------------------- : Events
virtual void onFocus();
virtual void onLoseFocus();
virtual bool onLeftDown (const RealPoint& pos, wxMouseEvent&);
virtual bool onLeftUp (const RealPoint& pos, wxMouseEvent&);
virtual bool onLeftDClick(const RealPoint& pos, wxMouseEvent&);
virtual bool onRightDown (const RealPoint& pos, wxMouseEvent&);
virtual bool onMotion (const RealPoint& pos, wxMouseEvent&);
virtual void onMouseLeave(const RealPoint& pos, wxMouseEvent&);
virtual bool onMouseWheel(const RealPoint& pos, wxMouseEvent&);
virtual bool onContextMenu(IconMenu& m, wxContextMenuEvent&);
virtual wxMenu* getMenu(int type) const;
virtual bool onCommand(int);
virtual bool onChar(wxKeyEvent&);
// --------------------------------------------------- : Actions
virtual void onValueChange();
virtual void onAction(const Action&, bool undone);
// --------------------------------------------------- : Clipboard
virtual bool canCopy() const;
virtual bool canPaste() const;
virtual bool doCopy();
virtual bool doPaste();
virtual bool doDelete();
// --------------------------------------------------- : Formating
virtual bool canFormat(int type) const;
virtual bool hasFormat(int type) const;
virtual void doFormat(int type);
// --------------------------------------------------- : Selection
virtual void select(size_t start, size_t end);
virtual size_t selectionStart() const { return selection_start; }
virtual size_t selectionEnd() const { return selection_end; }
virtual void insert(const String& text, const String& action_name);
// --------------------------------------------------- : Search/replace
virtual bool search(FindInfo& find, bool from_start);
DECLARE_VALUE_EDITOR(Text);
~TextValueEditor();
// --------------------------------------------------- : Events
virtual void onFocus();
virtual void onLoseFocus();
virtual bool onLeftDown (const RealPoint& pos, wxMouseEvent&);
virtual bool onLeftUp (const RealPoint& pos, wxMouseEvent&);
virtual bool onLeftDClick(const RealPoint& pos, wxMouseEvent&);
virtual bool onRightDown (const RealPoint& pos, wxMouseEvent&);
virtual bool onMotion (const RealPoint& pos, wxMouseEvent&);
virtual void onMouseLeave(const RealPoint& pos, wxMouseEvent&);
virtual bool onMouseWheel(const RealPoint& pos, wxMouseEvent&);
virtual bool onContextMenu(IconMenu& m, wxContextMenuEvent&);
virtual wxMenu* getMenu(int type) const;
virtual bool onCommand(int);
virtual bool onChar(wxKeyEvent&);
// --------------------------------------------------- : Actions
virtual void onValueChange();
virtual void onAction(const Action&, bool undone);
// --------------------------------------------------- : Clipboard
virtual bool canCopy() const;
virtual bool canPaste() const;
virtual bool doCopy();
virtual bool doPaste();
virtual bool doDelete();
// --------------------------------------------------- : Formating
virtual bool canFormat(int type) const;
virtual bool hasFormat(int type) const;
virtual void doFormat(int type);
// --------------------------------------------------- : Selection
virtual void select(size_t start, size_t end);
virtual size_t selectionStart() const { return selection_start; }
virtual size_t selectionEnd() const { return selection_end; }
virtual void insert(const String& text, const String& action_name);
// --------------------------------------------------- : Search/replace
virtual bool search(FindInfo& find, bool from_start);
private:
bool matchSubstr(const String& s, size_t pos, FindInfo& find);
bool matchSubstr(const String& s, size_t pos, FindInfo& find);
public:
// --------------------------------------------------- : Other
virtual wxCursor cursor(const RealPoint& pos) const;
virtual void determineSize(bool force_fit = false);
virtual bool containsPoint(const RealPoint& p) const;
virtual RealRect boundingBox() const;
virtual void onShow(bool);
virtual void draw(RotatedDC&);
// --------------------------------------------------- : Data
// --------------------------------------------------- : Other
virtual wxCursor cursor(const RealPoint& pos) const;
virtual void determineSize(bool force_fit = false);
virtual bool containsPoint(const RealPoint& p) const;
virtual RealRect boundingBox() const;
virtual void onShow(bool);
virtual void draw(RotatedDC&);
// --------------------------------------------------- : Data
private:
size_t selection_start, selection_end; ///< Cursor position/selection (if any), cursor positions
size_t selection_start_i, selection_end_i; ///< Cursor position/selection, character indices
bool selecting; ///< Selecting text?
bool select_words; ///< Select whole words when dragging the mouse?
TextValueEditorScrollBar* scrollbar; ///< Scrollbar for multiline fields in native look
bool scroll_with_cursor; ///< When the cursor moves, should the scrollposition change?
vector<WordListPosP> word_lists; ///< Word lists in the text
// --------------------------------------------------- : Selection / movement
/// Move the selection to a new location, clears the previously drawn selection.
/** t specifies what kind of position new_end is */
void moveSelection(IndexType t, size_t new_end, bool also_move_start=true, Movement dir = MOVE_MID);
/// Move the selection to a new location, but does not redraw.
/** t specifies what kind of position new_end is */
void moveSelectionNoRedraw(IndexType t, size_t new_end, bool also_move_start=true, Movement dir = MOVE_MID);
/// Redraw the selection
void redrawSelection(size_t old_selection_start_i, size_t old_selection_end_i, bool old_drop_down_shown);
/// Replace the current selection with 'replacement', name the action
/** replacement should be a tagged string (i.e. already escaped) */
void replaceSelection(const String& replacement, const String& name, bool allow_auto_replace = false, bool select_on_undo = true);
/// Try to autoreplace at the position before the cursor
void tryAutoReplace();
/// Make sure the selection satisfies its constraints
/** - selection_start and selection_end are inside the text
* - not inside tags
* - the selection does not contain a <sep> or </sep> tag
*
* When correcting the selection, move in the given direction
*/
void fixSelection(IndexType t = TYPE_CURSOR, Movement dir = MOVE_MID);
/// Return a position resulting from moving pos outside the range [start...end), in the direction dir
static size_t move(size_t pos, size_t start, size_t end, Movement dir);
/// Move the caret to the selection_end position and show it
void showCaret();
/// Position of previous visible & selectable character
/** Uses cursor positions */
size_t prevCharBoundary(size_t pos) const;
size_t nextCharBoundary(size_t pos) const;
/// Front of previous word, used witch Ctrl+Left/right
/** Uses character indices */
size_t prevWordBoundary(size_t pos_i) const;
size_t nextWordBoundary(size_t pos_i) const;
bool isWordBoundary(size_t pos_i) const;
// --------------------------------------------------- : Scrolling
friend class TextValueEditorScrollBar;
/// Scroll to the given position, called by scrollbar
void scrollTo(int pos);
/// Update the scrollbar to show the current scroll position
void updateScrollbar();
/// Scrolls to ensure the caret stays visible, return true if the control is scrolled
bool ensureCaretVisible();
/// Prepare for drawing if there is a scrollbar
void prepareDrawScrollbar(RotatedDC& dc);
// --------------------------------------------------- : Word lists
friend class DropDownWordList;
DropDownWordListP drop_down;
bool dropDownShown() const;
mutable WordListPos* hovered_words;
/// Find all word lists in the current value
void findWordLists();
/// Draw word list indicators
void drawWordListIndicators(RotatedDC& dc, bool redrawing = false);
/// Remove word list indicators
void clearWordListIndicators(RotatedDC& dc);
/// Re-draw word list indicators
void redrawWordListIndicators(bool toggling_dropdown = false);
/// Find a WordListPos under the mouse cursor (if any), pos is in internal coordinates
WordListPosP findWordList(const RealPoint& pos) const;
/// Find a WordListPos rectangle under the mouse cursor (if any), pos is in internal coordinates
WordListPosP findWordListBody(const RealPoint& pos) const;
/// Find a WordListPos for a index position
WordListPosP findWordList(size_t index) const;
/// Show a word list drop down menu, if wl. Returns true if a list is shown
bool wordListDropDown(const WordListPosP& wl);
size_t selection_start, selection_end; ///< Cursor position/selection (if any), cursor positions
size_t selection_start_i, selection_end_i; ///< Cursor position/selection, character indices
bool selecting; ///< Selecting text?
bool select_words; ///< Select whole words when dragging the mouse?
TextValueEditorScrollBar* scrollbar; ///< Scrollbar for multiline fields in native look
bool scroll_with_cursor; ///< When the cursor moves, should the scrollposition change?
vector<WordListPosP> word_lists; ///< Word lists in the text
// --------------------------------------------------- : Selection / movement
/// Move the selection to a new location, clears the previously drawn selection.
/** t specifies what kind of position new_end is */
void moveSelection(IndexType t, size_t new_end, bool also_move_start=true, Movement dir = MOVE_MID);
/// Move the selection to a new location, but does not redraw.
/** t specifies what kind of position new_end is */
void moveSelectionNoRedraw(IndexType t, size_t new_end, bool also_move_start=true, Movement dir = MOVE_MID);
/// Redraw the selection
void redrawSelection(size_t old_selection_start_i, size_t old_selection_end_i, bool old_drop_down_shown);
/// Replace the current selection with 'replacement', name the action
/** replacement should be a tagged string (i.e. already escaped) */
void replaceSelection(const String& replacement, const String& name, bool allow_auto_replace = false, bool select_on_undo = true);
/// Try to autoreplace at the position before the cursor
void tryAutoReplace();
/// Make sure the selection satisfies its constraints
/** - selection_start and selection_end are inside the text
* - not inside tags
* - the selection does not contain a <sep> or </sep> tag
*
* When correcting the selection, move in the given direction
*/
void fixSelection(IndexType t = TYPE_CURSOR, Movement dir = MOVE_MID);
/// Return a position resulting from moving pos outside the range [start...end), in the direction dir
static size_t move(size_t pos, size_t start, size_t end, Movement dir);
/// Move the caret to the selection_end position and show it
void showCaret();
/// Position of previous visible & selectable character
/** Uses cursor positions */
size_t prevCharBoundary(size_t pos) const;
size_t nextCharBoundary(size_t pos) const;
/// Front of previous word, used witch Ctrl+Left/right
/** Uses character indices */
size_t prevWordBoundary(size_t pos_i) const;
size_t nextWordBoundary(size_t pos_i) const;
bool isWordBoundary(size_t pos_i) const;
// --------------------------------------------------- : Scrolling
friend class TextValueEditorScrollBar;
/// Scroll to the given position, called by scrollbar
void scrollTo(int pos);
/// Update the scrollbar to show the current scroll position
void updateScrollbar();
/// Scrolls to ensure the caret stays visible, return true if the control is scrolled
bool ensureCaretVisible();
/// Prepare for drawing if there is a scrollbar
void prepareDrawScrollbar(RotatedDC& dc);
// --------------------------------------------------- : Word lists
friend class DropDownWordList;
DropDownWordListP drop_down;
bool dropDownShown() const;
mutable WordListPos* hovered_words;
/// Find all word lists in the current value
void findWordLists();
/// Draw word list indicators
void drawWordListIndicators(RotatedDC& dc, bool redrawing = false);
/// Remove word list indicators
void clearWordListIndicators(RotatedDC& dc);
/// Re-draw word list indicators
void redrawWordListIndicators(bool toggling_dropdown = false);
/// Find a WordListPos under the mouse cursor (if any), pos is in internal coordinates
WordListPosP findWordList(const RealPoint& pos) const;
/// Find a WordListPos rectangle under the mouse cursor (if any), pos is in internal coordinates
WordListPosP findWordListBody(const RealPoint& pos) const;
/// Find a WordListPos for a index position
WordListPosP findWordList(size_t index) const;
/// Show a word list drop down menu, if wl. Returns true if a list is shown
bool wordListDropDown(const WordListPosP& wl);
};
// ----------------------------------------------------------------------------- : EOF