diff --git a/src/PowderToySDL.cpp b/src/PowderToySDL.cpp index 701c197a7..7f11a411b 100644 --- a/src/PowderToySDL.cpp +++ b/src/PowderToySDL.cpp @@ -873,7 +873,7 @@ int main(int argc, char * argv[]) #else // FONTEDITOR if(argc <= 1) - throw std::runtime_error("Not enough arguments"); + throw std::runtime_error("Usage: " + ByteString(argv[0]) + " ./data/font.cpp"); engine->ShowWindow(new FontEditor(argv[1])); #endif diff --git a/src/gui/font/FontEditor.cpp b/src/gui/font/FontEditor.cpp index c5ecfd478..149bf7369 100644 --- a/src/gui/font/FontEditor.cpp +++ b/src/gui/font/FontEditor.cpp @@ -13,6 +13,7 @@ #include "gui/interface/Button.h" #include "gui/interface/Mouse.h" #include "gui/interface/Keys.h" +#include "gui/interface/ScrollPanel.h" #include "graphics/Graphics.h" #ifdef FONTEDITOR @@ -254,6 +255,26 @@ void FontEditor::PackData( fontRanges.push_back({0, 0}); } +class StretchLabel: public ui::Label +{ + using Label::Label; +public: + int WrappedLines() const + { + return displayTextWrapper.WrappedLines(); + } +}; + +class StretchTextbox: public ui::Textbox +{ + using Textbox::Textbox; +public: + int WrappedLines() const + { + return displayTextWrapper.WrappedLines(); + } +}; + #define FONT_SCALE 16 FontEditor::FontEditor(ByteString _header): ui::Window(ui::Point(0, 0), ui::Point(WINDOWW, WINDOWH)), @@ -339,8 +360,8 @@ FontEditor::FontEditor(ByteString _header): currentX += 33; showRulers->SetTogglable(true); showRulers->SetToggleState(rulers); - showRulers->SetActionCallback({ [this, showGrid] { - rulers = showGrid->GetToggleState(); + showRulers->SetActionCallback({ [this, showRulers] { + rulers = showRulers->GetToggleState(); } }); AddComponent(showRulers); @@ -375,29 +396,41 @@ FontEditor::FontEditor(ByteString _header): baseline += 18; - outputPreview = new ui::Label(ui::Point(0, baseline + (Size.Y - baseline) * 3 / 5), ui::Point(Size.X, (Size.Y - baseline) * 2 / 5), ""); + ui::ScrollPanel *outputPanel = new ui::ScrollPanel(ui::Point(Size.X / 2, baseline), ui::Point(Size.X / 2, Size.Y - baseline)); + AddComponent(outputPanel); + StretchLabel *outputPreview = new StretchLabel(ui::Point(0, 0), ui::Point(Size.X / 2, 0), ""); outputPreview->SetMultiline(true); outputPreview->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; outputPreview->Appearance.VerticalAlign = ui::Appearance::AlignTop; - AddComponent(outputPreview); + outputPanel->AddChild(outputPreview); - ui::Textbox *inputPreview = new ui::Textbox(ui::Point(0, baseline), ui::Point(Size.X, (Size.Y - baseline) * 3 / 5)); + ui::ScrollPanel *inputPanel = new ui::ScrollPanel(ui::Point(0, baseline), ui::Point(Size.X / 2, Size.Y - baseline)); + AddComponent(inputPanel); + StretchTextbox *inputPreview = new StretchTextbox(ui::Point(0, 0), ui::Point(Size.X / 2, 0)); inputPreview->SetMultiline(true); inputPreview->SetInputType(ui::Textbox::Multiline); inputPreview->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; inputPreview->Appearance.VerticalAlign = ui::Appearance::AlignTop; - auto textChangedCallback = [this, inputPreview] { + auto textChangedCallback = [outputPreview, outputPanel, inputPreview, inputPanel] { String str = inputPreview->GetText(); size_t at = 0; StringBuilder text; while(at < str.size()) { - unsigned int ch; + unsigned int ch1, ch2; if(str[at] != ' ') - if(String::Split split = str.SplitNumber(ch, Format::Hex(), at)) + if(String::Split split1 = str.SplitNumber(ch1, Format::Hex(), at)) { - text << String::value_type(ch); - at = split.PositionAfter(); + if(str[split1.PositionAfter()] == ':') + if(String::Split split2 = str.SplitNumber(ch2, Format::Hex(), split1.PositionAfter() + 1)) + { + for(unsigned int ch = ch1; ch <= ch2; ch++) + text << String::value_type(ch); + at = split2.PositionAfter(); + continue; + } + text << String::value_type(ch1); + at = split1.PositionAfter(); } else { @@ -407,16 +440,21 @@ FontEditor::FontEditor(ByteString _header): at++; } outputPreview->SetText(text.Build()); + outputPanel->InnerSize.Y = outputPreview->Size.Y = std::max(outputPreview->WrappedLines(), 1) * FONT_H + 2; + inputPanel->InnerSize.Y = inputPreview->Size.Y = std::max(inputPreview->WrappedLines(), 1) * FONT_H + 2; }; inputPreview->SetActionCallback({ textChangedCallback }); + inputPanel->AddChild(inputPreview); StringBuilder input; input << Format::Hex() << Format::Width(2); - for(unsigned int ch = 0x20; ch <= 0xFF; ch++) + for(unsigned int ch = 0x20; ch <= 0xFF; ch += 0x10) { - if(!(ch & 0x3F)) - input << 0x20 << " "; - input << ch << " "; + if(ch == 0x80) + input << "\n"; + else if(ch != 0x20) + input << " 0a "; + input << ch << ":" << (ch + 0x0F); } inputPreview->SetText(input.Build()); textChangedCallback(); @@ -478,16 +516,43 @@ void FontEditor::OnMouseDown(int x, int y, unsigned button) } } +void FontEditor::Translate(std::array, FONT_H> &pixels, int dx, int dy) +{ + std::array, FONT_H> old = pixels; + for(int j = 0; j < FONT_H; j++) + for(int i = 0; i < MAX_WIDTH; i++) + if(i - dx >= 0 && i - dx + 1 < MAX_WIDTH && j - dy >= 0 && j - dy + 1 < FONT_H) + pixels[j][i] = old[j - dy][i - dx]; + else + pixels[j][i] = 0; +} + void FontEditor::OnKeyPress(int key, int scan, bool repeat, bool shift, bool ctrl, bool alt) { if (IsFocused(NULL)) { switch(scan) { + case SDL_SCANCODE_UP: + if(shift) + Translate(fontPixels[currentChar], 0, -1); + break; + case SDL_SCANCODE_DOWN: + if(shift) + Translate(fontPixels[currentChar], 0, 1); + break; case SDL_SCANCODE_LEFT: - PrevChar(); break; + if(shift) + Translate(fontPixels[currentChar], -1, 0); + else + PrevChar(); + break; case SDL_SCANCODE_RIGHT: - PrevChar(); break; + if(shift) + Translate(fontPixels[currentChar], 1, 0); + else + NextChar(); + break; case SDL_SCANCODE_ESCAPE: case SDL_SCANCODE_Q: if(savedButton->GetToggleState()) diff --git a/src/gui/font/FontEditor.h b/src/gui/font/FontEditor.h index 439504281..310dea5c9 100644 --- a/src/gui/font/FontEditor.h +++ b/src/gui/font/FontEditor.h @@ -50,7 +50,6 @@ private: ui::Textbox *currentCharTextbox; ui::Button *savedButton; - ui::Label *outputPreview; String::value_type currentChar; int fgR, fgG, fgB; @@ -69,6 +68,7 @@ private: void GrowChar(); void Render(); void Save(); + void Translate(std::array, FONT_H> &, int dx, int dy); public: FontEditor(ByteString header); diff --git a/src/gui/interface/TextWrapper.h b/src/gui/interface/TextWrapper.h index 649435e06..aedaf5649 100644 --- a/src/gui/interface/TextWrapper.h +++ b/src/gui/interface/TextWrapper.h @@ -41,6 +41,11 @@ namespace ui return wrapped_text; } + int WrappedLines() const + { + return wrapped_lines; + } + Index IndexBegin() const { return Index{ 0, 0, 0 };