Commit 2fdd7eb9 authored by twanvl's avatar twanvl

Various tweaks and fixes, mostly to the drop down lists

parent 872d1463
...@@ -442,11 +442,13 @@ init script: ...@@ -442,11 +442,13 @@ init script:
cmc := to_text + { cmc := to_text + {
1 * number_of_items(in: sort_text(order:"SWUBRG")) # colored mana 1 * number_of_items(in: sort_text(order:"SWUBRG")) # colored mana
- 1 * number_of_items(in: sort_text(order:"/")) # guild mana, W/U -> 2 - 1 - 1 * number_of_items(in: sort_text(order:"/")) # guild mana, W/U -> 2 - 1
+ 1 * sort_text(order: "[0123456789]") # colorless mana + 1 * filter_text(match: "^[0123456789]+(?!/)") # colorless mana, but not 1/2
+ 1 * (length(sort_text(order:"compound(1/2)")) / 3) # compensate for 1/2. Should actually be 1.5 *
} }
colored_mana := to_text + { colored_mana := to_text + {
number_of_items(in: sort_text(order: "WUBRG")) # colored mana number_of_items(in: sort_text(order: "WUBRG")) # colored mana
- number_of_items(in: sort_text(order:"/")) # guild mana, W/U -> 2 - 1 - number_of_items(in: sort_text(order:"/")) # guild mana, W/U -> 2 - 1
+ 1 * (length(sort_text(order:"compound(1/2)")) / 3) # compensate for 1/2.
} }
primary_card_color := { primary_card_color := {
artifact := chosen(choice:"artifact") artifact := chosen(choice:"artifact")
...@@ -1236,10 +1238,14 @@ word list: ...@@ -1236,10 +1238,14 @@ word list:
is prefix: true is prefix: true
word: word:
name: Legendary name: Legendary
line below: true
is prefix: true is prefix: true
word:
name: Tribal
is prefix: true
line below: true
word: Creature word: Creature
word: Artifact word: Artifact
word: Artifact Creature
word: Enchantment word: Enchantment
word: Instant word: Instant
word: Sorcery word: Sorcery
...@@ -1256,11 +1262,15 @@ word list: ...@@ -1256,11 +1262,15 @@ word list:
word list: word list:
name: artifact name: artifact
word: word:
name:
line below: true
word: Equipment word: Equipment
word list: word list:
name: land name: land
word: word:
name:
line below: true
word: Plains word: Plains
word: Island word: Island
word: Swamp word: Swamp
...@@ -1270,11 +1280,15 @@ word list: ...@@ -1270,11 +1280,15 @@ word list:
word list: word list:
name: enchantment name: enchantment
word: word:
name:
line below: true
word: Aura word: Aura
word list: word list:
name: spell name: spell
word: word:
name:
line below: true
word: Arcane word: Arcane
...@@ -1455,6 +1469,9 @@ keyword parameter type: ...@@ -1455,6 +1469,9 @@ keyword parameter type:
# match: [A-Z][a-z, ]*([A-Z][a-z, ]*\xEB00) # commented out because it stopped prefix param from working, version below allows all "walks", including "Dame Judi Denchwalk", doesn't trigger #in middle of sentences, and doesn't trigger in chains of keywords. # match: [A-Z][a-z, ]*([A-Z][a-z, ]*\xEB00) # commented out because it stopped prefix param from working, version below allows all "walks", including "Dame Judi Denchwalk", doesn't trigger #in middle of sentences, and doesn't trigger in chains of keywords.
match: [A-Z][A-Z,a-z ]* match: [A-Z][A-Z,a-z ]*
example: Forest example: Forest
keyword parameter type:
name: a
match: an?
############################# All Magic keywords ############################# All Magic keywords
# By JrEye and Neko_Asakami, Updated by Pichoro and Buttock1234 # By JrEye and Neko_Asakami, Updated by Pichoro and Buttock1234
...@@ -1872,3 +1889,8 @@ keyword: ...@@ -1872,3 +1889,8 @@ keyword:
match: Grandeur match: Grandeur
mode: pseudo mode: pseudo
rules: Grandeur — Discard another card named ~: [effect]. rules: Grandeur — Discard another card named ~: [effect].
keyword:
keyword: Champion
match: Champion <atom-param>a</atom-param> <atom-param>name</atom-param>
mode: core
reminder: When this comes into play, sacrifice it unless you remove another {param2} you control from the game. When this leaves play, that card returns to play.
...@@ -6,6 +6,8 @@ A word in a [[type:word list]]. ...@@ -6,6 +6,8 @@ A word in a [[type:word list]].
! Property Type Default Description ! Property Type Default Description
| @name@ [[type:string]] ''Required'' The word | @name@ [[type:string]] ''Required'' The word
| @line below@ [[type:boolean]] @false@ Display a line below this item in the list? | @line below@ [[type:boolean]] @false@ Display a line below this item in the list?
| @is prefix@ [[type:boolean]] @false@ Should this word be used as a prefix before another word from the list?<br/>
Think "Legendary ". Note the space after it, words are directly concatenated.
| @words@ [[type:list]] of [[type:word list word]]s A submenu | @words@ [[type:list]] of [[type:word list word]]s A submenu
A word can also be given in a short form, in that case only the name is specified. A word can also be given in a short form, in that case only the name is specified.
......
...@@ -81,18 +81,22 @@ void set_alpha(Image& img, const Image& img_alpha) { ...@@ -81,18 +81,22 @@ void set_alpha(Image& img, const Image& img_alpha) {
} }
if (!img.HasAlpha()) img.InitAlpha(); if (!img.HasAlpha()) img.InitAlpha();
Byte *im = img.GetAlpha(), *al = img_alpha.GetData(); Byte *im = img.GetAlpha(), *al = img_alpha.GetData();
UInt size = img.GetWidth() * img.GetHeight(); size_t size = img.GetWidth() * img.GetHeight();
for (UInt i = 0 ; i < size ; ++i) { for (size_t i = 0 ; i < size ; ++i) {
im[i] = (im[i] * al[i*3]) / 255; im[i] = (im[i] * al[i*3]) / 255;
} }
} }
void set_alpha(Image& img, double alpha) { void set_alpha(Image& img, double alpha) {
if (!img.HasAlpha()) img.InitAlpha();
Byte b_alpha = alpha * 255; Byte b_alpha = alpha * 255;
if (!img.HasAlpha()) {
img.InitAlpha();
memset(img.GetAlpha(), b_alpha, img.GetWidth() * img.GetHeight());
} else {
Byte *im = img.GetAlpha(); Byte *im = img.GetAlpha();
UInt size = img.GetWidth() * img.GetHeight(); size_t size = img.GetWidth() * img.GetHeight();
for (UInt i = 0 ; i < size ; ++i) { for (size_t i = 0 ; i < size ; ++i) {
im[i] = (im[i] * b_alpha) / 255; im[i] = (im[i] * b_alpha) / 255;
} }
}
} }
...@@ -98,21 +98,30 @@ bool CardViewer::shouldDraw(const ValueViewer& v) const { ...@@ -98,21 +98,30 @@ bool CardViewer::shouldDraw(const ValueViewer& v) const {
} }
// helper class for overdrawDC() // helper class for overdrawDC()
class CardViewer::OverdrawDC : private wxClientDC, public wxBufferedDC { class CardViewer::OverdrawDC_aux : private wxClientDC {
public: protected:
OverdrawDC(CardViewer* window) wxBufferedDC bufferedDC;
OverdrawDC_aux(CardViewer* window)
: wxClientDC(window) : wxClientDC(window)
{ {
wxBufferedDC::Init((wxClientDC*)this, window->buffer); bufferedDC.Init((wxClientDC*)this, window->buffer);
} }
}; };
class CardViewer::OverdrawDC : private OverdrawDC_aux, public RotatedDC {
public:
OverdrawDC(CardViewer* window)
: OverdrawDC_aux(window)
, RotatedDC(bufferedDC, window->getRotation(), QUALITY_LOW)
{}
};
shared_ptr<DC> CardViewer::overdrawDC() { shared_ptr<RotatedDC> CardViewer::overdrawDC() {
#ifdef _DEBUG #ifdef _DEBUG
// don't call from onPaint // don't call from onPaint
assert(!inOnPaint()); assert(!inOnPaint());
#endif #endif
return shared_ptr<DC>((wxBufferedDC*)new OverdrawDC(this)); return shared_ptr<RotatedDC>(new OverdrawDC(this));
} }
Rotation CardViewer::getRotation() const { Rotation CardViewer::getRotation() const {
......
...@@ -28,7 +28,7 @@ class CardViewer : public wxControl, public DataViewer { ...@@ -28,7 +28,7 @@ class CardViewer : public wxControl, public DataViewer {
/// Get a dc to draw on the card outside onPaint /// Get a dc to draw on the card outside onPaint
/** May NOT be called while in onPaint/draw */ /** May NOT be called while in onPaint/draw */
shared_ptr<DC> overdrawDC(); shared_ptr<RotatedDC> overdrawDC();
/// Invalidate and redraw the entire viewer /// Invalidate and redraw the entire viewer
void redraw(); void redraw();
...@@ -59,6 +59,7 @@ class CardViewer : public wxControl, public DataViewer { ...@@ -59,6 +59,7 @@ class CardViewer : public wxControl, public DataViewer {
bool up_to_date; ///< Is the buffer up to date? bool up_to_date; ///< Is the buffer up to date?
class OverdrawDC; class OverdrawDC;
class OverdrawDC_aux;
}; };
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
......
...@@ -87,16 +87,16 @@ GraphData::GraphData(const GraphDataPre& d) ...@@ -87,16 +87,16 @@ GraphData::GraphData(const GraphDataPre& d)
left--; left--;
} }
} }
// drop empty tail
while (a->groups.size() > 1 && a->groups.back().size == 0) {
a->groups.pop_back();
}
// Also keep non-numeric entries // Also keep non-numeric entries
FOR_EACH(c, counts) { FOR_EACH(c, counts) {
a->groups.push_back(GraphGroup(c.first, c.second)); a->groups.push_back(GraphGroup(c.first, c.second));
a->max = max(a->max, c.second); a->max = max(a->max, c.second);
a->total += c.second; a->total += c.second;
} }
// drop empty tail
while (a->groups.size() > 1 && a->groups.back().size == 0) {
a->groups.pop_back();
}
} else if (a->order) { } else if (a->order) {
// specific group order // specific group order
FOR_EACH_CONST(gn, *a->order) { FOR_EACH_CONST(gn, *a->order) {
......
...@@ -138,7 +138,7 @@ void DropDownList::show(bool in_place, wxPoint pos, RealRect* rect) { ...@@ -138,7 +138,7 @@ void DropDownList::show(bool in_place, wxPoint pos, RealRect* rect) {
if (selected_item == NO_SELECTION && itemCount() > 0) selected_item = 0; // select first item by default if (selected_item == NO_SELECTION && itemCount() > 0) selected_item = 0; // select first item by default
mouse_down = false; mouse_down = false;
Window::Show(); Window::Show();
if (!parent_menu && GetParent()->HasCapture()) { if (isRoot() && GetParent()->HasCapture()) {
// release capture on parent // release capture on parent
GetParent()->ReleaseMouse(); GetParent()->ReleaseMouse();
} }
...@@ -168,7 +168,7 @@ void DropDownList::hide(bool event, bool allow_veto) { ...@@ -168,7 +168,7 @@ void DropDownList::hide(bool event, bool allow_veto) {
void DropDownList::realHide() { void DropDownList::realHide() {
if (!IsShown()) return; if (!IsShown()) return;
Window::Hide(); Window::Hide();
// onHide(); onHide();
hideSubMenu(); hideSubMenu();
if (parent_menu) { if (parent_menu) {
parent_menu->open_sub_menu = nullptr; parent_menu->open_sub_menu = nullptr;
...@@ -226,7 +226,12 @@ int DropDownList::itemPosition(size_t item) const { ...@@ -226,7 +226,12 @@ int DropDownList::itemPosition(size_t item) const {
void DropDownList::redrawArrowOnParent() { void DropDownList::redrawArrowOnParent() {
if (viewer) { if (viewer) {
ValueEditor* e = viewer->getEditor(); ValueEditor* e = viewer->getEditor();
if (e) e->redraw(); if (e && viewer->viewer.nativeLook()) {
CardEditor& editor = static_cast<CardEditor&>(viewer->viewer);
shared_ptr<RotatedDC> dcP = editor.overdrawDC();
RotatedDC& dc = *dcP;
draw_drop_down_arrow(&editor, dc.getDC(), dc.tr(viewer->getStyle()->getRect().grow(1)), IsShown());
}
} }
} }
......
...@@ -45,6 +45,10 @@ class DropDownList : public wxPopupWindow { ...@@ -45,6 +45,10 @@ class DropDownList : public wxPopupWindow {
/// Prepare for showing the list /// Prepare for showing the list
virtual void onShow() {} virtual void onShow() {}
/// Do something after hiding the list
virtual void onHide() {}
inline bool isRoot() { return parent_menu == nullptr; }
// --------------------------------------------------- : Selection // --------------------------------------------------- : Selection
static const size_t NO_SELECTION = (size_t)-1; static const size_t NO_SELECTION = (size_t)-1;
...@@ -98,9 +102,7 @@ class DropDownList : public wxPopupWindow { ...@@ -98,9 +102,7 @@ class DropDownList : public wxPopupWindow {
void onPaint(wxPaintEvent&); void onPaint(wxPaintEvent&);
void onLeftDown(wxMouseEvent&); void onLeftDown(wxMouseEvent&);
void onLeftUp (wxMouseEvent&); void onLeftUp (wxMouseEvent&);
protected: void onMotion(wxMouseEvent&);
virtual void onMotion(wxMouseEvent&); // allow override
private:
// --------------------------------------------------- : Privates // --------------------------------------------------- : Privates
...@@ -115,7 +117,8 @@ class DropDownList : public wxPopupWindow { ...@@ -115,7 +117,8 @@ class DropDownList : public wxPopupWindow {
void draw(DC& dc); void draw(DC& dc);
void drawItem(DC& dc, int y, size_t item); void drawItem(DC& dc, int y, size_t item);
void redrawArrowOnParent(); protected:
virtual void redrawArrowOnParent(); // allow override
}; };
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
......
This diff is collapsed.
...@@ -111,6 +111,9 @@ class TextValueEditor : public TextValueViewer, public ValueEditor { ...@@ -111,6 +111,9 @@ class TextValueEditor : public TextValueViewer, public ValueEditor {
/** t specifies what kind of position new_end is */ /** 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); 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 /// Replace the current selection with 'replacement', name the action
/** replacement should be a tagged string (i.e. already escaped) */ /** replacement should be a tagged string (i.e. already escaped) */
void replaceSelection(const String& replacement, const String& name); void replaceSelection(const String& replacement, const String& name);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
// ----------------------------------------------------------------------------- : SymbolTextElement // ----------------------------------------------------------------------------- : SymbolTextElement
void SymbolTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end) const { void SymbolTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end) const {
if (!(what & DRAW_NORMAL)) return;
if (font.font) { if (font.font) {
font.font->draw(dc, ctx, rect, font.size * scale, font.alignment, content.substr(start - this->start, end-start)); font.font->draw(dc, ctx, rect, font.size * scale, font.alignment, content.substr(start - this->start, end-start));
} }
......
...@@ -40,9 +40,9 @@ struct TextViewer::Line { ...@@ -40,9 +40,9 @@ struct TextViewer::Line {
return top + line_height > 0 && top < rot.getInternalSize().height; return top + line_height > 0 && top < rot.getInternalSize().height;
} }
/// Draws a selection indicator on this line from start to end /// Get a rectangle of the selection on this line
/** start and end need not be in this line */ /** start and end need not be in this line */
void drawSelection(RotatedDC& dc, size_t start, size_t end); RealRect selectionRectangle(const Rotation& rot, size_t start, size_t end);
}; };
size_t TextViewer::Line::posToIndex(double x) const { size_t TextViewer::Line::posToIndex(double x) const {
...@@ -89,6 +89,13 @@ void TextViewer::draw(RotatedDC& dc, const TextStyle& style, DrawWhat what) { ...@@ -89,6 +89,13 @@ void TextViewer::draw(RotatedDC& dc, const TextStyle& style, DrawWhat what) {
} }
} }
/// Intersection between two rectangles
RealRect intersect(const RealRect& a, const RealRect& b) {
RealPoint tl = piecewise_max(a.topLeft(), b.topLeft());
RealPoint br = piecewise_min(a.bottomRight(), b.bottomRight());
return RealRect(tl, RealSize(br - tl));
}
void TextViewer::drawSelection(RotatedDC& dc, const TextStyle& style, size_t sel_start, size_t sel_end) { void TextViewer::drawSelection(RotatedDC& dc, const TextStyle& style, size_t sel_start, size_t sel_end) {
Rotater r(dc, style.getRotation()); Rotater r(dc, style.getRotation());
if (sel_start == sel_end) return; if (sel_start == sel_end) return;
...@@ -96,18 +103,25 @@ void TextViewer::drawSelection(RotatedDC& dc, const TextStyle& style, size_t sel ...@@ -96,18 +103,25 @@ void TextViewer::drawSelection(RotatedDC& dc, const TextStyle& style, size_t sel
dc.SetBrush(*wxBLACK_BRUSH); dc.SetBrush(*wxBLACK_BRUSH);
dc.SetPen(*wxTRANSPARENT_PEN); dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetLogicalFunction(wxINVERT); dc.SetLogicalFunction(wxINVERT);
RealRect prev_rect(0,0,0,0);
FOR_EACH(l, lines) { FOR_EACH(l, lines) {
l.drawSelection(dc, sel_start, sel_end); RealRect rect = l.selectionRectangle(dc, sel_start, sel_end);
if (rect.height > 0) dc.DrawRectangle(rect);
// compensate for overlap between lines
RealRect overlap = intersect(rect, prev_rect);
if (overlap.height > 0 && overlap.width > 0) dc.DrawRectangle(overlap);
prev_rect = rect;
} }
dc.SetLogicalFunction(wxCOPY); dc.SetLogicalFunction(wxCOPY);
} }
void TextViewer::Line::drawSelection(RotatedDC& dc, size_t sel_start, size_t sel_end) { RealRect TextViewer::Line::selectionRectangle(const Rotation& rot, size_t sel_start, size_t sel_end) {
if (!visible(dc)) return; if (visible(rot) && sel_start < end() && sel_end > start) {
if (sel_start < end() && sel_end > start) {
double x1 = positions[max(start, sel_start) - start]; double x1 = positions[max(start, sel_start) - start];
double x2 = positions[min(end(), sel_end) - start]; double x2 = positions[min(end(), sel_end) - start];
dc.DrawRectangle(RealRect(x1, top, x2 - x1, line_height)); return RealRect(x1, top, x2 - x1, line_height);
} else {
return RealRect(0,0,0,0);
} }
} }
......
...@@ -37,7 +37,7 @@ void ChoiceValueViewer::draw(RotatedDC& dc) { ...@@ -37,7 +37,7 @@ void ChoiceValueViewer::draw(RotatedDC& dc) {
} else { } else {
img_options.width = (int) dc.trX(style().width); img_options.width = (int) dc.trX(style().width);
img_options.height = (int) dc.trY(style().height); img_options.height = (int) dc.trY(style().height);
img_options.preserve_aspect = style().alignment == ALIGN_STRETCH ? ASPECT_STRETCH : ASPECT_FIT; img_options.preserve_aspect = (style().alignment & ALIGN_STRETCH) ? ASPECT_STRETCH : ASPECT_FIT;
} }
Image image = img.generate(img_options, true); Image image = img.generate(img_options, true);
ImageCombine combine = img.combine(); ImageCombine combine = img.combine();
......
...@@ -70,8 +70,8 @@ void ColorValueViewer::draw(RotatedDC& dc) { ...@@ -70,8 +70,8 @@ void ColorValueViewer::draw(RotatedDC& dc) {
bool ColorValueViewer::containsPoint(const RealPoint& p) const { bool ColorValueViewer::containsPoint(const RealPoint& p) const {
// distance to each side // distance to each side
double left = p.x - style().left, right = style().left + style().width - p.x - 1; double left = p.x - style().left, right = style().right - p.x - 1;
double top = p.y - style().top, bottom = style().top + style().height - p.y - 1; double top = p.y - style().top, bottom = style().bottom - p.y - 1;
if (left < 0 || right < 0 || top < 0 || bottom < 0 || // outside bounding box if (left < 0 || right < 0 || top < 0 || bottom < 0 || // outside bounding box
(left >= style().left_width && right >= style().right_width && // outside horizontal border (left >= style().left_width && right >= style().right_width && // outside horizontal border
top >= style().top_width && bottom >= style().bottom_width)) { // outside vertical border top >= style().top_width && bottom >= style().bottom_width)) { // outside vertical border
......
...@@ -29,10 +29,12 @@ void TextValueViewer::draw(RotatedDC& dc) { ...@@ -29,10 +29,12 @@ void TextValueViewer::draw(RotatedDC& dc) {
if (!v.prepared()) { if (!v.prepared()) {
v.prepare(dc, value().value(), style(), viewer.getContext()); v.prepare(dc, value().value(), style(), viewer.getContext());
} }
if (viewer.drawFocus() && isCurrent()) {
v.draw(dc, style(), DRAW_ACTIVE);
}
v.draw(dc, style(), (DrawWhat)( v.draw(dc, style(), (DrawWhat)(
DRAW_NORMAL DRAW_NORMAL
| (viewer.drawBorders() ? DRAW_BORDERS : 0) | (viewer.drawBorders() ? DRAW_BORDERS : 0)
| (viewer.drawFocus() && isCurrent() ? DRAW_ACTIVE : 0)
)); ));
} }
......
...@@ -600,7 +600,7 @@ void init_script_basic_functions(Context& ctx) { ...@@ -600,7 +600,7 @@ void init_script_basic_functions(Context& ctx) {
ctx.setVariable(_("tag remove rule"), script_tag_remove_rule); ctx.setVariable(_("tag remove rule"), script_tag_remove_rule);
// collection // collection
ctx.setVariable(_("position"), script_position_of); ctx.setVariable(_("position"), script_position_of);
ctx.setVariable(_("length"), script_number_of_items); ctx.setVariable(_("length"), script_length);
ctx.setVariable(_("number of items"), script_number_of_items); ctx.setVariable(_("number of items"), script_number_of_items);
ctx.setVariable(_("filter list"), script_filter_list); ctx.setVariable(_("filter list"), script_filter_list);
ctx.setVariable(_("sort list"), script_sort_list); ctx.setVariable(_("sort list"), script_sort_list);
......
...@@ -169,7 +169,8 @@ void mixed_sort(const String& spec, String& input, String& ret) { ...@@ -169,7 +169,8 @@ void mixed_sort(const String& spec, String& input, String& ret) {
/// Sort a string, find a compound item /// Sort a string, find a compound item
/** Removed used characters from input! */ /** Removed used characters from input! */
void compound_sort(const String& spec, String& input, String& ret) { void compound_sort(const String& spec, String& input, String& ret) {
while (size_t pos = input.find(spec)) { size_t pos = input.find(spec);
while (pos != String::npos) {
ret += spec; ret += spec;
for (size_t j = 0 ; j < spec.size() ; ++j) input.SetChar(pos + j, REMOVED); for (size_t j = 0 ; j < spec.size() ; ++j) input.SetChar(pos + j, REMOVED);
pos = input.find(spec, pos + 1); pos = input.find(spec, pos + 1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment