mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
add font picker, color picker and bullet point ui tools
This commit is contained in:
+183
-21
@@ -102,40 +102,202 @@ TextValue& TextValueAction::value() const {
|
||||
}
|
||||
|
||||
|
||||
unique_ptr<TextValueAction> toggle_format_action(const TextValueP& value, vector<String>& tags, size_t start_i, size_t end_i, size_t start, size_t end, const String& action_name) {
|
||||
if (start > end) {
|
||||
swap(start, end);
|
||||
swap(start_i, end_i);
|
||||
}
|
||||
// Find absolute position of the selection
|
||||
String new_value = value->value();
|
||||
size_t untagged_start_i = to_untagged_pos(new_value, start_i);
|
||||
size_t untagged_end_i = to_untagged_pos(new_value, end_i);
|
||||
int offset = 0;
|
||||
// Compute the changes
|
||||
for (int i = 0; i < tags.size() ; ++i) {
|
||||
const String& tag = tags[i];
|
||||
new_value = tag.Contains(":") ? compute_new_variable_value(new_value, tag, start_i, end_i):
|
||||
tag == _("li") ? compute_new_bullet_value (new_value, offset, start_i, end_i):
|
||||
compute_new_simple_value (new_value, tag, start_i, end_i);
|
||||
// Erase redundant tags
|
||||
if (start != end) {
|
||||
// don't simplify if start == end, this way we insert <b></b>, allowing the
|
||||
// user to press Ctrl+B and start typing bold text
|
||||
new_value = simplify_tagged(new_value);
|
||||
}
|
||||
// Adjust selection
|
||||
start_i = to_tagged_pos(new_value, untagged_start_i, true, false);
|
||||
end_i = to_tagged_pos(new_value, untagged_end_i, true, false);
|
||||
}
|
||||
// Build action
|
||||
if (value->value() == new_value) {
|
||||
return nullptr; // no changes
|
||||
} else {
|
||||
return make_unique<TextValueAction>(value, start+offset, end+offset, end+offset, new_value, action_name);
|
||||
}
|
||||
}
|
||||
unique_ptr<TextValueAction> toggle_format_action(const TextValueP& value, const String& tag, size_t start_i, size_t end_i, size_t start, size_t end, const String& action_name) {
|
||||
if (start > end) {
|
||||
swap(start, end);
|
||||
swap(start_i, end_i);
|
||||
}
|
||||
String new_value;
|
||||
const String& str = value->value();
|
||||
// Are we inside the tag we are toggling?
|
||||
if (!is_in_tag(str, _("<") + tag, start_i, end_i)) {
|
||||
// we are not inside this tag, add it
|
||||
new_value = substr(str, 0, start_i);
|
||||
new_value += _("<") + tag + _(">");
|
||||
new_value += substr(str, start_i, end_i - start_i);
|
||||
new_value += _("</") + tag + _(">");
|
||||
new_value += substr(str, end_i);
|
||||
} else {
|
||||
// we are inside this tag, 'remove' it
|
||||
new_value = substr(str, 0, start_i);
|
||||
new_value += _("</") + tag + _(">");
|
||||
new_value += substr(str, start_i, end_i - start_i);
|
||||
new_value += _("<") + tag + _(">");
|
||||
new_value += substr(str, end_i);
|
||||
}
|
||||
// Build action
|
||||
}
|
||||
String new_value = value->value();
|
||||
int offset = 0;
|
||||
// Compute the changes
|
||||
new_value = tag.Contains(":") ? compute_new_variable_value(new_value, tag, start_i, end_i):
|
||||
tag == _("li") ? compute_new_bullet_value (new_value, offset, start_i, end_i):
|
||||
compute_new_simple_value (new_value, tag, start_i, end_i);
|
||||
// Erase redundant tags
|
||||
if (start != end) {
|
||||
// don't simplify if start == end, this way we insert <b></b>, allowing the
|
||||
// user to press Ctrl+B and start typing bold text
|
||||
new_value = simplify_tagged(new_value);
|
||||
}
|
||||
// Build action
|
||||
if (value->value() == new_value) {
|
||||
return nullptr; // no changes
|
||||
} else {
|
||||
return make_unique<TextValueAction>(value, start, end, end, new_value, action_name);
|
||||
return make_unique<TextValueAction>(value, start+offset, end+offset, end+offset, new_value, action_name);
|
||||
}
|
||||
}
|
||||
|
||||
String compute_new_simple_value(const String& str, const String& tag, size_t start_i, size_t end_i) {
|
||||
String prefix(substr(str, 0, start_i));
|
||||
String suffix(substr(str, end_i));
|
||||
String selection(substr(str, start_i, end_i - start_i));
|
||||
// if we are inside the tag we are toggling, 'remove' it
|
||||
if (in_tag(str, _("<") + tag, start_i, end_i) != String::npos) selection = anti_wrap_tag(selection, _("<") + tag + _(">"));
|
||||
// otherwise add it
|
||||
else selection = wrap_tag(selection, _("<") + tag + _(">"));
|
||||
return prefix + selection + suffix;
|
||||
}
|
||||
|
||||
String compute_new_variable_value(const String& str, const String& tag, size_t start_i, size_t end_i) {
|
||||
size_t start_tag = in_tag(str, _("<") + tag, start_i, end_i, true);
|
||||
// if we are inside the tag we are toggling, 'remove' it
|
||||
if (start_tag != String::npos) {
|
||||
String prefix(substr(str, 0, start_i));
|
||||
String suffix(substr(str, end_i));
|
||||
String selection(substr(str, start_i, end_i - start_i));
|
||||
selection = anti_wrap_tag(selection, _("<") + tag + _(">"));
|
||||
return prefix + selection + suffix;
|
||||
}
|
||||
// we are not inside this tag, add it around the selection, and
|
||||
// move all instances of variants of this tag to the sides of the selection
|
||||
|
||||
// first, include surrounding formatting tags to the selection
|
||||
int start_temp = str.find_last_of("<", start_i - 1);
|
||||
while (start_temp != String::npos &&
|
||||
str.GetChar(start_i - 1) == '>' &&
|
||||
is_formatting_tag(str, start_temp)) {
|
||||
start_i = start_temp;
|
||||
start_temp = str.find_last_of("<", start_i - 1);
|
||||
}
|
||||
while (end_i < str.size() &&
|
||||
is_formatting_tag(str, end_i)) {
|
||||
end_i = str.find_first_of(">", end_i) + 1;
|
||||
}
|
||||
String prefix(substr(str, 0, start_i));
|
||||
String suffix(substr(str, end_i));
|
||||
String selection(substr(str, start_i, end_i - start_i));
|
||||
|
||||
// tally open tags that are variants of this tag
|
||||
vector<String> tag_list;
|
||||
map<String, int> tag_map;
|
||||
int start = 0;
|
||||
int end = 0;
|
||||
String tag_variants = _("<") + tag.substr(0, tag.find_first_of(":"));
|
||||
size_t size = tag_variants.size();
|
||||
String temp; temp.reserve(selection.size());
|
||||
for (; end < selection.size() ; ++end) {
|
||||
if (is_substr(selection, end, tag_variants)) {
|
||||
temp += selection.substr(start, end - start);
|
||||
start = end + 1;
|
||||
end = selection.find(">", end + size);
|
||||
String new_tag = selection.substr(start, end+1 - start);
|
||||
if (tag_map.find(new_tag) != tag_map.end()) {
|
||||
tag_map[new_tag] = tag_map[new_tag]+1;
|
||||
}
|
||||
else {
|
||||
tag_map[new_tag] = 1;
|
||||
tag_list.push_back(new_tag);
|
||||
}
|
||||
start = end+1;
|
||||
}
|
||||
}
|
||||
temp += selection.substr(start, end - start);
|
||||
|
||||
// tally close tags
|
||||
selection.Clear(); selection.reserve(temp.size());
|
||||
String cejected_tag = close_tag(tag_variants);
|
||||
size_t csize = size + 1;
|
||||
for (start = 0, end = 0; end < temp.size() ; ++end) {
|
||||
if (is_substr(temp, end, cejected_tag)) {
|
||||
selection += temp.substr(start, end - start);
|
||||
start = end + 2;
|
||||
end = temp.find(">", end + csize);
|
||||
String new_tag = temp.substr(start, end+1 - start);
|
||||
if (tag_map.find(new_tag) != tag_map.end()) {
|
||||
tag_map[new_tag] = tag_map[new_tag]-1;
|
||||
}
|
||||
else {
|
||||
tag_map[new_tag] = -1;
|
||||
tag_list.push_back(new_tag);
|
||||
}
|
||||
start = end+1;
|
||||
}
|
||||
}
|
||||
selection += temp.substr(start, end - start);
|
||||
|
||||
// add the actual tag we are toggling
|
||||
selection = wrap_tag(selection, _("<") + tag + _(">"));
|
||||
|
||||
// add the tallied open and close tags
|
||||
for (int i = 0; i < tag_list.size() ; ++i) {
|
||||
String& new_tag = tag_list[i];
|
||||
int count = tag_map[new_tag];
|
||||
if (count > 0) {
|
||||
selection = selection + _("<") + new_tag;
|
||||
}
|
||||
else if (count < 0) {
|
||||
selection = _("</") + new_tag + selection;
|
||||
}
|
||||
}
|
||||
|
||||
// add the stuff around the selection
|
||||
return prefix + selection + suffix;
|
||||
}
|
||||
|
||||
String compute_new_bullet_value(const String& str, int& offset, size_t start_i, size_t end_i) {
|
||||
// Are we inside the tag we are toggling?
|
||||
size_t start_tag = in_tag(str, _("<li"), start_i, end_i);
|
||||
if (start_tag == String::npos) {
|
||||
// we are not inside this tag, add it
|
||||
// first, expand the selection to the end of the line
|
||||
end_i = min(str.find(_("<li"), end_i),
|
||||
min(str.find(_("<sep"), end_i),
|
||||
min(str.find(_("<suffix"), end_i),
|
||||
min(str.find(_("\n"), end_i),
|
||||
min(str.find(_("<line"), end_i),
|
||||
str.find(_("<soft-line"), end_i))))));
|
||||
String prefix(substr(str, 0, start_i));
|
||||
String suffix = end_i == String::npos ? String() : substr(str, end_i);
|
||||
String selection(substr(str, start_i, end_i - start_i));
|
||||
selection = _("<li><bullet>• </bullet>") + selection + _("</li>");
|
||||
offset += 1;
|
||||
return prefix + selection + suffix;
|
||||
}
|
||||
// we are inside this tag, 'remove' it
|
||||
// first, expand the selection to include the tags
|
||||
start_i = start_tag;
|
||||
end_i = str.find(_("</li>"), start_tag);
|
||||
if (end_i != String::npos) end_i += 5;
|
||||
String prefix(substr(str, 0, start_i));
|
||||
String suffix = end_i == String::npos ? String() : substr(str, end_i);
|
||||
String selection(substr(str, start_i, end_i - start_i));
|
||||
selection = remove_tag(remove_tag_contents(selection, _("<bullet>")), _("<bullet>"));
|
||||
selection = remove_tag(selection, _("<li>"));
|
||||
offset -= 1;
|
||||
return prefix + selection + suffix;
|
||||
}
|
||||
|
||||
unique_ptr<TextValueAction> typing_action(const TextValueP& value, size_t start_i, size_t end_i, size_t start, size_t end, const String& replacement, const String& action_name) {
|
||||
|
||||
Reference in New Issue
Block a user