Refactor MessageEditor to utilize gfx::SnesColor for font preview colors and replace custom TextBox implementation with gui::TextBox for improved functionality; adjust child window dimensions dynamically based on current font bitmap size.
This commit is contained in:
@@ -50,10 +50,10 @@ void MessageEditor::Initialize() {
|
|||||||
all_dictionaries_ = BuildDictionaryEntries(rom());
|
all_dictionaries_ = BuildDictionaryEntries(rom());
|
||||||
ReadAllTextData(rom(), list_of_texts_);
|
ReadAllTextData(rom(), list_of_texts_);
|
||||||
|
|
||||||
font_preview_colors_.AddColor(0x7FFF); // White
|
font_preview_colors_.AddColor(gfx::SnesColor(0x7FFF)); // White
|
||||||
font_preview_colors_.AddColor(0x7C00); // Red
|
font_preview_colors_.AddColor(gfx::SnesColor(0x7C00)); // Red
|
||||||
font_preview_colors_.AddColor(0x03E0); // Green
|
font_preview_colors_.AddColor(gfx::SnesColor(0x03E0)); // Green
|
||||||
font_preview_colors_.AddColor(0x001F); // Blue
|
font_preview_colors_.AddColor(gfx::SnesColor(0x001F)); // Blue
|
||||||
|
|
||||||
std::vector<uint8_t> data(0x4000, 0);
|
std::vector<uint8_t> data(0x4000, 0);
|
||||||
for (int i = 0; i < 0x4000; i++) {
|
for (int i = 0; i < 0x4000; i++) {
|
||||||
@@ -190,8 +190,8 @@ void MessageEditor::DrawCurrentMessage() {
|
|||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
gui::BeginPadding(1);
|
gui::BeginPadding(1);
|
||||||
BeginChild("CurrentGfxFont", ImVec2(200, 0), true,
|
BeginChild("CurrentGfxFont", ImVec2(current_font_gfx16_bitmap_.width(), 0),
|
||||||
ImGuiWindowFlags_AlwaysVerticalScrollbar);
|
true, ImGuiWindowFlags_AlwaysVerticalScrollbar);
|
||||||
current_font_gfx16_canvas_.DrawBackground();
|
current_font_gfx16_canvas_.DrawBackground();
|
||||||
gui::EndPadding();
|
gui::EndPadding();
|
||||||
current_font_gfx16_canvas_.DrawContextMenu();
|
current_font_gfx16_canvas_.DrawContextMenu();
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
#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"
|
||||||
@@ -12,6 +10,7 @@
|
|||||||
#include "app/editor/message/message_data.h"
|
#include "app/editor/message/message_data.h"
|
||||||
#include "app/gfx/bitmap.h"
|
#include "app/gfx/bitmap.h"
|
||||||
#include "app/gui/canvas.h"
|
#include "app/gui/canvas.h"
|
||||||
|
#include "app/gui/style.h"
|
||||||
#include "app/rom.h"
|
#include "app/rom.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
@@ -113,62 +112,7 @@ class MessageEditor : public Editor {
|
|||||||
gui::Canvas tile_editor_canvas_{"##TileEditorCanvas", ImVec2(256, 256)};
|
gui::Canvas tile_editor_canvas_{"##TileEditorCanvas", ImVec2(256, 256)};
|
||||||
gui::Canvas tile_preview_canvas_{"##TilePreviewCanvas", ImVec2(64, 64)};
|
gui::Canvas tile_preview_canvas_{"##TilePreviewCanvas", ImVec2(64, 64)};
|
||||||
|
|
||||||
struct TextBox {
|
gui::TextBox message_text_box_;
|
||||||
std::string text;
|
|
||||||
std::string buffer;
|
|
||||||
int cursor_pos = 0;
|
|
||||||
int selection_start = 0;
|
|
||||||
int selection_end = 0;
|
|
||||||
int selection_length = 0;
|
|
||||||
bool has_selection = false;
|
|
||||||
bool has_focus = false;
|
|
||||||
bool changed = false;
|
|
||||||
bool can_undo = false;
|
|
||||||
|
|
||||||
void Undo() {
|
|
||||||
text = buffer;
|
|
||||||
cursor_pos = selection_start;
|
|
||||||
has_selection = false;
|
|
||||||
}
|
|
||||||
void clearUndo() { can_undo = false; }
|
|
||||||
void Copy() { ImGui::SetClipboardText(text.c_str()); }
|
|
||||||
void Cut() {
|
|
||||||
Copy();
|
|
||||||
text.erase(selection_start, selection_end - selection_start);
|
|
||||||
cursor_pos = selection_start;
|
|
||||||
has_selection = false;
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
void Paste() {
|
|
||||||
text.erase(selection_start, selection_end - selection_start);
|
|
||||||
text.insert(selection_start, ImGui::GetClipboardText());
|
|
||||||
std::string str = ImGui::GetClipboardText();
|
|
||||||
cursor_pos = selection_start + str.size();
|
|
||||||
has_selection = false;
|
|
||||||
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_;
|
|
||||||
|
|
||||||
absl::Status status_;
|
absl::Status status_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef YAZE_APP_CORE_STYLE_H
|
#ifndef YAZE_APP_CORE_STYLE_H
|
||||||
#define YAZE_APP_CORE_STYLE_H
|
#define YAZE_APP_CORE_STYLE_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -71,54 +72,152 @@ void TextWithSeparators(const absl::string_view &text);
|
|||||||
|
|
||||||
void DrawFontManager();
|
void DrawFontManager();
|
||||||
|
|
||||||
static const char *ExampleNames[] = {
|
struct TextBox {
|
||||||
"Artichoke", "Arugula", "Asparagus", "Avocado",
|
std::string text;
|
||||||
"Bamboo Shoots", "Bean Sprouts", "Beans", "Beet",
|
std::string buffer;
|
||||||
"Belgian Endive", "Bell Pepper", "Bitter Gourd", "Bok Choy",
|
int cursor_pos = 0;
|
||||||
"Broccoli", "Brussels Sprouts", "Burdock Root", "Cabbage",
|
int selection_start = 0;
|
||||||
"Calabash", "Capers", "Carrot", "Cassava",
|
int selection_end = 0;
|
||||||
"Cauliflower", "Celery", "Celery Root", "Celcuce",
|
int selection_length = 0;
|
||||||
"Chayote", "Chinese Broccoli", "Corn", "Cucumber"};
|
bool has_selection = false;
|
||||||
|
bool has_focus = false;
|
||||||
|
bool changed = false;
|
||||||
|
bool can_undo = false;
|
||||||
|
|
||||||
struct MultiSelectWithClipper {
|
void Undo() {
|
||||||
const int ITEMS_COUNT = 10000;
|
text = buffer;
|
||||||
void Update() {
|
cursor_pos = selection_start;
|
||||||
// Use default selection.Adapter: Pass index to
|
has_selection = false;
|
||||||
// SetNextItemSelectionUserData(), store index in Selection
|
}
|
||||||
static ImGuiSelectionBasicStorage selection;
|
void clearUndo() { can_undo = false; }
|
||||||
|
void Copy() { ImGui::SetClipboardText(text.c_str()); }
|
||||||
|
void Cut() {
|
||||||
|
Copy();
|
||||||
|
text.erase(selection_start, selection_end - selection_start);
|
||||||
|
cursor_pos = selection_start;
|
||||||
|
has_selection = false;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
void Paste() {
|
||||||
|
text.erase(selection_start, selection_end - selection_start);
|
||||||
|
text.insert(selection_start, ImGui::GetClipboardText());
|
||||||
|
std::string str = ImGui::GetClipboardText();
|
||||||
|
cursor_pos = selection_start + str.size();
|
||||||
|
has_selection = false;
|
||||||
|
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; }
|
||||||
|
};
|
||||||
|
|
||||||
ImGui::Text("Selection: %d/%d", selection.Size, ITEMS_COUNT);
|
// Generic multi-select component that can be used with different types of data
|
||||||
if (ImGui::BeginChild(
|
template <typename T>
|
||||||
"##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20),
|
class MultiSelect {
|
||||||
ImGuiChildFlags_FrameStyle | ImGuiChildFlags_ResizeY)) {
|
public:
|
||||||
|
// Callback function type for rendering an item
|
||||||
|
using ItemRenderer =
|
||||||
|
std::function<void(int index, const T &item, bool is_selected)>;
|
||||||
|
|
||||||
|
// Constructor with optional title and default flags
|
||||||
|
MultiSelect(
|
||||||
|
const char *title = "Selection",
|
||||||
ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_ClearOnEscape |
|
ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_ClearOnEscape |
|
||||||
ImGuiMultiSelectFlags_BoxSelect1d;
|
ImGuiMultiSelectFlags_BoxSelect1d)
|
||||||
|
: title_(title), flags_(flags), selection_() {}
|
||||||
|
|
||||||
|
// Set the items to display
|
||||||
|
void SetItems(const std::vector<T> &items) { items_ = items; }
|
||||||
|
|
||||||
|
// Set the renderer function for items
|
||||||
|
void SetItemRenderer(ItemRenderer renderer) { item_renderer_ = renderer; }
|
||||||
|
|
||||||
|
// Set the height of the selection area (in font size units)
|
||||||
|
void SetHeight(float height_in_font_units = 20.0f) {
|
||||||
|
height_in_font_units_ = height_in_font_units;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the child window flags
|
||||||
|
void SetChildFlags(ImGuiChildFlags flags) { child_flags_ = flags; }
|
||||||
|
|
||||||
|
// Update and render the multi-select component
|
||||||
|
void Update() {
|
||||||
|
ImGui::Text("%s: %d/%d", title_, selection_.Size, items_.size());
|
||||||
|
|
||||||
|
if (ImGui::BeginChild(
|
||||||
|
"##MultiSelectChild",
|
||||||
|
ImVec2(-FLT_MIN, ImGui::GetFontSize() * height_in_font_units_),
|
||||||
|
child_flags_)) {
|
||||||
ImGuiMultiSelectIO *ms_io =
|
ImGuiMultiSelectIO *ms_io =
|
||||||
ImGui::BeginMultiSelect(flags, selection.Size, ITEMS_COUNT);
|
ImGui::BeginMultiSelect(flags_, selection_.Size, items_.size());
|
||||||
selection.ApplyRequests(ms_io);
|
selection_.ApplyRequests(ms_io);
|
||||||
|
|
||||||
ImGuiListClipper clipper;
|
ImGuiListClipper clipper;
|
||||||
clipper.Begin(ITEMS_COUNT);
|
clipper.Begin(items_.size());
|
||||||
if (ms_io->RangeSrcItem != -1)
|
if (ms_io->RangeSrcItem != -1)
|
||||||
clipper.IncludeItemByIndex(
|
clipper.IncludeItemByIndex((int)ms_io->RangeSrcItem);
|
||||||
(int)ms_io->RangeSrcItem); // Ensure RangeSrc item is not clipped.
|
|
||||||
while (clipper.Step()) {
|
while (clipper.Step()) {
|
||||||
for (int n = clipper.DisplayStart; n < clipper.DisplayEnd; n++) {
|
for (int n = clipper.DisplayStart; n < clipper.DisplayEnd; n++) {
|
||||||
char label[64];
|
bool item_is_selected = selection_.Contains((ImGuiID)n);
|
||||||
// sprintf(label, "Object %05d: %s", n,
|
|
||||||
// ExampleNames[n % IM_ARRAYSIZE(ExampleNames)]);
|
|
||||||
bool item_is_selected = selection.Contains((ImGuiID)n);
|
|
||||||
ImGui::SetNextItemSelectionUserData(n);
|
ImGui::SetNextItemSelectionUserData(n);
|
||||||
ImGui::Selectable(label, item_is_selected);
|
|
||||||
|
if (item_renderer_) {
|
||||||
|
item_renderer_(n, items_[n], item_is_selected);
|
||||||
|
} else {
|
||||||
|
// Default rendering if no custom renderer is provided
|
||||||
|
char label[64];
|
||||||
|
snprintf(label, sizeof(label), "Item %d", n);
|
||||||
|
ImGui::Selectable(label, item_is_selected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ms_io = ImGui::EndMultiSelect();
|
ms_io = ImGui::EndMultiSelect();
|
||||||
selection.ApplyRequests(ms_io);
|
selection_.ApplyRequests(ms_io);
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
ImGui::TreePop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the selected indices
|
||||||
|
std::vector<int> GetSelectedIndices() const {
|
||||||
|
std::vector<int> indices;
|
||||||
|
for (int i = 0; i < items_.size(); i++) {
|
||||||
|
if (selection_.Contains((ImGuiID)i)) {
|
||||||
|
indices.push_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the selection
|
||||||
|
void ClearSelection() { selection_.Clear(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char *title_;
|
||||||
|
ImGuiMultiSelectFlags flags_;
|
||||||
|
ImGuiSelectionBasicStorage selection_;
|
||||||
|
std::vector<T> items_;
|
||||||
|
ItemRenderer item_renderer_;
|
||||||
|
float height_in_font_units_ = 20.0f;
|
||||||
|
ImGuiChildFlags child_flags_ =
|
||||||
|
ImGuiChildFlags_FrameStyle | ImGuiChildFlags_ResizeY;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace gui
|
||||||
|
|||||||
Reference in New Issue
Block a user