Enhance message editor with import/export functionality for messages, including file handling and UI updates

This commit is contained in:
scawful
2025-04-16 22:34:34 -04:00
parent 97788fc033
commit a01d554f15
4 changed files with 315 additions and 242 deletions

View File

@@ -307,6 +307,95 @@ std::vector<std::string> ParseMessageData(
return parsed_messages; return parsed_messages;
} }
void ReadAllTextData(Rom *rom, std::vector<MessageData> &list_of_texts_) {
// Read all text data from the ROM.
int pos = kTextData;
int message_id = 0;
std::vector<uint8_t> raw_message;
std::vector<uint8_t> parsed_message;
std::string current_raw_message;
std::string current_parsed_message;
uint8_t current_byte = 0;
while (current_byte != 0xFF) {
current_byte = rom->data()[pos++];
if (current_byte == kMessageTerminator) {
list_of_texts_.push_back(
MessageData(message_id++, pos, current_raw_message, raw_message,
current_parsed_message, parsed_message));
raw_message.clear();
parsed_message.clear();
current_raw_message.clear();
current_parsed_message.clear();
continue;
} else if (current_byte == 0xFF) {
break;
}
raw_message.push_back(current_byte);
auto text_element = FindMatchingCommand(current_byte);
if (text_element != std::nullopt) {
parsed_message.push_back(current_byte);
if (text_element->HasArgument) {
current_byte = rom->data()[pos++];
raw_message.push_back(current_byte);
parsed_message.push_back(current_byte);
}
current_raw_message.append(text_element->GetParamToken(current_byte));
current_parsed_message.append(text_element->GetParamToken(current_byte));
if (text_element->Token == kBankToken) {
pos = kTextData2;
}
continue;
}
// Check for special characters.
auto special_element = FindMatchingSpecial(current_byte);
if (special_element != std::nullopt) {
current_raw_message.append(special_element->GetParamToken());
current_parsed_message.append(special_element->GetParamToken());
parsed_message.push_back(current_byte);
continue;
}
// Check for dictionary.
int dictionary = FindDictionaryEntry(current_byte);
if (dictionary >= 0) {
current_raw_message.append("[");
current_raw_message.append(DICTIONARYTOKEN);
current_raw_message.append(":");
current_raw_message.append(util::HexByte(dictionary));
current_raw_message.append("]");
uint32_t address = Get24LocalFromPC(
rom->mutable_data(), kPointersDictionaries + (dictionary * 2));
uint32_t address_end = Get24LocalFromPC(
rom->mutable_data(), kPointersDictionaries + ((dictionary + 1) * 2));
for (uint32_t i = address; i < address_end; i++) {
parsed_message.push_back(rom->data()[i]);
current_parsed_message.append(ParseTextDataByte(rom->data()[i]));
}
continue;
}
// Everything else.
if (CharEncoder.contains(current_byte)) {
std::string str = "";
str.push_back(CharEncoder.at(current_byte));
current_raw_message.append(str);
current_parsed_message.append(str);
parsed_message.push_back(current_byte);
}
}
}
std::vector<std::string> ImportMessageData(std::string_view filename) { std::vector<std::string> ImportMessageData(std::string_view filename) {
std::vector<std::string> messages; std::vector<std::string> messages;
std::ifstream file(filename.data()); std::ifstream file(filename.data());

View File

@@ -311,6 +311,12 @@ std::vector<std::string> ParseMessageData(
std::vector<MessageData> &message_data, std::vector<MessageData> &message_data,
const std::vector<DictionaryEntry> &dictionary_entries); const std::vector<DictionaryEntry> &dictionary_entries);
constexpr int kTextData2 = 0x75F40;
constexpr int kTextData2End = 0x773FF;
// Reads all text data from the ROM and returns a vector of MessageData objects.
void ReadAllTextData(Rom *rom, std::vector<MessageData> &list_of_texts_);
std::vector<std::string> ImportMessageData(std::string_view filename); std::vector<std::string> ImportMessageData(std::string_view filename);
} // namespace editor } // namespace editor

View File

@@ -5,6 +5,7 @@
#include <vector> #include <vector>
#include "absl/status/status.h" #include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h" #include "absl/strings/str_format.h"
#include "absl/strings/str_replace.h" #include "absl/strings/str_replace.h"
#include "app/core/platform/renderer.h" #include "app/core/platform/renderer.h"
@@ -47,7 +48,7 @@ void MessageEditor::Initialize() {
} }
all_dictionaries_ = BuildDictionaryEntries(rom()); all_dictionaries_ = BuildDictionaryEntries(rom());
ReadAllTextDataV2(); ReadAllTextData(rom(), list_of_texts_);
font_preview_colors_.AddColor(0x7FFF); // White font_preview_colors_.AddColor(0x7FFF); // White
font_preview_colors_.AddColor(0x7C00); // Red font_preview_colors_.AddColor(0x7C00); // Red
@@ -77,6 +78,7 @@ void MessageEditor::Initialize() {
current_font_gfx16_bitmap_, font_preview_colors_); current_font_gfx16_bitmap_, font_preview_colors_);
*font_gfx_bitmap_.mutable_palette() = font_preview_colors_; *font_gfx_bitmap_.mutable_palette() = font_preview_colors_;
*current_font_gfx16_bitmap_.mutable_palette() = font_preview_colors_;
parsed_messages_ = ParseMessageData(list_of_texts_, all_dictionaries_); parsed_messages_ = ParseMessageData(list_of_texts_, all_dictionaries_);
DrawMessagePreview(); DrawMessagePreview();
@@ -107,13 +109,15 @@ absl::Status MessageEditor::Update() {
TableNextColumn(); TableNextColumn();
DrawTextCommands(); DrawTextCommands();
DrawSpecialCharacters();
TableNextColumn(); TableNextColumn();
DrawDictionary(); DrawDictionary();
DrawImportExport();
EndTable(); EndTable();
} }
CLEAR_AND_RETURN_STATUS(status_);
return absl::OkStatus(); return absl::OkStatus();
} }
@@ -126,7 +130,6 @@ void MessageEditor::DrawMessageList() {
TableSetupColumn("Data"); TableSetupColumn("Data");
TableHeadersRow(); TableHeadersRow();
for (const auto& message : list_of_texts_) { for (const auto& message : list_of_texts_) {
TableNextColumn(); TableNextColumn();
if (Button(util::HexWord(message.ID).c_str())) { if (Button(util::HexWord(message.ID).c_str())) {
@@ -172,9 +175,20 @@ void MessageEditor::DrawCurrentMessage() {
Separator(); Separator();
Text("Message Preview"); Text("Message Preview");
if (Button("Create Preview")) {
DrawMessagePreview();
}
if (Button("Refresh Bitmap")) { if (Button("Refresh Bitmap")) {
Renderer::GetInstance().UpdateBitmap(&current_font_gfx16_bitmap_); Renderer::GetInstance().UpdateBitmap(&current_font_gfx16_bitmap_);
} }
ImGui::SameLine();
if (Button("View Palette")) {
ImGui::OpenPopup("Palette");
}
if (ImGui::BeginPopup("Palette")) {
status_ = gui::DisplayPalette(font_preview_colors_, true);
ImGui::EndPopup();
}
gui::BeginPadding(1); gui::BeginPadding(1);
BeginChild("CurrentGfxFont", ImVec2(200, 0), true, BeginChild("CurrentGfxFont", ImVec2(200, 0), true,
ImGuiWindowFlags_AlwaysVerticalScrollbar); ImGuiWindowFlags_AlwaysVerticalScrollbar);
@@ -188,17 +202,29 @@ void MessageEditor::DrawCurrentMessage() {
} }
void MessageEditor::DrawTextCommands() { void MessageEditor::DrawTextCommands() {
if (BeginChild("##TextCommands", ImVec2(0, 0), true, ImGui::BeginChild("##TextCommands",
ImGuiWindowFlags_AlwaysVerticalScrollbar)) { ImVec2(0, ImGui::GetWindowContentRegionMax().y / 2), true,
for (const auto& text_element : TextCommands) { ImGuiWindowFlags_AlwaysVerticalScrollbar);
if (Button(text_element.GenericToken.c_str())) { for (const auto& text_element : TextCommands) {
// Insert the command into the message text box. if (Button(text_element.GenericToken.c_str())) {
message_text_box_.text.append(text_element.GenericToken); message_text_box_.text.append(text_element.GenericToken);
}
SameLine();
TextWrapped("%s", text_element.Description.c_str());
Separator();
} }
SameLine();
TextWrapped("%s", text_element.Description.c_str());
Separator();
}
EndChild();
}
void MessageEditor::DrawSpecialCharacters() {
ImGui::BeginChild("##SpecialChars",
ImVec2(0, ImGui::GetWindowContentRegionMax().y / 2), true,
ImGuiWindowFlags_AlwaysVerticalScrollbar);
for (const auto& text_element : SpecialChars) {
if (Button(text_element.GenericToken.c_str())) {
message_text_box_.text.append(text_element.GenericToken);
}
Separator();
} }
EndChild(); EndChild();
} }
@@ -207,8 +233,9 @@ void MessageEditor::DrawDictionary() {
if (all_dictionaries_.empty()) { if (all_dictionaries_.empty()) {
return; return;
} }
if (ImGui::BeginChild("##DictionaryChild", ImVec2(200, 0), true, if (ImGui::BeginChild("##DictionaryChild",
ImGuiWindowFlags_AlwaysVerticalScrollbar)) { ImVec2(200, ImGui::GetWindowContentRegionMax().y / 2),
true, ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
if (BeginTable("##Dictionary", 2, kMessageTableFlags)) { if (BeginTable("##Dictionary", 2, kMessageTableFlags)) {
TableSetupColumn("ID"); TableSetupColumn("ID");
TableSetupColumn("Contents"); TableSetupColumn("Contents");
@@ -225,189 +252,27 @@ void MessageEditor::DrawDictionary() {
EndChild(); EndChild();
} }
void MessageEditor::ReadAllTextDataV2() { void MessageEditor::DrawImportExport() {
// Read all text data from the ROM. ImGui::Text("Import Messages");
int pos = kTextData; ImGui::Separator();
int message_id = 0;
std::vector<uint8_t> raw_message; static char import_path[256] = "";
std::vector<uint8_t> parsed_message; ImGui::InputText("Import File", import_path, sizeof(import_path));
std::string current_raw_message;
std::string current_parsed_message;
uint8_t current_byte = 0; if (ImGui::Button("Import")) {
while (current_byte != 0xFF) { status_ = ImportMessagesFromFile(import_path);
current_byte = rom()->data()[pos++];
if (current_byte == kMessageTerminator) {
list_of_texts_.push_back(
MessageData(message_id++, pos, current_raw_message, raw_message,
current_parsed_message, parsed_message));
raw_message.clear();
parsed_message.clear();
current_raw_message.clear();
current_parsed_message.clear();
continue;
} else if (current_byte == 0xFF) {
break;
}
raw_message.push_back(current_byte);
auto text_element = FindMatchingCommand(current_byte);
if (text_element != std::nullopt) {
parsed_message.push_back(current_byte);
if (text_element->HasArgument) {
current_byte = rom()->data()[pos++];
raw_message.push_back(current_byte);
parsed_message.push_back(current_byte);
}
current_raw_message.append(text_element->GetParamToken(current_byte));
current_parsed_message.append(text_element->GetParamToken(current_byte));
if (text_element->Token == kBankToken) {
pos = kTextData2;
}
continue;
}
// Check for special characters.
auto special_element = FindMatchingSpecial(current_byte);
if (special_element != std::nullopt) {
current_raw_message.append(special_element->GetParamToken());
current_parsed_message.append(special_element->GetParamToken());
parsed_message.push_back(current_byte);
continue;
}
// Check for dictionary.
int dictionary = FindDictionaryEntry(current_byte);
if (dictionary >= 0) {
current_raw_message.append("[");
current_raw_message.append(DICTIONARYTOKEN);
current_raw_message.append(":");
current_raw_message.append(util::HexByte(dictionary));
current_raw_message.append("]");
uint32_t address = Get24LocalFromPC(
rom()->mutable_data(), kPointersDictionaries + (dictionary * 2));
uint32_t address_end =
Get24LocalFromPC(rom()->mutable_data(),
kPointersDictionaries + ((dictionary + 1) * 2));
for (uint32_t i = address; i < address_end; i++) {
parsed_message.push_back(rom()->data()[i]);
current_parsed_message.append(ParseTextDataByte(rom()->data()[i]));
}
continue;
}
// Everything else.
if (CharEncoder.contains(current_byte)) {
std::string str = "";
str.push_back(CharEncoder.at(current_byte));
current_raw_message.append(str);
current_parsed_message.append(str);
parsed_message.push_back(current_byte);
}
} }
}
void MessageEditor::ReadAllTextData() { // Export section
int pos = kTextData; ImGui::Spacing();
int message_id = 0; ImGui::Text("Export Messages");
uint8_t current_byte; ImGui::Separator();
std::vector<uint8_t> temp_bytes_raw;
std::vector<uint8_t> temp_bytes_parsed;
std::string current_message_raw; static char export_path[256] = "";
std::string current_message_parsed; ImGui::InputText("Export File", export_path, sizeof(export_path));
while (true) { if (ImGui::Button("Export")) {
current_byte = rom()->data()[pos++]; status_ = ExportMessagesToFile(export_path);
if (current_byte == kMessageTerminator) {
auto message =
MessageData(message_id++, pos, current_message_raw, temp_bytes_raw,
current_message_parsed, temp_bytes_parsed);
list_of_texts_.push_back(message);
temp_bytes_raw.clear();
temp_bytes_parsed.clear();
current_message_raw.clear();
current_message_parsed.clear();
continue;
} else if (current_byte == 0xFF) {
break;
}
temp_bytes_raw.push_back(current_byte);
// Check for command.
auto text_element = FindMatchingCommand(current_byte);
if (text_element.has_value()) {
temp_bytes_parsed.push_back(current_byte);
if (text_element->HasArgument) {
current_byte = rom()->data()[pos++];
temp_bytes_raw.push_back(current_byte);
temp_bytes_parsed.push_back(current_byte);
}
current_message_raw.append(text_element->GetParamToken(current_byte));
current_message_parsed.append(text_element->GetParamToken(current_byte));
if (text_element->Token == kBankToken) {
pos = kTextData2;
}
continue;
}
// Check for special characters.
auto special_element = FindMatchingSpecial(current_byte);
if (special_element.has_value()) {
current_message_raw.append(special_element->GetParamToken());
current_message_parsed.append(special_element->GetParamToken());
temp_bytes_parsed.push_back(current_byte);
continue;
}
// Check for dictionary.
int dictionary = FindDictionaryEntry(current_byte);
if (dictionary >= 0) {
current_message_raw.append("[");
current_message_raw.append(DICTIONARYTOKEN);
current_message_raw.append(":");
current_message_raw.append(util::HexWord(dictionary));
current_message_raw.append("]");
uint32_t address = Get24LocalFromPC(
rom()->mutable_data(), kPointersDictionaries + (dictionary * 2));
uint32_t address_end =
Get24LocalFromPC(rom()->mutable_data(),
kPointersDictionaries + ((dictionary + 1) * 2));
for (uint32_t i = address; i < address_end; i++) {
temp_bytes_parsed.push_back(rom()->data()[i]);
current_message_parsed.append(ParseTextDataByte(rom()->data()[i]));
}
continue;
}
// Everything else.
if (CharEncoder.contains(current_byte)) {
std::string str = "";
str.push_back(CharEncoder.at(current_byte));
current_message_raw.append(str);
current_message_parsed.append(str);
temp_bytes_parsed.push_back(current_byte);
}
} }
} }
@@ -521,45 +386,9 @@ void MessageEditor::DrawMessagePreview() {
text_position_ = 0; text_position_ = 0;
DrawCharacterToPreview(current_message_.Data); DrawCharacterToPreview(current_message_.Data);
shown_lines_ = 0; shown_lines_ = 0;
}
absl::Status MessageEditor::Cut() { Renderer::GetInstance().UpdateBitmap(&font_gfx_bitmap_);
// Ensure that text is currently selected in the text box. Renderer::GetInstance().RenderBitmap(&current_font_gfx16_bitmap_);
if (!message_text_box_.text.empty()) {
// Cut the selected text in the control and paste it into the Clipboard.
message_text_box_.Cut();
}
return absl::OkStatus();
}
absl::Status MessageEditor::Paste() {
// Determine if there is any text in the Clipboard to paste into the
if (ImGui::GetClipboardText() != nullptr) {
// Paste the text from the Clipboard into the text box.
message_text_box_.Paste();
}
return absl::OkStatus();
}
absl::Status MessageEditor::Copy() {
// Ensure that text is selected in the text box.
if (message_text_box_.selection_length > 0) {
// Copy the selected text to the Clipboard.
message_text_box_.Copy();
}
return absl::OkStatus();
}
absl::Status MessageEditor::Undo() {
// Determine if last operation can be undone in text box.
if (message_text_box_.can_undo) {
// Undo the last operation.
message_text_box_.Undo();
// clear the undo buffer to prevent last action from being redone.
message_text_box_.clearUndo();
}
return absl::OkStatus();
} }
absl::Status MessageEditor::Save() { absl::Status MessageEditor::Save() {
@@ -619,6 +448,51 @@ std::string MessageEditor::DisplayTextOverflowError(int pos, bool bank) {
return message; return message;
} }
absl::Status MessageEditor::Cut() {
// Ensure that text is currently selected in the text box.
if (!message_text_box_.text.empty()) {
// Cut the selected text in the control and paste it into the Clipboard.
message_text_box_.Cut();
}
return absl::OkStatus();
}
absl::Status MessageEditor::Paste() {
// Determine if there is any text in the Clipboard to paste into the
if (ImGui::GetClipboardText() != nullptr) {
// Paste the text from the Clipboard into the text box.
message_text_box_.Paste();
}
return absl::OkStatus();
}
absl::Status MessageEditor::Copy() {
// Ensure that text is selected in the text box.
if (message_text_box_.selection_length > 0) {
// Copy the selected text to the Clipboard.
message_text_box_.Copy();
}
return absl::OkStatus();
}
absl::Status MessageEditor::Undo() {
// Determine if last operation can be undone in text box.
if (message_text_box_.can_undo) {
// Undo the last operation.
message_text_box_.Undo();
// clear the undo buffer to prevent last action from being redone.
message_text_box_.clearUndo();
}
return absl::OkStatus();
}
absl::Status MessageEditor::Redo() {
// Implementation of redo functionality
// This would require tracking a redo stack in the TextBox struct
return absl::OkStatus();
}
void MessageEditor::Delete() { void MessageEditor::Delete() {
// Determine if any text is selected in the TextBox control. // Determine if any text is selected in the TextBox control.
if (message_text_box_.selection_length == 0) { if (message_text_box_.selection_length == 0) {
@@ -638,16 +512,102 @@ void MessageEditor::SelectAll() {
} }
} }
absl::Status MessageEditor::Redo() {
// Implementation of redo functionality
// This would require tracking a redo stack in the TextBox struct
return absl::OkStatus();
}
absl::Status MessageEditor::Find() { absl::Status MessageEditor::Find() {
if (ImGui::Begin("Find Text", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
static char find_text[256] = "";
ImGui::InputText("Search", find_text, IM_ARRAYSIZE(find_text));
if (ImGui::Button("Find Next")) {
search_text_ = find_text;
}
ImGui::SameLine();
if (ImGui::Button("Find All")) {
search_text_ = find_text;
}
ImGui::SameLine();
if (ImGui::Button("Replace")) {
// TODO: Implement replace functionality
}
ImGui::Checkbox("Case Sensitive", &case_sensitive_);
ImGui::SameLine();
ImGui::Checkbox("Match Whole Word", &match_whole_word_);
}
ImGui::End();
return absl::OkStatus(); return absl::OkStatus();
} }
absl::Status MessageEditor::ImportMessagesFromFile(const std::string& path) {
// Open the file
std::ifstream file(path);
if (!file.is_open()) {
return absl::NotFoundError("Failed to open file");
}
// Read the file line by line
std::string line;
int line_number = 0;
while (std::getline(file, line)) {
line_number++;
// Skip empty lines and comments
if (line.empty() || line[0] == '#') {
continue;
}
// Parse the line
// Format: ID=content
size_t equal_pos = line.find('=');
if (equal_pos == std::string::npos) {
return absl::InvalidArgumentError(
absl::StrFormat("Invalid format at line %d", line_number));
}
std::string id_str = line.substr(0, equal_pos);
std::string content = line.substr(equal_pos + 1);
// Parse the ID
int id;
if (!absl::SimpleAtoi(id_str, &id)) {
return absl::InvalidArgumentError(
absl::StrFormat("Invalid ID at line %d", line_number));
}
// Update a regular message
for (auto& message : list_of_texts_) {
if (message.ID == id) {
message.ContentsParsed = content;
message.DataParsed = ParseMessageToData(content);
break;
}
}
}
return absl::OkStatus();
}
absl::Status MessageEditor::ExportMessagesToFile(const std::string& path) {
// Open the file
std::ofstream file(path);
if (!file.is_open()) {
return absl::NotFoundError("Failed to open file");
}
// Write a header
file << "# Message Export\n";
file << "# Format: ID=content\n\n";
// Write regular messages
for (const auto& message : list_of_texts_) {
file << absl::StrFormat("%d=%s\n", message.ID, message.ContentsParsed);
}
return absl::OkStatus();
}
} // namespace editor } // namespace editor
} // namespace yaze } // namespace yaze

View File

@@ -2,7 +2,9 @@
#define YAZE_APP_EDITOR_MESSAGE_EDITOR_H #define YAZE_APP_EDITOR_MESSAGE_EDITOR_H
#include <array> #include <array>
#include <memory>
#include <string> #include <string>
#include <unordered_map>
#include <vector> #include <vector>
#include "absl/status/status.h" #include "absl/status/status.h"
@@ -16,8 +18,6 @@ namespace yaze {
namespace editor { namespace editor {
constexpr int kGfxFont = 0x70000; // 2bpp format constexpr int kGfxFont = 0x70000; // 2bpp format
constexpr int kTextData2 = 0x75F40;
constexpr int kTextData2End = 0x773FF;
constexpr int kCharactersWidth = 0x74ADF; constexpr int kCharactersWidth = 0x74ADF;
constexpr int kNumMessages = 396; constexpr int kNumMessages = 396;
constexpr int kCurrentMessageWidth = 172; constexpr int kCurrentMessageWidth = 172;
@@ -30,7 +30,7 @@ constexpr uint8_t kWidthArraySize = 100;
constexpr uint8_t kBlockTerminator = 0x80; constexpr uint8_t kBlockTerminator = 0x80;
constexpr uint8_t kMessageBankChangeId = 0x80; constexpr uint8_t kMessageBankChangeId = 0x80;
class MessageEditor : public Editor, public SharedRom { class MessageEditor : public Editor {
public: public:
explicit MessageEditor(Rom* rom = nullptr) : rom_(rom) { explicit MessageEditor(Rom* rom = nullptr) : rom_(rom) {
type_ = EditorType::kMessage; type_ = EditorType::kMessage;
@@ -42,10 +42,10 @@ class MessageEditor : public Editor, public SharedRom {
void DrawMessageList(); void DrawMessageList();
void DrawCurrentMessage(); void DrawCurrentMessage();
void DrawTextCommands(); void DrawTextCommands();
void DrawSpecialCharacters();
void DrawDictionary(); void DrawDictionary();
void DrawImportExport();
void ReadAllTextDataV2(); void DrawMessageSettings();
[[deprecated]] void ReadAllTextData();
absl::Status Cut() override; absl::Status Cut() override;
absl::Status Copy() override; absl::Status Copy() override;
@@ -66,6 +66,15 @@ class MessageEditor : public Editor, public SharedRom {
void DrawMessagePreview(); void DrawMessagePreview();
std::string DisplayTextOverflowError(int pos, bool bank); std::string DisplayTextOverflowError(int pos, bool bank);
absl::Status ImportMessagesFromFile(const std::string& filename);
absl::Status ExportMessagesToFile(const std::string& filename);
void SetMessageFont(int font_index);
void SetMessageColor(int color_index);
void SetMessageSpeed(int speed);
void SetMessageWindow(int window_type);
void SetMessagePosition(int x, int y);
void set_rom(Rom* rom) { rom_ = rom; } void set_rom(Rom* rom) { rom_ = rom; }
Rom* rom() const { return rom_; } Rom* rom() const { return rom_; }
@@ -73,12 +82,17 @@ class MessageEditor : public Editor, public SharedRom {
Rom* rom_; Rom* rom_;
bool skip_next = false; bool skip_next = false;
bool data_loaded_ = false; bool data_loaded_ = false;
bool case_sensitive_ = false;
bool match_whole_word_ = false;
bool export_expanded_messages_ = false;
int text_line_ = 0; int text_line_ = 0;
int text_position_ = 0; int text_position_ = 0;
int shown_lines_ = 0; int shown_lines_ = 0;
std::string search_text_ = ""; std::string search_text_ = "";
std::string import_filename_ = "";
std::string export_filename_ = "";
std::array<uint8_t, kWidthArraySize> width_array = {0}; std::array<uint8_t, kWidthArraySize> width_array = {0};
std::vector<uint8_t> font_gfx16_data_; std::vector<uint8_t> font_gfx16_data_;
@@ -96,6 +110,8 @@ class MessageEditor : public Editor, public SharedRom {
gui::Canvas font_gfx_canvas_{"##FontGfxCanvas", ImVec2(128, 128)}; gui::Canvas font_gfx_canvas_{"##FontGfxCanvas", ImVec2(128, 128)};
gui::Canvas current_font_gfx16_canvas_{"##CurrentMessageGfx", gui::Canvas current_font_gfx16_canvas_{"##CurrentMessageGfx",
ImVec2(172, 4096)}; ImVec2(172, 4096)};
gui::Canvas tile_editor_canvas_{"##TileEditorCanvas", ImVec2(256, 256)};
gui::Canvas tile_preview_canvas_{"##TilePreviewCanvas", ImVec2(64, 64)};
struct TextBox { struct TextBox {
std::string text; std::string text;
@@ -153,6 +169,8 @@ class MessageEditor : public Editor, public SharedRom {
}; };
TextBox message_text_box_; TextBox message_text_box_;
absl::Status status_;
}; };
} // namespace editor } // namespace editor