Add text editor module for cardinal

Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
falkTX 2021-12-17 14:21:23 +00:00
parent bba168ecc6
commit 268c31c029
No known key found for this signature in database
GPG key ID: CDBAA37ABC74FBA0
13 changed files with 3957 additions and 26 deletions

2
dpf

@ -1 +1 @@
Subproject commit 400dca29de54e1cceee55f22672e940ae5d5e005
Subproject commit 493837049e773e45f842c0ee83b6b69c7c56adf9

View file

@ -75,6 +75,15 @@
"tags": [
"Utility"
]
},
{
"slug": "TextEditor",
"disabled": false,
"name": "Text Editor",
"description": "A embed text editor inside Cardinal",
"tags": [
"Utility"
]
}
]
}

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 BalazsJako
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,398 @@
#pragma once
#include <string>
#include <vector>
#include <array>
#include <memory>
#include <unordered_set>
#include <unordered_map>
#include <map>
#include <regex>
#include "../DearImGui/imgui.h"
class TextEditor
{
public:
enum class PaletteIndex
{
Default,
Keyword,
Number,
String,
CharLiteral,
Punctuation,
Preprocessor,
Identifier,
KnownIdentifier,
PreprocIdentifier,
Comment,
MultiLineComment,
Background,
Cursor,
Selection,
ErrorMarker,
Breakpoint,
LineNumber,
CurrentLineFill,
CurrentLineFillInactive,
CurrentLineEdge,
Max
};
enum class SelectionMode
{
Normal,
Word,
Line
};
struct Breakpoint
{
int mLine;
bool mEnabled;
std::string mCondition;
Breakpoint()
: mLine(-1)
, mEnabled(false)
{}
};
// Represents a character coordinate from the user's point of view,
// i. e. consider an uniform grid (assuming fixed-width font) on the
// screen as it is rendered, and each cell has its own coordinate, starting from 0.
// Tabs are counted as [1..mTabSize] count empty spaces, depending on
// how many space is necessary to reach the next tab stop.
// For example, coordinate (1, 5) represents the character 'B' in a line "\tABC", when mTabSize = 4,
// because it is rendered as " ABC" on the screen.
struct Coordinates
{
int mLine, mColumn;
Coordinates() : mLine(0), mColumn(0) {}
Coordinates(int aLine, int aColumn) : mLine(aLine), mColumn(aColumn)
{
assert(aLine >= 0);
assert(aColumn >= 0);
}
static Coordinates Invalid() { static Coordinates invalid(-1, -1); return invalid; }
bool operator ==(const Coordinates& o) const
{
return
mLine == o.mLine &&
mColumn == o.mColumn;
}
bool operator !=(const Coordinates& o) const
{
return
mLine != o.mLine ||
mColumn != o.mColumn;
}
bool operator <(const Coordinates& o) const
{
if (mLine != o.mLine)
return mLine < o.mLine;
return mColumn < o.mColumn;
}
bool operator >(const Coordinates& o) const
{
if (mLine != o.mLine)
return mLine > o.mLine;
return mColumn > o.mColumn;
}
bool operator <=(const Coordinates& o) const
{
if (mLine != o.mLine)
return mLine < o.mLine;
return mColumn <= o.mColumn;
}
bool operator >=(const Coordinates& o) const
{
if (mLine != o.mLine)
return mLine > o.mLine;
return mColumn >= o.mColumn;
}
};
struct Identifier
{
Coordinates mLocation;
std::string mDeclaration;
};
typedef std::string String;
typedef std::unordered_map<std::string, Identifier> Identifiers;
typedef std::unordered_set<std::string> Keywords;
typedef std::map<int, std::string> ErrorMarkers;
typedef std::unordered_set<int> Breakpoints;
typedef std::array<ImU32, (unsigned)PaletteIndex::Max> Palette;
typedef uint8_t Char;
struct Glyph
{
Char mChar;
PaletteIndex mColorIndex = PaletteIndex::Default;
bool mComment : 1;
bool mMultiLineComment : 1;
bool mPreprocessor : 1;
Glyph(Char aChar, PaletteIndex aColorIndex) : mChar(aChar), mColorIndex(aColorIndex),
mComment(false), mMultiLineComment(false), mPreprocessor(false) {}
};
typedef std::vector<Glyph> Line;
typedef std::vector<Line> Lines;
struct LanguageDefinition
{
typedef std::pair<std::string, PaletteIndex> TokenRegexString;
typedef std::vector<TokenRegexString> TokenRegexStrings;
typedef bool(*TokenizeCallback)(const char * in_begin, const char * in_end, const char *& out_begin, const char *& out_end, PaletteIndex & paletteIndex);
typedef void(*ColorizeCallback)(Lines &lines, void *data);
std::string mName;
Keywords mKeywords;
Identifiers mIdentifiers;
Identifiers mPreprocIdentifiers;
std::string mCommentStart, mCommentEnd, mSingleLineComment;
char mPreprocChar;
bool mAutoIndentation;
ColorizeCallback mColorize;
void *mColorizeData;
TokenizeCallback mTokenize;
TokenRegexStrings mTokenRegexStrings;
bool mCaseSensitive;
LanguageDefinition()
: mPreprocChar('#')
, mAutoIndentation(true)
, mColorize(nullptr)
, mColorizeData(nullptr)
, mTokenize(nullptr)
, mCaseSensitive(true)
{
}
static const LanguageDefinition& CPlusPlus();
static const LanguageDefinition& HLSL();
static const LanguageDefinition& GLSL();
static const LanguageDefinition& C();
static const LanguageDefinition& SQL();
static const LanguageDefinition& AngelScript();
static const LanguageDefinition& Lua();
};
TextEditor();
~TextEditor();
void SetLanguageDefinition(const LanguageDefinition& aLanguageDef);
const LanguageDefinition& GetLanguageDefinition() const { return mLanguageDefinition; }
const Palette& GetPalette() const { return mPaletteBase; }
void SetPalette(const Palette& aValue);
void SetErrorMarkers(const ErrorMarkers& aMarkers) { mErrorMarkers = aMarkers; }
void SetBreakpoints(const Breakpoints& aMarkers) { mBreakpoints = aMarkers; }
void Render(const char* aTitle, const ImVec2& aSize = ImVec2(), bool aBorder = false);
void SetText(const std::string& aText);
std::string GetText() const;
void SetTextLines(const std::vector<std::string>& aLines);
std::vector<std::string> GetTextLines() const;
std::string GetSelectedText() const;
std::string GetCurrentLineText()const;
int GetTotalLines() const { return (int)mLines.size(); }
bool IsOverwrite() const { return mOverwrite; }
void SetReadOnly(bool aValue);
bool IsReadOnly() const { return mReadOnly; }
bool IsTextChanged() const { return mTextChanged; }
bool IsCursorPositionChanged() const { return mCursorPositionChanged; }
bool IsColorizerEnabled() const { return mColorizerEnabled; }
void SetColorizerEnable(bool aValue);
Coordinates GetCursorPosition() const { return GetActualCursorCoordinates(); }
void SetCursorPosition(const Coordinates& aPosition);
inline void SetHandleMouseInputs (bool aValue){ mHandleMouseInputs = aValue;}
inline bool IsHandleMouseInputsEnabled() const { return mHandleMouseInputs; }
inline void SetHandleKeyboardInputs (bool aValue){ mHandleKeyboardInputs = aValue;}
inline bool IsHandleKeyboardInputsEnabled() const { return mHandleKeyboardInputs; }
inline void SetImGuiChildIgnored (bool aValue){ mIgnoreImGuiChild = aValue;}
inline bool IsImGuiChildIgnored() const { return mIgnoreImGuiChild; }
inline void SetShowWhitespaces(bool aValue) { mShowWhitespaces = aValue; }
inline bool IsShowingWhitespaces() const { return mShowWhitespaces; }
void SetTabSize(int aValue);
inline int GetTabSize() const { return mTabSize; }
void InsertText(const std::string& aValue);
void InsertText(const char* aValue);
void MoveUp(int aAmount = 1, bool aSelect = false);
void MoveDown(int aAmount = 1, bool aSelect = false);
void MoveLeft(int aAmount = 1, bool aSelect = false, bool aWordMode = false);
void MoveRight(int aAmount = 1, bool aSelect = false, bool aWordMode = false);
void MoveTop(bool aSelect = false);
void MoveBottom(bool aSelect = false);
void MoveHome(bool aSelect = false);
void MoveEnd(bool aSelect = false);
void SetSelectionStart(const Coordinates& aPosition);
void SetSelectionEnd(const Coordinates& aPosition);
void SetSelection(const Coordinates& aStart, const Coordinates& aEnd, SelectionMode aMode = SelectionMode::Normal);
void SelectWordUnderCursor();
void SelectAll();
bool HasSelection() const;
void Copy();
void Cut();
void Paste();
void Delete();
bool CanUndo() const;
bool CanRedo() const;
void Undo(int aSteps = 1);
void Redo(int aSteps = 1);
static const Palette& GetDarkPalette();
static const Palette& GetLightPalette();
static const Palette& GetRetroBluePalette();
private:
typedef std::vector<std::pair<std::regex, PaletteIndex>> RegexList;
struct EditorState
{
Coordinates mSelectionStart;
Coordinates mSelectionEnd;
Coordinates mCursorPosition;
};
class UndoRecord
{
public:
UndoRecord() {}
~UndoRecord() {}
UndoRecord(
const std::string& aAdded,
const TextEditor::Coordinates aAddedStart,
const TextEditor::Coordinates aAddedEnd,
const std::string& aRemoved,
const TextEditor::Coordinates aRemovedStart,
const TextEditor::Coordinates aRemovedEnd,
TextEditor::EditorState& aBefore,
TextEditor::EditorState& aAfter);
void Undo(TextEditor* aEditor);
void Redo(TextEditor* aEditor);
std::string mAdded;
Coordinates mAddedStart;
Coordinates mAddedEnd;
std::string mRemoved;
Coordinates mRemovedStart;
Coordinates mRemovedEnd;
EditorState mBefore;
EditorState mAfter;
};
typedef std::vector<UndoRecord> UndoBuffer;
void ProcessInputs();
void Colorize(int aFromLine = 0, int aCount = -1);
void ColorizeRange(int aFromLine = 0, int aToLine = 0);
void ColorizeInternal();
float TextDistanceToLineStart(const Coordinates& aFrom) const;
void EnsureCursorVisible();
int GetPageSize() const;
std::string GetText(const Coordinates& aStart, const Coordinates& aEnd) const;
Coordinates GetActualCursorCoordinates() const;
Coordinates SanitizeCoordinates(const Coordinates& aValue) const;
void Advance(Coordinates& aCoordinates) const;
void DeleteRange(const Coordinates& aStart, const Coordinates& aEnd);
int InsertTextAt(Coordinates& aWhere, const char* aValue);
void AddUndo(UndoRecord& aValue);
Coordinates ScreenPosToCoordinates(const ImVec2& aPosition) const;
Coordinates FindWordStart(const Coordinates& aFrom) const;
Coordinates FindWordEnd(const Coordinates& aFrom) const;
Coordinates FindNextWord(const Coordinates& aFrom) const;
int GetCharacterIndex(const Coordinates& aCoordinates) const;
int GetCharacterColumn(int aLine, int aIndex) const;
int GetLineCharacterCount(int aLine) const;
int GetLineMaxColumn(int aLine) const;
bool IsOnWordBoundary(const Coordinates& aAt) const;
void RemoveLine(int aStart, int aEnd);
void RemoveLine(int aIndex);
Line& InsertLine(int aIndex);
void EnterCharacter(ImWchar aChar, bool aShift);
void Backspace();
void DeleteSelection();
std::string GetWordUnderCursor() const;
std::string GetWordAt(const Coordinates& aCoords) const;
ImU32 GetGlyphColor(const Glyph& aGlyph) const;
void HandleKeyboardInputs();
void HandleMouseInputs();
void Render();
float mLineSpacing;
Lines mLines;
EditorState mState;
UndoBuffer mUndoBuffer;
int mUndoIndex;
int mTabSize;
bool mOverwrite;
bool mReadOnly;
bool mWithinRender;
bool mScrollToCursor;
bool mScrollToTop;
bool mTextChanged;
bool mColorizerEnabled;
float mTextStart; // position (in pixels) where a code line starts relative to the left of the TextEditor.
int mLeftMargin;
bool mCursorPositionChanged;
int mColorRangeMin, mColorRangeMax;
SelectionMode mSelectionMode;
bool mHandleKeyboardInputs;
bool mHandleMouseInputs;
bool mIgnoreImGuiChild;
bool mShowWhitespaces;
Palette mPaletteBase;
Palette mPalette;
LanguageDefinition mLanguageDefinition;
RegexList mRegexList;
bool mCheckComments;
Breakpoints mBreakpoints;
ErrorMarkers mErrorMarkers;
ImVec2 mCharAdvance;
Coordinates mInteractiveStart, mInteractiveEnd;
std::string mLineBuffer;
uint64_t mStartTime;
float mLastClick;
};

View file

@ -722,30 +722,6 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread {
std::strcpy(fPluginSearchString, "Search...");
ImGuiStyle& style(ImGui::GetStyle());
style.FrameRounding = 4;
ImVec4* colors = ImGui::GetStyle().Colors;
ImVec4 color_Cardinal = ImVec4(0.76f, 0.11f, 0.22f, 1.00f);
ImVec4 color_DimCardinal = ImVec4(171.0 / 255.0, 54.0 / 255.0, 73.0 / 255.0, 1.00f);
colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.101f, 0.101f, 0.101f, 0.94f);
colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.21f, 0.22f, 0.54f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.40f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.18f, 0.18f, 0.18f, 0.67f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.29f, 0.29f, 0.29f, 1.00f);
colors[ImGuiCol_CheckMark] = color_Cardinal;
colors[ImGuiCol_SliderGrab] = color_DimCardinal;
colors[ImGuiCol_SliderGrabActive] = color_Cardinal;
colors[ImGuiCol_Button] = color_DimCardinal;
colors[ImGuiCol_ButtonHovered] = color_Cardinal;
colors[ImGuiCol_ButtonActive] = color_Cardinal;
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.87f, 0.87f, 0.87f, 0.35f);
colors[ImGuiCol_Header] = ImVec4(0.44f, 0.44f, 0.44f, 0.40f);
colors[ImGuiCol_HeaderHovered] = color_DimCardinal;
colors[ImGuiCol_HeaderActive] = color_Cardinal;
if (checkIfPluginIsLoaded())
fIdleState = kIdleInitPluginAlreadyLoaded;

View file

@ -0,0 +1,125 @@
/*
* Syntax highlighting text editor (for ImGui in DPF)
* Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
* Copyright (c) 2017 BalazsJako
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "ImGuiTextEditor.hpp"
#include "DearImGuiColorTextEditor/TextEditor.h"
// --------------------------------------------------------------------------------------------------------------------
struct ImGuiTextEditor::PrivateData {
ImGuiTextEditor* const self;
TextEditor editor;
std::string file;
explicit PrivateData(ImGuiTextEditor* const s)
: self(s)
{
// https://github.com/BalazsJako/ColorTextEditorDemo/blob/master/main.cpp
editor.SetLanguageDefinition(TextEditor::LanguageDefinition::CPlusPlus());
editor.SetText(""
"// Welcome to a real text editor inside Cardinal\n"
"\n"
"#define I_AM_A_MACRO\n"
"\n"
"int and_i_am_a_variable;\n"
"\n"
"/* look ma, a comment! */\n"
"int such_highlight_much_wow() { return 1337; }\n"
);
editor.SetCursorPosition(TextEditor::Coordinates(8, 0));
}
DISTRHO_DECLARE_NON_COPYABLE(PrivateData)
};
// --------------------------------------------------------------------------------------------------------------------
ImGuiTextEditor::ImGuiTextEditor()
: ImGuiWidget(),
pData(new PrivateData(this)) {}
ImGuiTextEditor::~ImGuiTextEditor()
{
delete pData;
}
// --------------------------------------------------------------------------------------------------------------------
void ImGuiTextEditor::setText(const std::string& text)
{
pData->editor.SetText(text);
}
std::string ImGuiTextEditor::getText() const
{
return pData->editor.GetText();
}
void ImGuiTextEditor::setTextLines(const std::vector<std::string>& lines)
{
pData->editor.SetTextLines(lines);
}
std::vector<std::string> ImGuiTextEditor::getTextLines() const
{
return pData->editor.GetTextLines();
}
std::string ImGuiTextEditor::getSelectedText() const
{
return pData->editor.GetSelectedText();
}
std::string ImGuiTextEditor::getCurrentLineText()const
{
return pData->editor.GetCurrentLineText();
}
// --------------------------------------------------------------------------------------------------------------------
void ImGuiTextEditor::drawImGui()
{
ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSize(ImVec2(box.size.x, box.size.y));
if (ImGui::Begin("TextEdit", nullptr, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize))
{
TextEditor& editor(pData->editor);
const TextEditor::Coordinates cpos = editor.GetCursorPosition();
ImGui::Text("%6d/%-6d %6d lines | %s | %s | %s | %s",
cpos.mLine + 1, cpos.mColumn + 1,
editor.GetTotalLines(),
editor.IsOverwrite() ? "Ovr" : "Ins",
editor.CanUndo() ? "*" : " ",
editor.GetLanguageDefinition().mName.c_str(),
pData->file.c_str());
editor.Render("TextEditor");
}
ImGui::End();
}

View file

@ -0,0 +1,56 @@
/*
* Syntax highlighting text editor (for ImGui in DPF, converted to VCV)
* Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
* Copyright (c) 2017 BalazsJako
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#pragma once
#include "ImGuiWidget.hpp"
#include "DearImGuiColorTextEditor/TextEditor.h"
#include <string>
#include <vector>
struct ImGuiTextEditor : ImGuiWidget
{
struct PrivateData;
PrivateData* const pData;
ImGuiTextEditor();
~ImGuiTextEditor() override;
/**
Methods from internal TextEdit.
*/
void setText(const std::string& text);
std::string getText() const;
void setTextLines(const std::vector<std::string>& lines);
std::vector<std::string> getTextLines() const;
std::string getSelectedText() const;
std::string getCurrentLineText()const;
protected:
/** @internal */
void drawImGui() override;
};

View file

@ -38,11 +38,34 @@ struct ImGuiWidget::PrivateData {
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.IniFilename = nullptr;
/*
ImGuiStyle& style(ImGui::GetStyle());
style.FrameRounding = 4;
/*
style.ScaleAllSizes(scaleFactor);
*/
const ImVec4 color_Cardinal(0.76f, 0.11f, 0.22f, 1.00f);
const ImVec4 color_DimCardinal(171.0 / 255.0, 54.0 / 255.0, 73.0 / 255.0, 1.00f);
ImVec4* const colors = style.Colors;
colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.101f, 0.101f, 0.101f, 0.94f);
colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.21f, 0.22f, 0.54f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.40f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.18f, 0.18f, 0.18f, 0.67f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.29f, 0.29f, 0.29f, 1.00f);
colors[ImGuiCol_CheckMark] = color_Cardinal;
colors[ImGuiCol_SliderGrab] = color_DimCardinal;
colors[ImGuiCol_SliderGrabActive] = color_Cardinal;
colors[ImGuiCol_Button] = color_DimCardinal;
colors[ImGuiCol_ButtonHovered] = color_Cardinal;
colors[ImGuiCol_ButtonActive] = color_Cardinal;
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.87f, 0.87f, 0.87f, 0.35f);
colors[ImGuiCol_Header] = ImVec4(0.44f, 0.44f, 0.44f, 0.40f);
colors[ImGuiCol_HeaderHovered] = color_DimCardinal;
colors[ImGuiCol_HeaderActive] = color_Cardinal;
#ifndef DGL_NO_SHARED_RESOURCES
using namespace dpf_resources;
ImFontConfig fc;

View file

@ -0,0 +1,139 @@
/*
* DISTRHO Cardinal Plugin
* Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the LICENSE file.
*/
#include "plugincontext.hpp"
#ifndef HEADLESS
# include "ImGuiTextEditor.hpp"
# include "extra/FileBrowserDialog.hpp"
#endif
#include <fstream>
// --------------------------------------------------------------------------------------------------------------------
struct TextEditorModule : Module {
enum ParamIds {
NUM_PARAMS
};
enum InputIds {
NUM_INPUTS
};
enum OutputIds {
NUM_OUTPUTS
};
enum LightIds {
NUM_LIGHTS
};
TextEditorModule()
{
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
}
~TextEditorModule() override
{
}
void process(const ProcessArgs&) override
{
}
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TextEditorModule)
};
// --------------------------------------------------------------------------------------------------------------------
#ifndef HEADLESS
struct TextEditorWidget : ImGuiTextEditor
{
TextEditorWidget() : ImGuiTextEditor() {}
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TextEditorWidget)
};
// --------------------------------------------------------------------------------------------------------------------
struct TextEditorLoadFileItem : MenuItem {
TextEditorWidget* widget = nullptr;
void onAction(const event::Action &e) override
{
WeakPtr<TextEditorWidget> widget = this->widget;
async_dialog_filebrowser(false, nullptr, "Load File", [widget](char* path)
{
if (path)
{
if (widget)
{
std::ifstream f(path);
if (f.good())
{
const std::string str((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
widget->setText(str);
}
}
free(path);
}
});
}
};
// --------------------------------------------------------------------------------------------------------------------
struct TextEditorModuleWidget : ModuleWidget {
TextEditorWidget* textEditorWidget = nullptr;
TextEditorModuleWidget(TextEditorModule* const module)
{
setModule(module);
setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Ildaeil.svg")));
if (module != nullptr)
{
textEditorWidget = new TextEditorWidget();
textEditorWidget->box.pos = Vec(2 * RACK_GRID_WIDTH, 0);
textEditorWidget->box.size = Vec(box.size.x - 2 * RACK_GRID_WIDTH, box.size.y);
addChild(textEditorWidget);
}
addChild(createWidget<ScrewBlack>(Vec(0, 0)));
addChild(createWidget<ScrewBlack>(Vec(0, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
addChild(createWidget<ScrewBlack>(Vec(RACK_GRID_WIDTH, 0)));
addChild(createWidget<ScrewBlack>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
}
void appendContextMenu(Menu *menu) override {
menu->addChild(new MenuEntry);
TextEditorLoadFileItem* loadFileItem = new TextEditorLoadFileItem;
loadFileItem->text = "Load File";
loadFileItem->widget = textEditorWidget;
menu->addChild(loadFileItem);
}
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TextEditorModuleWidget)
};
#else
typedef ModuleWidget TextEditorModuleWidget;
#endif
// --------------------------------------------------------------------------------------------------------------------
Model* modelTextEditor = createModel<TextEditorModule, TextEditorModuleWidget>("TextEditor");
// --------------------------------------------------------------------------------------------------------------------

View file

@ -34,3 +34,4 @@ extern Model* modelHostCV;
extern Model* modelHostParameters;
extern Model* modelHostTime;
extern Model* modelIldaeil;
extern Model* modelTextEditor;

View file

@ -192,10 +192,13 @@ PLUGIN_FILES += Cardinal/src/HostCV.cpp
PLUGIN_FILES += Cardinal/src/HostParameters.cpp
PLUGIN_FILES += Cardinal/src/HostTime.cpp
PLUGIN_FILES += Cardinal/src/Ildaeil.cpp
PLUGIN_FILES += Cardinal/src/TextEditor.cpp
ifneq ($(HEADLESS),true)
PLUGIN_FILES += Cardinal/src/ImGuiWidget.cpp
PLUGIN_FILES += Cardinal/src/ImGuiTextEditor.cpp
PLUGIN_FILES += $(wildcard Cardinal/src/DearImGui/*.cpp)
PLUGIN_FILES += $(wildcard Cardinal/src/DearImGuiColorTextEditor/*.cpp)
endif
ifneq ($(NOPLUGINS),true)

View file

@ -675,6 +675,7 @@ static void initStatic__Cardinal()
p->addModel(modelHostParameters);
p->addModel(modelHostTime);
p->addModel(modelIldaeil);
p->addModel(modelTextEditor);
}
}