Clean text rendering in editor.

This commit is contained in:
James Grogan 2022-12-02 11:50:15 +00:00
parent 290b64e230
commit f16dd7c0d9
45 changed files with 59 additions and 60 deletions

View file

@ -0,0 +1,64 @@
set(APP_NAME notes_tk)
message(STATUS "Checking dependencies for app: " ${APP_NAME})
list(APPEND client_HEADERS
NotesTk.h
text_editor/TextEditorView.h
text_editor/TextEditorModel.h
text_editor/TextEditorController.h
text_editor/PlainTextDocument.h
audio_editor/AudioEditorView.h
image_editor/ImageEditorView.h
image_editor/ImageViewWidget.h
canvas/CanvasView.h
canvas/CanvasController.h
mesh_viewer/MeshViewerView.h
mesh_viewer/MeshViewerController.h
mesh_viewer/MeshViewerCanvas.h
web_client/WebClientView.h)
list(APPEND client_LIB_INCLUDES
text_editor/TextEditorView.cpp
text_editor/TextEditorModel.cpp
text_editor/TextEditorController.cpp
text_editor/PlainTextDocument.cpp
audio_editor/AudioEditorView.cpp
image_editor/ImageEditorView.cpp
image_editor/ImageViewWidget.cpp
mesh_viewer/MeshViewerView.cpp
mesh_viewer/MeshViewerController.cpp
mesh_viewer/MeshViewerCanvas.cpp
canvas/CanvasView.cpp
canvas/CanvasController.cpp
web_client/WebClientView.cpp
NotesTk.cpp)
set(DEPENDENCIES_FOUND True)
if(WIN32)
add_executable(${APP_NAME} WIN32 main-win.cpp ${client_LIB_INCLUDES})
else()
find_package(X11 QUIET)
if(X11_FOUND)
add_executable(${APP_NAME} main.cpp ${client_LIB_INCLUDES} ${client_HEADERS})
else()
message(STATUS "X11 not found - skipping")
set(DEPENDENCIES_FOUND FALSE)
endif()
endif()
if(DEPENDENCIES_FOUND)
target_include_directories(${APP_NAME} PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/text_editor"
"${CMAKE_CURRENT_SOURCE_DIR}/audio_editor"
"${CMAKE_CURRENT_SOURCE_DIR}/image_editor"
"${CMAKE_CURRENT_SOURCE_DIR}/web_client"
"${CMAKE_CURRENT_SOURCE_DIR}/canvas"
"${CMAKE_CURRENT_SOURCE_DIR}/mesh_viewer"
)
target_link_libraries(${APP_NAME} PUBLIC client windows console core network database geometry audio web)
set_property(TARGET ${APP_NAME} PROPERTY FOLDER apps)
endif()

71
apps/notes_tk/NotesTk.cpp Normal file
View file

@ -0,0 +1,71 @@
#include "NotesTk.h"
#include "TextEditorView.h"
#include "AudioEditorView.h"
#include "ImageEditorView.h"
#include "WebClientView.h"
#include "CanvasView.h"
#include "MeshViewerView.h"
#include "TabbedPanelWidget.h"
#include "TopBar.h"
#include "TextNode.h"
#include "StatusBar.h"
#include "HorizontalSpacer.h"
#include "DesktopManager.h"
#include "MainApplication.h"
NotesTk::NotesTk(std::unique_ptr<CommandLineArgs> args)
: GuiApplication(std::move(args))
{
}
void NotesTk::initializeViews()
{
auto mainWindow = mDesktopManager->getWindowManager()->getMainWindow();
mainWindow->setSize(800, 600);
mainWindow->setTitle("NotesTK");
auto tabbedPanel = TabbedPanelWidget::Create();
auto textEditor = TextEditorView::Create();
auto path = mMainApplication->getCommandLineArgs()->getLaunchPath();
path /= "out.txt";
textEditor->setName("TextEditor");
textEditor->getController()->SetSavePath(path);
textEditor->getController()->SetLoadPath(path);
textEditor->initialize();
tabbedPanel->addPanel(std::move(textEditor), "Text Editor");
auto audioEditor = AudioEditorView::Create();
audioEditor->setName("audioEditor");
tabbedPanel->addPanel(std::move(audioEditor), "Audio Editor");
auto imageEditor = ImageEditorView::Create();
imageEditor->setName("imageEditor");
tabbedPanel->addPanel(std::move(imageEditor), "Image Editor");
auto webClient = WebClientView::Create();
webClient->setName("webClient");
tabbedPanel->addPanel(std::move(webClient), "Web Client");
auto canvas = CanvasView::Create();
canvas->setName("CanvasView");
tabbedPanel->addPanel(std::move(canvas), "Canvas");
auto mesh = MeshViewerView::Create();
mesh->setName("MeshViewer");
tabbedPanel->addPanel(std::move(mesh), "Mesh Viewer");
auto topBar = TopBar::Create();
//auto statusBar = StatusBar::Create();
auto horizontal_spacer = HorizontalSpacer::Create();
horizontal_spacer->addWidgetWithScale(std::move(topBar), 1);
horizontal_spacer->addWidgetWithScale(std::move(tabbedPanel), 20);
//horizontal_spacer->addWidgetWithScale(std::move(statusBar), 1);
mainWindow->setWidget(std::move(horizontal_spacer));
}

12
apps/notes_tk/NotesTk.h Normal file
View file

@ -0,0 +1,12 @@
#pragma once
#include "GuiApplication.h"
class NotesTk : public GuiApplication
{
public:
NotesTk(std::unique_ptr<CommandLineArgs> args);
protected:
void initializeViews() override;
};

View file

@ -0,0 +1,19 @@
#include "AudioEditorView.h"
#include "Label.h"
#include "TextNode.h"
#include "Theme.h"
AudioEditorView::AudioEditorView()
{
auto label = Label::Create();
label->setLabel("audio Editor");
label->setBackgroundColor(Theme::getBackgroundPrimary());
label->setMargin(1);
addWidget(std::move(label));
}
std::unique_ptr<AudioEditorView> AudioEditorView::Create()
{
return std::make_unique<AudioEditorView>();
}

View file

@ -0,0 +1,14 @@
#pragma once
#include "Widget.h"
class AudioEditorView : public Widget
{
public:
AudioEditorView();
static std::unique_ptr<AudioEditorView> Create();
};
using AudioEditorViewUPtr = std::unique_ptr<AudioEditorView>;

View file

@ -0,0 +1,6 @@
#include "CanvasController.h"
std::unique_ptr<CanvasController> CanvasController::Create()
{
return std::make_unique<CanvasController>();
}

View file

@ -0,0 +1,9 @@
#pragma once
#include <memory>
class CanvasController
{
public:
static std::unique_ptr<CanvasController> Create();
};

View file

@ -0,0 +1,75 @@
#include "CanvasView.h"
#include "HorizontalSpacer.h"
#include "VerticalSpacer.h"
#include "CanvasController.h"
#include "Theme.h"
#include "TextNode.h"
#include "Label.h"
#include "Button.h"
#include <iostream>
CanvasView::CanvasView()
: mController(CanvasController::Create())
{
initialize();
}
CanvasView::~CanvasView()
{
}
std::unique_ptr<CanvasView> CanvasView::Create()
{
return std::make_unique<CanvasView>();
}
void CanvasView::initialize()
{
auto label = Label::Create();
label->setLabel("Canvas");
label->setBackgroundColor(Theme::getBannerBackground());
label->setMargin(1);
auto hSpacer = HorizontalSpacer::Create();
hSpacer->addWidgetWithScale(std::move(label), 1);
//hSpacer->addWidgetWithScale(std::move(textBox), 14);
auto cache_button_spacer = initializeCacheButtons();
hSpacer->addWidgetWithScale(std::move(cache_button_spacer), 1);
addWidget(std::move(hSpacer));
}
std::unique_ptr<Widget> CanvasView::initializeCacheButtons()
{
auto saveButton = Button::Create();
saveButton->setLabel("Save");
saveButton->setBackgroundColor(Theme::getButtonPrimaryBackground());
saveButton->setMargin(2);
auto clearButton = Button::Create();
clearButton->setLabel("Clear");
clearButton->setBackgroundColor(Theme::getButtonPrimaryBackground());
clearButton->setMargin(2);
auto loadButton = Button::Create();
loadButton->setLabel("Load");
loadButton->setBackgroundColor(Theme::getButtonPrimaryBackground());
loadButton->setMargin(2);
auto buttonSpacer = VerticalSpacer::Create();
buttonSpacer->AddWidgetWithScale(std::move(saveButton), 1);
buttonSpacer->AddWidgetWithScale(std::move(clearButton), 1);
buttonSpacer->AddWidgetWithScale(std::move(loadButton), 1);
return buttonSpacer;
}

View file

@ -0,0 +1,26 @@
#pragma once
#include "Widget.h"
class CanvasController;
class CanvasView : public Widget
{
public:
CanvasView();
~CanvasView();
static std::unique_ptr<CanvasView> Create();
private:
void initialize();
std::unique_ptr<Widget> initializeCacheButtons();
//std::unique_ptr<Widget> initializeCacheButtons();
std::unique_ptr<CanvasController> mController;
};
using CanvasViewPtr = std::unique_ptr<CanvasView>;

View file

@ -0,0 +1,30 @@
#include "ImageEditorView.h"
#include "Label.h"
#include "Color.h"
#include "TextNode.h"
#include "Theme.h"
#include "ImageViewWidget.h"
#include "HorizontalSpacer.h"
ImageEditorView::ImageEditorView()
{
auto label = Label::Create();
label->setLabel("Image Editor");
label->setBackgroundColor(Theme::getBackgroundPrimary());
label->setMargin(1);
auto image_widget = std::make_unique<ImageViewWidget>();
auto hSpacer = HorizontalSpacer::Create();
hSpacer->addWidgetWithScale(std::move(label), 1);
hSpacer->addWidgetWithScale(std::move(image_widget), 14);
addWidget(std::move(hSpacer));
}
std::unique_ptr<ImageEditorView> ImageEditorView::Create()
{
return std::make_unique<ImageEditorView>();
}

View file

@ -0,0 +1,14 @@
#pragma once
#include "Widget.h"
class ImageEditorView : public Widget
{
public:
ImageEditorView();
static std::unique_ptr<ImageEditorView> Create();
};
using ImageEditorViewUPtr = std::unique_ptr<ImageEditorView>;

View file

@ -0,0 +1,46 @@
#include "ImageViewWidget.h"
#include "GridNode.h"
#include "TransformNode.h"
#include <iostream>
ImageViewWidget::ImageViewWidget()
{
mName = "ImageViewWidget";
}
void ImageViewWidget::doPaint(const PaintEvent* event)
{
if (!mVisible)
{
return;
}
if (!mGridNode)
{
mGridNode = std::make_unique<GridNode>(mLocation);
mGridNode->setName(mName + "_GridNode");
mGridNode->setNumX(mNumX);
mGridNode->setNumY(mNumY);
mGridNode->setWidth(mSize.mWidth);
mGridNode->setHeight(mSize.mHeight);
mGridNode->setStrokeColor(mBorderColor);
mRootNode->addChild(mGridNode.get());
}
if (mTransformDirty)
{
mGridNode->setLocation(mLocation);
mGridNode->setWidth(mSize.mWidth);
mGridNode->setHeight(mSize.mHeight);
}
if (mMaterialDirty)
{
mGridNode->setFillColor(mBorderColor);
}
}

View file

@ -0,0 +1,18 @@
#pragma once
#include "Widget.h"
#include "GridNode.h"
class ImageViewWidget : public Widget
{
public:
ImageViewWidget();
private:
void doPaint(const PaintEvent* event) override;
unsigned mNumX{5};
unsigned mNumY{5};
std::unique_ptr<GridNode> mGridNode;
};

View file

@ -0,0 +1,67 @@
#ifndef UNICODE
#define UNICODE
#endif
#include "MainApplication.h"
#include "GuiApplication.h"
#include "CommandLineArgs.h"
#include "Win32WindowInterface.h"
#include "FileLogger.h"
#include "StringUtils.h"
#include "windows.h"
#include <iostream>
#include <vector>
#include <string>
void initializeCommandLineArgs(CommandLineArgs* args)
{
int nArgs{ 0 };
auto szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
if (szArglist == nullptr)
{
return;
}
std::vector<std::string> windowsArgs(nArgs);
for (int idx = 0; idx < nArgs; idx++)
{
windowsArgs[idx] = StringUtils::convert(szArglist[idx]);
}
LocalFree(szArglist);
args->process(windowsArgs);
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
std::ofstream out("out.txt");
std::cout.rdbuf(out.rdbuf());
auto args = CommandLineArgs::Create();
initializeCommandLineArgs(args.get());
args->recordLaunchPath();
// Start the main app
auto main_app = MainApplication::Create();
auto applicationContext = std::make_unique<Win32ApplicationContext>();
applicationContext->hInstance = reinterpret_cast<void*>(hInstance);
applicationContext->nCmdShow = nCmdShow;
main_app->initialize(std::move(args), std::move(applicationContext));
MLOG_INFO("Creating GUI Application");
// Start the gui application
auto gui_app = GuiApplication();
//gui_app.setMainApplication(main_app);
MLOG_INFO("Running GUI Application");
gui_app.run();
main_app->shutDown();
return 0;
}

19
apps/notes_tk/main.cpp Normal file
View file

@ -0,0 +1,19 @@
#include <memory>
#include "NotesTk.h"
#include "MainApplication.h"
#include "CommandLineArgs.h"
int main(int argc, char *argv[])
{
auto args = CommandLineArgs::Create();
args->process(argc, argv);
args->recordLaunchPath();
// Start the gui app
auto app = NotesTk(std::move(args));
//app.setUiInterfaceBackend(UiInterfaceFactory::Backend::X11_RASTER);
app.run();
return 0;
}

View file

@ -0,0 +1,65 @@
#include "MeshViewerView.h"
#include "MeshNode.h"
#include "TransformNode.h"
#include "AbstractMesh.h"
#include "MeshPrimitives.h"
#include <iostream>
std::unique_ptr<MeshViewerView> MeshViewerView::Create()
{
return std::make_unique<MeshViewerView>();
}
MeshViewerView::~MeshViewerView()
{
}
MeshViewerView::MeshViewerView()
{
mName = "MeshViewerView";
mBackgroundColor = {204, 204, 255};
}
void MeshViewerView::doPaint(const PaintEvent* event)
{
if (!mVisible)
{
return;
}
if (!mMeshNode)
{
mMeshNode = std::make_unique<MeshNode>(mLocation);
mMeshNode->setName(mName + "_MeshNode");
mMeshNode->setWidth(mSize.mWidth);
mMeshNode->setHeight(mSize.mHeight);
mMeshNode->setFillColor(mBackgroundColor);
mRootNode->addChild(mMeshNode.get());
}
if (mTransformDirty)
{
mMeshNode->setLocation(mLocation);
mMeshNode->setWidth(mSize.mWidth);
mMeshNode->setHeight(mSize.mHeight);
}
if (mMaterialDirty)
{
mMeshNode->setFillColor(mBackgroundColor);
}
if (!mMesh)
{
auto mesh = MeshPrimitives::buildRectangleAsTriMesh();
mMesh = std::move(mesh);
mMeshNode->setMesh(mMesh.get());
}
}

View file

@ -0,0 +1,19 @@
#pragma once
#include "Widget.h"
class MeshNode;
class AbstractMesh;
class MeshViewerView : public Widget
{
public:
MeshViewerView();
~MeshViewerView();
static std::unique_ptr<MeshViewerView> Create();
void doPaint(const PaintEvent* event) override;
private:
std::unique_ptr<AbstractMesh> mMesh;
std::unique_ptr<MeshNode> mMeshNode;
};

View file

@ -0,0 +1,27 @@
#include "PlainTextDocument.h"
PlainTextDocument::PlainTextDocument()
: mContent()
{
}
std::unique_ptr<PlainTextDocument> PlainTextDocument::Create()
{
return std::make_unique<PlainTextDocument>();
}
std::string PlainTextDocument::GetContent() const
{
return mContent;
}
void PlainTextDocument::SetContent(const std::string& content)
{
mContent = content;
}
void PlainTextDocument::Clear()
{
mContent = "";
}

View file

@ -0,0 +1,24 @@
#pragma once
#include <string>
#include <memory>
class PlainTextDocument
{
std::string mContent;
public:
PlainTextDocument();
static std::unique_ptr<PlainTextDocument> Create();
std::string GetContent() const;
void SetContent(const std::string& content);
void Clear();
};
using PlainTextDocumentUPtr = std::unique_ptr<PlainTextDocument>;

View file

@ -0,0 +1,58 @@
#include "TextEditorController.h"
#include "File.h"
TextEditorController::TextEditorController()
: mModel(TextEditorModel::Create()),
mSavePath(),
mLoadPath()
{
}
std::unique_ptr<TextEditorController> TextEditorController::Create()
{
return std::make_unique<TextEditorController>();
}
void TextEditorController::SetContent(const std::string& content)
{
mModel->GetDocument()->SetContent(content);
}
std::string TextEditorController::GetContent() const
{
return mModel->GetDocument()->GetContent();
}
void TextEditorController::OnSave()
{
if(mSavePath.empty()) return;
File outfile(mSavePath);
outfile.open(File::AccessMode::Write);
outfile.writeText(mModel->GetDocument()->GetContent());
}
void TextEditorController::OnLoad()
{
if(mLoadPath.empty()) return;
File infile(mLoadPath);
infile.open(File::AccessMode::Read);
mModel->GetDocument()->SetContent(infile.readText());
}
void TextEditorController::SetSavePath(const std::filesystem::path& path)
{
mSavePath = path;
}
void TextEditorController::SetLoadPath(const std::filesystem::path& path)
{
mLoadPath = path;
}
void TextEditorController::OnClear()
{
mModel->GetDocument()->Clear();
}

View file

@ -0,0 +1,34 @@
#pragma once
#include <memory>
#include <filesystem>
#include "TextEditorModel.h"
class TextEditorController
{
public:
TextEditorController();
static std::unique_ptr<TextEditorController> Create();
void OnSave();
void OnClear();
void OnLoad();
std::string GetContent() const;
void SetContent(const std::string& content);
void SetSavePath(const std::filesystem::path& path);
void SetLoadPath(const std::filesystem::path& path);
private:
TextEditorModelUPtr mModel;
std::filesystem::path mSavePath;
std::filesystem::path mLoadPath;
};
using TextEditorControllerUPtr = std::unique_ptr<TextEditorController>;

View file

@ -0,0 +1,17 @@
#include "TextEditorModel.h"
TextEditorModel::TextEditorModel()
: mDocument(PlainTextDocument::Create())
{
}
std::unique_ptr<TextEditorModel> TextEditorModel::Create()
{
return std::make_unique<TextEditorModel>();
}
PlainTextDocument* TextEditorModel::GetDocument() const
{
return mDocument.get();
}

View file

@ -0,0 +1,19 @@
#pragma once
#include "PlainTextDocument.h"
#include <memory>
class TextEditorModel
{
PlainTextDocumentUPtr mDocument;
public:
TextEditorModel();
static std::unique_ptr<TextEditorModel> Create();
PlainTextDocument* GetDocument() const;
};
using TextEditorModelUPtr = std::unique_ptr<TextEditorModel>;

View file

@ -0,0 +1,90 @@
#include "TextEditorView.h"
#include "HorizontalSpacer.h"
#include "VerticalSpacer.h"
#include "Theme.h"
#include "TextNode.h"
#include <iostream>
TextEditorView::TextEditorView()
: mTextBox(),
mController(TextEditorController::Create())
{
}
TextEditorController* TextEditorView::getController()
{
return mController.get();
}
void TextEditorView::initialize()
{
auto label = Label::Create();
label->setLabel("Text Editor");
label->setBackgroundColor(Theme::getBannerBackground());
label->setMargin(1);
auto textBox = TextBox::Create();
textBox->setName("Text Box");
mTextBox = textBox.get();
auto saveButton = Button::Create();
saveButton->setLabel("Save");
saveButton->setBackgroundColor(Theme::getButtonPrimaryBackground());
saveButton->setMargin(2);
auto onSave = [this](Widget* self){
if(this && mController && mTextBox)
{
mController->SetContent(mTextBox->getContent());
mController->OnSave();
};
};
saveButton->setOnClickFunction(onSave);
auto clearButton = Button::Create();
clearButton->setLabel("Clear");
clearButton->setBackgroundColor(Theme::getButtonPrimaryBackground());
clearButton->setMargin(2);
auto onClear = [this](Widget* self){
if(this && mController && mTextBox)
{
mController->OnClear();
mTextBox->setContent("");
};
};
clearButton->setOnClickFunction(onClear);
auto loadButton = Button::Create();
loadButton->setLabel("Load");
loadButton->setBackgroundColor(Theme::getButtonPrimaryBackground());
loadButton->setMargin(2);
auto onLoad = [this](Widget* self){
if(this && mController && mTextBox)
{
mController->OnLoad();
mTextBox->setContent(mController->GetContent());
};
};
loadButton->setOnClickFunction(onLoad);
auto buttonSpacer = VerticalSpacer::Create();
buttonSpacer->AddWidgetWithScale(std::move(saveButton), 1);
buttonSpacer->AddWidgetWithScale(std::move(clearButton), 1);
buttonSpacer->AddWidgetWithScale(std::move(loadButton), 1);
auto hSpacer = HorizontalSpacer::Create();
hSpacer->addWidgetWithScale(std::move(label), 1);
hSpacer->addWidgetWithScale(std::move(textBox), 14);
hSpacer->addWidgetWithScale(std::move(buttonSpacer), 1);
addWidget(std::move(hSpacer));
}
std::unique_ptr<TextEditorView> TextEditorView::Create()
{
return std::make_unique<TextEditorView>();
}

View file

@ -0,0 +1,27 @@
#pragma once
#include "Widget.h"
#include "Button.h"
#include "Label.h"
#include "TextBox.h"
#include "TextEditorController.h"
#include <functional>
class TextEditorView : public Widget
{
public:
TextEditorView();
static std::unique_ptr<TextEditorView> Create();
TextEditorController* getController();
void initialize();
private:
TextBox* mTextBox;
TextEditorControllerUPtr mController;
};
using TextEditorViewUPtr = std::unique_ptr<TextEditorView>;

View file

@ -0,0 +1,21 @@
#include "WebClientView.h"
#include "Label.h"
#include "TextNode.h"
#include "Theme.h"
WebClientView::WebClientView()
{
auto label = Label::Create();
label->setLabel("Web Client");
label->setBackgroundColor(Theme::getBackgroundPrimary());
label->setMargin(1);
addWidget(std::move(label));
}
std::unique_ptr<WebClientView> WebClientView::Create()
{
return std::make_unique<WebClientView>();
}

View file

@ -0,0 +1,14 @@
#pragma once
#include "Widget.h"
class WebClientView : public Widget
{
public:
WebClientView();
static std::unique_ptr<WebClientView> Create();
};
using WebClientViewUPtr = std::unique_ptr<WebClientView>;