message editor updates
This commit is contained in:
@@ -4,6 +4,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "absl/strings/str_cat.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace editor {
|
namespace editor {
|
||||||
@@ -104,6 +106,70 @@ struct MessageData {
|
|||||||
DataParsed = ParseMessageToData(ContentsParsed);
|
DataParsed = ParseMessageToData(ContentsParsed);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TextElement {
|
||||||
|
uint8_t ID;
|
||||||
|
std::string Token;
|
||||||
|
std::string GenericToken;
|
||||||
|
std::string Pattern;
|
||||||
|
std::string StrictPattern;
|
||||||
|
std::string Description;
|
||||||
|
bool HasArgument;
|
||||||
|
|
||||||
|
TextElement() = default;
|
||||||
|
TextElement(uint8_t id, std::string token, bool arg,
|
||||||
|
std::string description) {
|
||||||
|
ID = id;
|
||||||
|
Token = token;
|
||||||
|
if (arg) {
|
||||||
|
GenericToken = absl::StrFormat("[%s:##]", Token);
|
||||||
|
} else {
|
||||||
|
GenericToken = absl::StrFormat("[%s]", Token);
|
||||||
|
}
|
||||||
|
HasArgument = arg;
|
||||||
|
Description = description;
|
||||||
|
Pattern =
|
||||||
|
arg ? "\\[" + Token + ":?([0-9A-F]{1,2})\\]" : "\\[" + Token + "\\]";
|
||||||
|
Pattern = absl::StrReplaceAll(Pattern, {{"[", "\\["}, {"]", "\\]"}});
|
||||||
|
StrictPattern = absl::StrCat("^", Pattern, "$");
|
||||||
|
StrictPattern = "^" + Pattern + "$";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetParameterizedToken(uint8_t value = 0) {
|
||||||
|
if (HasArgument) {
|
||||||
|
return absl::StrFormat("[%s:%02X]", Token, value);
|
||||||
|
} else {
|
||||||
|
return absl::StrFormat("[%s]", Token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToString() {
|
||||||
|
return absl::StrFormat("%s %s", GenericToken, Description);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::smatch MatchMe(std::string dfrag) const {
|
||||||
|
std::regex pattern(StrictPattern);
|
||||||
|
std::smatch match;
|
||||||
|
std::regex_match(dfrag, match, pattern);
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Empty() { return ID == 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ParsedElement {
|
||||||
|
TextElement Parent;
|
||||||
|
uint8_t Value;
|
||||||
|
bool Active = false;
|
||||||
|
|
||||||
|
ParsedElement() = default;
|
||||||
|
ParsedElement(TextElement textElement, uint8_t value) {
|
||||||
|
Parent = textElement;
|
||||||
|
Value = value;
|
||||||
|
Active = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace editor
|
} // namespace editor
|
||||||
} // namespace app
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|||||||
@@ -121,7 +121,6 @@ static std::vector<uint8_t> ParseMessageToData(string str) {
|
|||||||
|
|
||||||
absl::Status MessageEditor::Update() {
|
absl::Status MessageEditor::Update() {
|
||||||
if (rom()->is_loaded() && !data_loaded_) {
|
if (rom()->is_loaded() && !data_loaded_) {
|
||||||
RETURN_IF_ERROR(rom()->LoadFontGraphicsData())
|
|
||||||
RETURN_IF_ERROR(Initialize());
|
RETURN_IF_ERROR(Initialize());
|
||||||
CurrentMessage = ListOfTexts[1];
|
CurrentMessage = ListOfTexts[1];
|
||||||
data_loaded_ = true;
|
data_loaded_ = true;
|
||||||
@@ -162,13 +161,29 @@ void MessageEditor::DrawMessageList() {
|
|||||||
|
|
||||||
if (BeginChild("##MessagesList", ImVec2(0, 0), true,
|
if (BeginChild("##MessagesList", ImVec2(0, 0), true,
|
||||||
ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
|
ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
|
||||||
for (const auto& message : ListOfTexts) {
|
if (BeginTable("##MessagesTable", 3,
|
||||||
if (Button(core::UppercaseHexWord(message.ID).c_str())) {
|
ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders |
|
||||||
CurrentMessage = message;
|
ImGuiTableFlags_Resizable)) {
|
||||||
|
TableSetupColumn("ID");
|
||||||
|
TableSetupColumn("Contents");
|
||||||
|
TableSetupColumn("Data");
|
||||||
|
|
||||||
|
TableHeadersRow();
|
||||||
|
|
||||||
|
for (const auto& message : ListOfTexts) {
|
||||||
|
TableNextColumn();
|
||||||
|
if (Button(core::UppercaseHexWord(message.ID).c_str())) {
|
||||||
|
CurrentMessage = message;
|
||||||
|
}
|
||||||
|
TableNextColumn();
|
||||||
|
TextWrapped("%s", ParsedMessages[message.ID].c_str());
|
||||||
|
TableNextColumn();
|
||||||
|
TextWrapped(
|
||||||
|
"%s",
|
||||||
|
core::UppercaseHexLong(ListOfTexts[message.ID].Address).c_str());
|
||||||
}
|
}
|
||||||
SameLine();
|
|
||||||
TextWrapped("%s", ParsedMessages[message.ID].c_str());
|
EndTable();
|
||||||
Separator();
|
|
||||||
}
|
}
|
||||||
EndChild();
|
EndChild();
|
||||||
}
|
}
|
||||||
@@ -230,11 +245,12 @@ absl::Status MessageEditor::Initialize() {
|
|||||||
font_preview_colors_.AddColor(0x03E0); // Green
|
font_preview_colors_.AddColor(0x03E0); // Green
|
||||||
font_preview_colors_.AddColor(0x001F); // Blue
|
font_preview_colors_.AddColor(0x001F); // Blue
|
||||||
|
|
||||||
fontgfx16Ptr = rom()->font_gfx_data();
|
RETURN_IF_ERROR(rom()->LoadFontGraphicsData())
|
||||||
|
font_gfx16_data = rom()->font_gfx_data();
|
||||||
|
|
||||||
// 4bpp
|
// 4bpp
|
||||||
RETURN_IF_ERROR(rom()->CreateAndRenderBitmap(
|
RETURN_IF_ERROR(rom()->CreateAndRenderBitmap(
|
||||||
128, 128, 64, fontgfx16Ptr, font_gfx_bitmap_, font_preview_colors_))
|
128, 128, 8, font_gfx16_data, font_gfx_bitmap_, font_preview_colors_))
|
||||||
|
|
||||||
currentfontgfx16Ptr.reserve(172 * 4096);
|
currentfontgfx16Ptr.reserve(172 * 4096);
|
||||||
for (int i = 0; i < 172 * 4096; i++) {
|
for (int i = 0; i < 172 * 4096; i++) {
|
||||||
@@ -260,8 +276,6 @@ absl::Status MessageEditor::Initialize() {
|
|||||||
DisplayedMessages.push_back(message);
|
DisplayedMessages.push_back(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateFontGfxData(rom()->data());
|
|
||||||
|
|
||||||
for (const auto& each_message : ListOfTexts) {
|
for (const auto& each_message : ListOfTexts) {
|
||||||
// Each string has a [:XX] char encoded
|
// Each string has a [:XX] char encoded
|
||||||
// The corresponding character is found in CharEncoder unordered_map
|
// The corresponding character is found in CharEncoder unordered_map
|
||||||
@@ -334,7 +348,7 @@ void MessageEditor::ReadAllTextData() {
|
|||||||
|
|
||||||
std::string current_message_raw;
|
std::string current_message_raw;
|
||||||
std::string current_message_parsed;
|
std::string current_message_parsed;
|
||||||
TextElement textElement;
|
TextElement text_element;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
current_byte = rom()->data()[pos++];
|
current_byte = rom()->data()[pos++];
|
||||||
@@ -359,22 +373,22 @@ void MessageEditor::ReadAllTextData() {
|
|||||||
temp_bytes_raw.push_back(current_byte);
|
temp_bytes_raw.push_back(current_byte);
|
||||||
|
|
||||||
// Check for command.
|
// Check for command.
|
||||||
textElement = FindMatchingCommand(current_byte);
|
text_element = FindMatchingCommand(current_byte);
|
||||||
|
|
||||||
if (!textElement.Empty()) {
|
if (!text_element.Empty()) {
|
||||||
temp_bytes_parsed.push_back(current_byte);
|
temp_bytes_parsed.push_back(current_byte);
|
||||||
if (textElement.HasArgument) {
|
if (text_element.HasArgument) {
|
||||||
current_byte = rom()->data()[pos++];
|
current_byte = rom()->data()[pos++];
|
||||||
temp_bytes_raw.push_back(current_byte);
|
temp_bytes_raw.push_back(current_byte);
|
||||||
temp_bytes_parsed.push_back(current_byte);
|
temp_bytes_parsed.push_back(current_byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
current_message_raw.append(
|
current_message_raw.append(
|
||||||
textElement.GetParameterizedToken(current_byte));
|
text_element.GetParameterizedToken(current_byte));
|
||||||
current_message_parsed.append(
|
current_message_parsed.append(
|
||||||
textElement.GetParameterizedToken(current_byte));
|
text_element.GetParameterizedToken(current_byte));
|
||||||
|
|
||||||
if (textElement.Token == BANKToken) {
|
if (text_element.Token == BANKToken) {
|
||||||
pos = kTextData2;
|
pos = kTextData2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,11 +396,11 @@ void MessageEditor::ReadAllTextData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for special characters.
|
// Check for special characters.
|
||||||
textElement = FindMatchingSpecial(current_byte);
|
text_element = FindMatchingSpecial(current_byte);
|
||||||
|
|
||||||
if (!textElement.Empty()) {
|
if (!text_element.Empty()) {
|
||||||
current_message_raw.append(textElement.GetParameterizedToken());
|
current_message_raw.append(text_element.GetParameterizedToken());
|
||||||
current_message_parsed.append(textElement.GetParameterizedToken());
|
current_message_parsed.append(text_element.GetParameterizedToken());
|
||||||
temp_bytes_parsed.push_back(current_byte);
|
temp_bytes_parsed.push_back(current_byte);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -519,7 +533,6 @@ TextElement MessageEditor::FindMatchingCommand(uint8_t b) {
|
|||||||
return text_element;
|
return text_element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return empty_element;
|
return empty_element;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,7 +543,6 @@ TextElement MessageEditor::FindMatchingSpecial(uint8_t value) {
|
|||||||
return text_element;
|
return text_element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return empty_element;
|
return empty_element;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -679,7 +691,7 @@ void MessageEditor::DrawTileToPreview(int x, int y, int srcx, int srcy, int pal,
|
|||||||
// Formula information to get tile index position in the array.
|
// Formula information to get tile index position in the array.
|
||||||
// ((ID / nbrofXtiles) * (imgwidth/2) + (ID - ((ID/16)*16) ))
|
// ((ID / nbrofXtiles) * (imgwidth/2) + (ID - ((ID/16)*16) ))
|
||||||
int tx = ((drawid / 16) * 512) + ((drawid - ((drawid / 16) * 16)) * 4);
|
int tx = ((drawid / 16) * 512) + ((drawid - ((drawid / 16) * 16)) * 4);
|
||||||
uint8_t pixel = fontgfx16Ptr[tx + (yl * 64) + xl];
|
uint8_t pixel = font_gfx16_data[tx + (yl * 64) + xl];
|
||||||
|
|
||||||
// nx,ny = object position, xx,yy = tile position, xl,yl = pixel
|
// nx,ny = object position, xx,yy = tile position, xl,yl = pixel
|
||||||
// position
|
// position
|
||||||
@@ -708,6 +720,49 @@ std::string MessageEditor::DisplayTextOverflowError(int pos, bool bank) {
|
|||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// push_backs a command to the text field when the push_back command button is
|
||||||
|
// pressed or the command is double clicked in the list.
|
||||||
|
void MessageEditor::InsertCommandButton_Click_1() {
|
||||||
|
// InsertSelectedText(
|
||||||
|
// TextCommands[TextCommandList.SelectedIndex].GetParameterizedToken(
|
||||||
|
// (uint8_t)ParamsBox.HexValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
// push_backs a special character to the text field when the push_back command
|
||||||
|
// button is pressed or the character is double clicked in the list.
|
||||||
|
void MessageEditor::InsertSpecialButton_Click() {
|
||||||
|
// InsertSelectedText(
|
||||||
|
// SpecialChars[SpecialsList.SelectedIndex].GetParameterizedToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageEditor::InsertSelectedText(string str) {
|
||||||
|
int textboxPos = message_text_box_.selection_start;
|
||||||
|
from_form = true;
|
||||||
|
// message_text_box_.Text = message_text_box_.Text.Insert(textboxPos, str);
|
||||||
|
from_form = false;
|
||||||
|
message_text_box_.selection_start = textboxPos + str.size();
|
||||||
|
message_text_box_.Focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageEditor::Delete() {
|
||||||
|
// Determine if any text is selected in the TextBox control.
|
||||||
|
if (message_text_box_.selection_length == 0) {
|
||||||
|
// clear all of the text in the textbox.
|
||||||
|
message_text_box_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageEditor::SelectAll() {
|
||||||
|
// Determine if any text is selected in the TextBox control.
|
||||||
|
if (message_text_box_.selection_length == 0) {
|
||||||
|
// Select all text in the text box.
|
||||||
|
message_text_box_.SelectAll();
|
||||||
|
|
||||||
|
// Move the cursor to the text box.
|
||||||
|
message_text_box_.Focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace editor
|
} // namespace editor
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
|||||||
@@ -45,68 +45,6 @@ static int defaultColor = 6;
|
|||||||
|
|
||||||
static std::vector<uint8_t> ParseMessageToData(string str);
|
static std::vector<uint8_t> ParseMessageToData(string str);
|
||||||
|
|
||||||
struct TextElement {
|
|
||||||
uint8_t ID;
|
|
||||||
string Token;
|
|
||||||
string GenericToken;
|
|
||||||
string Pattern;
|
|
||||||
string StrictPattern;
|
|
||||||
string Description;
|
|
||||||
bool HasArgument;
|
|
||||||
|
|
||||||
TextElement() = default;
|
|
||||||
TextElement(uint8_t id, string token, bool arg, string description) {
|
|
||||||
ID = id;
|
|
||||||
Token = token;
|
|
||||||
if (arg) {
|
|
||||||
GenericToken = absl::StrFormat("[%s:##]", Token);
|
|
||||||
} else {
|
|
||||||
GenericToken = absl::StrFormat("[%s]", Token);
|
|
||||||
}
|
|
||||||
HasArgument = arg;
|
|
||||||
Description = description;
|
|
||||||
Pattern =
|
|
||||||
arg ? "\\[" + Token + ":?([0-9A-F]{1,2})\\]" : "\\[" + Token + "\\]";
|
|
||||||
Pattern = absl::StrReplaceAll(Pattern, {{"[", "\\["}, {"]", "\\]"}});
|
|
||||||
StrictPattern = absl::StrCat("^", Pattern, "$");
|
|
||||||
StrictPattern = "^" + Pattern + "$";
|
|
||||||
}
|
|
||||||
|
|
||||||
string GetParameterizedToken(uint8_t value = 0) {
|
|
||||||
if (HasArgument) {
|
|
||||||
return absl::StrFormat("[%s:%02X]", Token, value);
|
|
||||||
} else {
|
|
||||||
return absl::StrFormat("[%s]", Token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string ToString() {
|
|
||||||
return absl::StrFormat("%s %s", GenericToken, Description);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::smatch MatchMe(std::string dfrag) const {
|
|
||||||
std::regex pattern(StrictPattern);
|
|
||||||
std::smatch match;
|
|
||||||
std::regex_match(dfrag, match, pattern);
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Empty() { return ID == 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ParsedElement {
|
|
||||||
TextElement Parent;
|
|
||||||
uint8_t Value;
|
|
||||||
bool Active = false;
|
|
||||||
|
|
||||||
ParsedElement() = default;
|
|
||||||
ParsedElement(TextElement textElement, uint8_t value) {
|
|
||||||
Parent = textElement;
|
|
||||||
Value = value;
|
|
||||||
Active = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static ParsedElement FindMatchingElement(string str);
|
static ParsedElement FindMatchingElement(string str);
|
||||||
|
|
||||||
static const TextElement TextCommands[] = {
|
static const TextElement TextCommands[] = {
|
||||||
@@ -297,6 +235,8 @@ class MessageEditor : public Editor,
|
|||||||
return absl::UnimplementedError("Find not implemented");
|
return absl::UnimplementedError("Find not implemented");
|
||||||
}
|
}
|
||||||
absl::Status Save();
|
absl::Status Save();
|
||||||
|
void Delete();
|
||||||
|
void SelectAll();
|
||||||
void RegisterTests(ImGuiTestEngine* e) override;
|
void RegisterTests(ImGuiTestEngine* e) override;
|
||||||
|
|
||||||
TextElement FindMatchingCommand(uint8_t byte);
|
TextElement FindMatchingCommand(uint8_t byte);
|
||||||
@@ -316,6 +256,10 @@ class MessageEditor : public Editor,
|
|||||||
void DrawMessagePreview();
|
void DrawMessagePreview();
|
||||||
std::string DisplayTextOverflowError(int pos, bool bank);
|
std::string DisplayTextOverflowError(int pos, bool bank);
|
||||||
|
|
||||||
|
void InsertCommandButton_Click_1();
|
||||||
|
void InsertSpecialButton_Click();
|
||||||
|
void InsertSelectedText(string str);
|
||||||
|
|
||||||
static const std::vector<DictionaryEntry> AllDicts;
|
static const std::vector<DictionaryEntry> AllDicts;
|
||||||
|
|
||||||
uint8_t width_array[100];
|
uint8_t width_array[100];
|
||||||
@@ -350,7 +294,7 @@ class MessageEditor : public Editor,
|
|||||||
gfx::Bitmap font_gfx_bitmap_;
|
gfx::Bitmap font_gfx_bitmap_;
|
||||||
gfx::Bitmap current_font_gfx16_bitmap_;
|
gfx::Bitmap current_font_gfx16_bitmap_;
|
||||||
|
|
||||||
Bytes fontgfx16Ptr;
|
Bytes font_gfx16_data;
|
||||||
Bytes currentfontgfx16Ptr;
|
Bytes currentfontgfx16Ptr;
|
||||||
|
|
||||||
gfx::SnesPalette font_preview_colors_;
|
gfx::SnesPalette font_preview_colors_;
|
||||||
@@ -389,6 +333,25 @@ class MessageEditor : public Editor,
|
|||||||
has_selection = false;
|
has_selection = false;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
void clear() {
|
||||||
|
text.clear();
|
||||||
|
buffer.clear();
|
||||||
|
cursor_pos = 0;
|
||||||
|
selection_start = 0;
|
||||||
|
selection_end = 0;
|
||||||
|
selection_length = 0;
|
||||||
|
has_selection = false;
|
||||||
|
has_focus = false;
|
||||||
|
changed = false;
|
||||||
|
can_undo = false;
|
||||||
|
}
|
||||||
|
void SelectAll() {
|
||||||
|
selection_start = 0;
|
||||||
|
selection_end = text.size();
|
||||||
|
selection_length = text.size();
|
||||||
|
has_selection = true;
|
||||||
|
}
|
||||||
|
void Focus() { has_focus = true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
TextBox message_text_box_;
|
TextBox message_text_box_;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "message_editor.h"
|
#include "message_editor.h"
|
||||||
|
|
||||||
|
#include "app/core/testable.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace editor {
|
namespace editor {
|
||||||
@@ -11,7 +13,6 @@ void MessageEditor::RegisterTests(ImGuiTestEngine* e) {
|
|||||||
t = IM_REGISTER_TEST(e, "message_editor", "read_all_text_data");
|
t = IM_REGISTER_TEST(e, "message_editor", "read_all_text_data");
|
||||||
t->TestFunc = [](ImGuiTestContext* ctx) {
|
t->TestFunc = [](ImGuiTestContext* ctx) {
|
||||||
ctx->SetRef("##YazeMain/##TabBar/Message");
|
ctx->SetRef("##YazeMain/##TabBar/Message");
|
||||||
ctx->ItemClick("TestButton");
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user