├── src
├── examples
│ ├── assets
│ │ ├── .gitignore
│ │ ├── add.svg
│ │ ├── test.md
│ │ ├── check_box_blank.svg
│ │ ├── delete.svg
│ │ ├── check_box.svg
│ │ └── include.h
│ ├── basic
│ │ └── main.cpp
│ ├── crud
│ │ └── main.cpp
│ ├── counter
│ │ ├── main.cpp
│ │ └── Counter.h
│ ├── text
│ │ ├── main.cpp
│ │ └── TextDemo.h
│ ├── button
│ │ ├── main.cpp
│ │ └── ButtonDemo.h
│ ├── flex
│ │ ├── main.cpp
│ │ └── FlexDemo.h
│ ├── tempconv
│ │ ├── main.cpp
│ │ └── TempConv.h
│ ├── elementor.h
│ ├── todo
│ │ └── main.cpp
│ └── main.cpp
├── library
│ ├── platforms
│ │ └── gl
│ │ │ ├── elementor.h
│ │ │ ├── include.h
│ │ │ ├── GLClipboard.h
│ │ │ ├── GLDisplay.h
│ │ │ ├── utility.h
│ │ │ ├── GLPerfomance.h
│ │ │ ├── GLPlatformContext.h
│ │ │ ├── GLFontManager.h
│ │ │ ├── GLCursor.h
│ │ │ ├── GLEventLoop.h
│ │ │ ├── GLPlatform.h
│ │ │ ├── utility.cpp
│ │ │ └── GLPlatform.cpp
│ ├── include.h
│ ├── WithChild.h
│ ├── elements
│ │ ├── Flexible.cpp
│ │ ├── include.h
│ │ ├── Background.cpp
│ │ ├── FitCover.cpp
│ │ ├── Stack.cpp
│ │ ├── Image.cpp
│ │ ├── Focusable.cpp
│ │ ├── Ratio.cpp
│ │ ├── Hoverable.cpp
│ │ ├── Height.cpp
│ │ ├── FitContain.cpp
│ │ ├── Width.cpp
│ │ ├── Ratio.h
│ │ ├── FitContain.h
│ │ ├── Rounded.cpp
│ │ ├── Stack.h
│ │ ├── FitCover.h
│ │ ├── Align.cpp
│ │ ├── Width.h
│ │ ├── Flexible.h
│ │ ├── Height.h
│ │ ├── Row.h
│ │ ├── Column.h
│ │ ├── Clickable.cpp
│ │ ├── Column.cpp
│ │ ├── Row.cpp
│ │ ├── SVG.cpp
│ │ ├── Padding.cpp
│ │ ├── SVG.h
│ │ ├── ParagraphPlaceholder.cpp
│ │ ├── Hoverable.h
│ │ ├── Background.h
│ │ ├── Clickable.h
│ │ ├── Image.h
│ │ ├── Rounded.h
│ │ ├── Padding.h
│ │ ├── Focusable.h
│ │ ├── Draggable.cpp
│ │ ├── ParagraphPlaceholder.h
│ │ ├── Border.cpp
│ │ ├── Scrollable.cpp
│ │ ├── Flex.h
│ │ ├── Draggable.h
│ │ ├── Border.h
│ │ ├── Paragraph.h
│ │ └── Scrollable.h
│ ├── debug.h
│ ├── utility.h
│ ├── WithChildren.h
│ ├── ApplicationHoverState.h
│ ├── Component.h
│ ├── ApplicationFocusState.h
│ ├── Element.h
│ ├── ApplicationHoverState.cpp
│ ├── Render.cpp
│ ├── utility.cpp
│ ├── ApplicationContext.h
│ ├── Render.h
│ └── ApplicationTree.h
└── components
│ ├── elementor.h
│ ├── include.h
│ ├── utility.h
│ ├── utility.cpp
│ ├── FPSLabel.h
│ ├── Slot.h
│ ├── Outline.cpp
│ ├── Outline.h
│ ├── Eventable.h
│ ├── TextButton.h
│ ├── Cursorable.h
│ ├── Scrollbar.h
│ ├── IconButton.h
│ ├── ClickableOutside.h
│ └── Button.h
├── tests
├── .gitignore
├── screenshots
│ ├── basic.png
│ ├── crud.png
│ ├── flex.png
│ ├── text.png
│ ├── todo.png
│ ├── button.png
│ ├── counter.png
│ └── tempconv.png
├── compare_screenshots.py
└── make_screenshots.cpp
├── .gitignore
├── clear.py
├── test.py
├── LICENSE
├── environment.yml
├── xmake.lua
├── third_party
└── skia-build.lua
└── README.md
/src/examples/assets/.gitignore:
--------------------------------------------------------------------------------
1 | todo.md
--------------------------------------------------------------------------------
/tests/.gitignore:
--------------------------------------------------------------------------------
1 | screenshots_diff/
2 | screenshots_new/
3 | __pycache__/
4 |
--------------------------------------------------------------------------------
/tests/screenshots/basic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/noartem/elementor/HEAD/tests/screenshots/basic.png
--------------------------------------------------------------------------------
/tests/screenshots/crud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/noartem/elementor/HEAD/tests/screenshots/crud.png
--------------------------------------------------------------------------------
/tests/screenshots/flex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/noartem/elementor/HEAD/tests/screenshots/flex.png
--------------------------------------------------------------------------------
/tests/screenshots/text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/noartem/elementor/HEAD/tests/screenshots/text.png
--------------------------------------------------------------------------------
/tests/screenshots/todo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/noartem/elementor/HEAD/tests/screenshots/todo.png
--------------------------------------------------------------------------------
/tests/screenshots/button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/noartem/elementor/HEAD/tests/screenshots/button.png
--------------------------------------------------------------------------------
/tests/screenshots/counter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/noartem/elementor/HEAD/tests/screenshots/counter.png
--------------------------------------------------------------------------------
/tests/screenshots/tempconv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/noartem/elementor/HEAD/tests/screenshots/tempconv.png
--------------------------------------------------------------------------------
/src/examples/assets/add.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/examples/assets/test.md:
--------------------------------------------------------------------------------
1 | - [x] Забрать посылку на почте
2 | - [ ] Сходить подстричься
3 | - [x] Найти тот самый фильм, про который мне говорили
4 | - [x] Надо что-нибудь приготовить...
5 | - [x] daadda
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xmake cache
2 | .xmake/
3 | build/
4 |
5 | # MacOS Cache
6 | .DS_Store
7 |
8 | Makefile
9 | src/examples/assets/todo.md
10 |
11 | CMakeLists.txt
12 | cmake-build-debug/
13 | .vscode/
14 | .idea/
--------------------------------------------------------------------------------
/clear.py:
--------------------------------------------------------------------------------
1 | import os
2 | import shutil
3 |
4 | shutil.rmtree("build")
5 | shutil.rmtree(".xmake")
6 | shutil.rmtree("tests/screenshots_diff")
7 | shutil.rmtree("tests/screenshots_new")
8 | os.remove("CMakeLists.txt")
9 |
--------------------------------------------------------------------------------
/src/library/platforms/gl/elementor.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 12.01.2024.
3 | //
4 |
5 | #ifndef ELEMENTOR_ELEMENTOR_H
6 | #define ELEMENTOR_ELEMENTOR_H
7 |
8 | #include "../../include.h"
9 |
10 | #endif //ELEMENTOR_ELEMENTOR_H
11 |
--------------------------------------------------------------------------------
/src/examples/assets/check_box_blank.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/examples/assets/delete.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/examples/assets/check_box.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/elementor.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 04.02.2023.
3 | //
4 |
5 | #ifndef ELEMENTOR_COMPONENTS_ELEMENTOR_H
6 | #define ELEMENTOR_COMPONENTS_ELEMENTOR_H
7 |
8 | #include "../library/include.h"
9 | #include "../library/elements/include.h"
10 |
11 | using namespace elementor;
12 | using namespace elementor::elements;
13 |
14 | #endif //ELEMENTOR_COMPONENTS_ELEMENTOR_H
15 |
--------------------------------------------------------------------------------
/src/library/platforms/gl/include.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 15.08.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_GL_INCLUDE_H
6 | #define ELEMENTOR_GL_INCLUDE_H
7 |
8 | #include "GLClipboard.h"
9 | #include "GLCursor.h"
10 | #include "GLFontManager.h"
11 | #include "GLDisplay.h"
12 | #include "GLPerfomance.h"
13 | #include "GLPlatform.h"
14 | #include "GLWindow.h"
15 | #include "utility.h"
16 |
17 | #endif //ELEMENTOR_GL_INCLUDE_H
18 |
--------------------------------------------------------------------------------
/src/examples/basic/main.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 12.01.2024.
3 | //
4 |
5 | #include "./Basic.h"
6 |
7 | int main() {
8 | auto platform = std::make_shared();
9 |
10 | auto window = std::make_shared(platform);
11 | window->setTitle("Elementor: Basic");
12 | window->setSize({ 420, 320 });
13 | window->setMinSize({ 240, 180 });
14 | platform->addWindow(window);
15 |
16 | window->setRoot(
17 | Basic::New(window)
18 | );
19 |
20 | platform->run();
21 | }
--------------------------------------------------------------------------------
/src/examples/crud/main.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 12.01.2024.
3 | //
4 |
5 | #include "./Crud.h"
6 |
7 | int main() {
8 | auto platform = std::make_shared();
9 |
10 | auto window = std::make_shared(platform);
11 | window->setTitle("Elementor: Counter");
12 | window->setSize({ 512, 256 });
13 | window->setMinSize({ 512, 256 });
14 | platform->addWindow(window);
15 |
16 | window->setRoot(
17 | Crud::New(window)
18 | );
19 |
20 | platform->run();
21 | }
--------------------------------------------------------------------------------
/src/examples/counter/main.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 12.01.2024.
3 | //
4 |
5 | #include "./Counter.h"
6 |
7 | int main() {
8 | auto platform = std::make_shared();
9 |
10 | auto window = std::make_shared(platform);
11 | window->setTitle("Elementor: Counter");
12 | window->setSize({ 224, 64 });
13 | window->setMinSize({ 160, 64 });
14 | platform->addWindow(window);
15 |
16 | window->setRoot(
17 | Counter::New(window)
18 | );
19 |
20 | platform->run();
21 | }
--------------------------------------------------------------------------------
/src/examples/text/main.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 08.05.2024.
3 | //
4 |
5 | #include "./TextDemo.h"
6 |
7 | int main() {
8 | auto platform = std::make_shared();
9 |
10 | auto window = std::make_shared(platform);
11 | window->setTitle("Elementor: Text");
12 | window->setSize({ 420, 320 });
13 | window->setMinSize({ 240, 180 });
14 | platform->addWindow(window);
15 |
16 | window->setRoot(
17 | TextDemo::New(window)
18 | );
19 |
20 | platform->run();
21 | }
--------------------------------------------------------------------------------
/src/examples/button/main.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 08.05.2024.
3 | //
4 |
5 | #include "./ButtonDemo.h"
6 |
7 | int main() {
8 | auto platform = std::make_shared();
9 |
10 | auto window = std::make_shared(platform);
11 | window->setTitle("Elementor: Button");
12 | window->setSize({ 420, 320 });
13 | window->setMinSize({ 240, 180 });
14 | platform->addWindow(window);
15 |
16 | window->setRoot(
17 | ButtonDemo::New(window)
18 | );
19 |
20 | platform->run();
21 | }
--------------------------------------------------------------------------------
/src/examples/flex/main.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 08.06.2024.
3 | //
4 |
5 | #include "./FlexDemo.h"
6 |
7 | int main() {
8 | auto platform = std::make_shared();
9 |
10 | auto window = std::make_shared(platform);
11 | window->setTitle("Elementor: Flexbox Layout");
12 | window->setSize({ 420, 320 });
13 | window->setMinSize({ 420, 320 });
14 | platform->addWindow(window);
15 |
16 | window->setRoot(
17 | FlexDemo::New(window)
18 | );
19 |
20 | platform->run();
21 | }
--------------------------------------------------------------------------------
/src/examples/tempconv/main.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 12.01.2024.
3 | //
4 |
5 | #include "./TempConv.h"
6 |
7 | int main() {
8 | auto platform = std::make_shared();
9 |
10 | auto window = std::make_shared(platform);
11 | window->setTitle("Elementor: Temperature Converter");
12 | window->setSize({ 384, 64 });
13 | window->setMinSize({ 384, 64 });
14 | platform->addWindow(window);
15 |
16 | window->setRoot(
17 | TempConv::New(window)
18 | );
19 |
20 | platform->run();
21 | }
--------------------------------------------------------------------------------
/src/components/include.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 04.02.2023.
3 | //
4 |
5 | #ifndef ELEMENTOR_COMPONENTS_INCLUDE_H
6 | #define ELEMENTOR_COMPONENTS_INCLUDE_H
7 |
8 | #include "Button.h"
9 | #include "ClickableOutside.h"
10 | #include "Cursorable.h"
11 | #include "Eventable.h"
12 | #include "FPSLabel.h"
13 | #include "IconButton.h"
14 | #include "Outline.h"
15 | #include "Scrollbar.h"
16 | #include "Slot.h"
17 | #include "TextButton.h"
18 | #include "TextInput.h"
19 |
20 | #endif //ELEMENTOR_COMPONENTS_INCLUDE_H
21 |
--------------------------------------------------------------------------------
/src/examples/elementor.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 15.02.2024.
3 | //
4 |
5 | #ifndef EXAMPLES_ELEMENTOR_H
6 | #define EXAMPLES_ELEMENTOR_H
7 |
8 | #include "../library/include.h"
9 | #include "../library/platforms/gl/include.h"
10 | #include "../library/elements/include.h"
11 | #include "../components/include.h"
12 |
13 | using namespace elementor;
14 | using namespace elementor::platforms::gl;
15 | using namespace elementor::elements;
16 | using namespace elementor::components;
17 |
18 | #endif //EXAMPLES_ELEMENTOR_H
19 |
--------------------------------------------------------------------------------
/src/components/utility.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 04.02.2023.
3 | //
4 |
5 | #ifndef ELEMENTOR_COMPONENTS_UTILITY_H
6 | #define ELEMENTOR_COMPONENTS_UTILITY_H
7 |
8 | #include
9 | #include
10 |
11 | namespace elementor::components {
12 | void openURL(std::string url);
13 |
14 | tm now_tm();
15 |
16 | std::string leftPadAndFit(const std::string& value, unsigned int size, const char paddingChar);
17 |
18 | int daysInMonth(int month, int year);
19 | }
20 |
21 | #endif //ELEMENTOR_COMPONENTS_UTILITY_H
22 |
--------------------------------------------------------------------------------
/src/examples/assets/include.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by admin on 17.02.2024.
3 | //
4 |
5 | #ifndef ASSETS_INCLUDE_H
6 | #define ASSETS_INCLUDE_H
7 |
8 | #include
9 | #include
10 |
11 | std::string asset(const std::string_view& name) {
12 | return std::filesystem::current_path()
13 | .append("..")
14 | .append("..")
15 | .append("..")
16 | .append("..")
17 | .append("src")
18 | .append("examples")
19 | .append("assets")
20 | .append(name)
21 | .string();
22 | }
23 |
24 | #endif //ASSETS_INCLUDE_H
25 |
--------------------------------------------------------------------------------
/src/examples/todo/main.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 15.02.2024.
3 | //
4 |
5 | #include "./Todo.h"
6 |
7 | int main() {
8 | auto platform = std::make_shared();
9 |
10 | auto window = std::make_shared(platform);
11 | window->setTitle("Elementor: TODO");
12 | window->setSize({ 320, 420 });
13 | window->setMinSize({ 240, 320 });
14 | platform->addWindow(window);
15 |
16 | window->setRoot(
17 | Todo::New(window, {
18 | .filename = asset("todo.md"),
19 | })
20 | );
21 |
22 | platform->run();
23 | }
--------------------------------------------------------------------------------
/src/library/include.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 29.05.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_INCLUDE_H
6 | #define ELEMENTOR_INCLUDE_H
7 |
8 | #include "ApplicationTree.h"
9 | #include "ApplicationContext.h"
10 | #include "Component.h"
11 | #include "Element.h"
12 | #include "Event.h"
13 | #include "ApplicationFocusState.h"
14 | #include "ApplicationHoverState.h"
15 | #include "Render.h"
16 | #include "utility.h"
17 | #include "WithChild.h"
18 | #include "WithChildren.h"
19 | #include "debug.h"
20 |
21 | #endif //ELEMENTOR_INCLUDE_H
22 |
--------------------------------------------------------------------------------
/test.py:
--------------------------------------------------------------------------------
1 | import os
2 | from os import path
3 | import subprocess
4 |
5 | ctx = os.getcwd()
6 | os.chdir(path.dirname(__file__))
7 |
8 |
9 | def sh(args):
10 | if isinstance(args, str):
11 | args = args.split(" ")
12 |
13 | process = subprocess.Popen(args)
14 | process.wait()
15 |
16 |
17 | if not path.isdir("./tests/screenshots_new"):
18 | os.mkdir("./tests/screenshots_new")
19 |
20 | sh("xmake")
21 | sh("xmake run make-screenshots")
22 |
23 | os.chdir("tests")
24 | sh("python compare_screenshots.py")
25 | os.chdir("..")
26 |
27 | os.chdir(ctx)
28 |
--------------------------------------------------------------------------------
/src/library/platforms/gl/GLClipboard.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 15.08.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_GL_CLIPBOARD_H
6 | #define ELEMENTOR_GL_CLIPBOARD_H
7 |
8 | #include "elementor.h"
9 |
10 | #include "GLFW/glfw3.h"
11 |
12 | namespace elementor::platforms::gl {
13 | class GLClipboard : public Clipboard {
14 | public:
15 | void set(const std::string_view& value) override {
16 | glfwSetClipboardString(nullptr, value.data());
17 | }
18 |
19 | const std::string_view& get() override {
20 | return glfwGetClipboardString(nullptr);
21 | }
22 | };
23 | };
24 |
25 |
26 | #endif //ELEMENTOR_GL_CLIPBOARD_H
27 |
--------------------------------------------------------------------------------
/src/library/WithChild.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 12.01.2024.
3 | //
4 |
5 | #ifndef ELEMENTOR_WITH_CHILD_H
6 | #define ELEMENTOR_WITH_CHILD_H
7 |
8 | #include
9 |
10 | #include "Element.h"
11 |
12 | namespace elementor {
13 | class WithChild {
14 | public:
15 | [[nodiscard]] auto getChild() const {
16 | return child;
17 | }
18 |
19 | [[nodiscard]] bool hasChild() const {
20 | return child != nullptr;
21 | }
22 |
23 | [[nodiscard]] bool doesNotHaveChild() const {
24 | return child == nullptr;
25 | }
26 |
27 | protected:
28 | std::shared_ptr child;
29 | };
30 | }
31 |
32 | #endif //ELEMENTOR_WITH_CHILD_H
33 |
--------------------------------------------------------------------------------
/src/library/elements/Flexible.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 13.04.2022.
3 | //
4 |
5 | #include "Flexible.h"
6 |
7 | namespace elementor::elements {
8 | Size Flexible::getSize(const Boundaries& boundaries) {
9 | if (doesNotHaveChild()) {
10 | return boundaries.max;
11 | }
12 |
13 | return child->getSize(boundaries);
14 | }
15 |
16 | std::vector Flexible::getChildren(const ElementRect& rect) {
17 | if (doesNotHaveChild()) {
18 | return {};
19 | }
20 |
21 | Rect childRect = {
22 | .size = rect.size,
23 | .position = { 0, 0 }
24 | };
25 | ElementWithRect childElement(child, childRect);
26 | return { childElement };
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/library/debug.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 13.01.2024.
3 | //
4 |
5 | #ifndef ELEMENTOR_DEBUG_H
6 | #define ELEMENTOR_DEBUG_H
7 |
8 | #include
9 |
10 | #ifndef LOG
11 | #define LOG(x) std::cout << __TIME__ << " | " << __FILE__ << ":" << __LINE__ << " | " << x << std::endl
12 | #endif
13 |
14 | #ifndef PRINT
15 | #define PRINT(x) LOG(#x"=" << x)
16 | #endif
17 |
18 | #ifdef DEBUG
19 | #define D(x) x
20 | #else
21 | #define D(x)
22 | #endif
23 |
24 | #ifndef D_PRINT
25 | #define D_PRINT(x) D(PRINT(x))
26 | #endif
27 |
28 | #ifndef D_LOG
29 | #define D_LOG(x) D(LOG(x))
30 | #endif
31 |
32 | #ifndef D_IF_LOG
33 | #define D_IF_LOG(c, x) if (c) D(LOG(x))
34 | #endif
35 |
36 | #endif //ELEMENTOR_DEBUG_H
37 |
--------------------------------------------------------------------------------
/src/library/platforms/gl/GLDisplay.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 15.08.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_GL_DISPLAY_H
6 | #define ELEMENTOR_GL_DISPLAY_H
7 |
8 | #include "elementor.h"
9 |
10 | #include "GLFW/glfw3.h"
11 |
12 | #include "utility.h"
13 |
14 | namespace elementor::platforms::gl {
15 | class GLDisplay : public Display {
16 | public:
17 | GLDisplay(GLFWmonitor* glMonitor) {
18 | size = getMonitorSize(glMonitor);
19 | physicalSize = getMonitorPhysicalSize(glMonitor);
20 | }
21 |
22 | Size getSize() override {
23 | return size;
24 | }
25 |
26 | Size getPhysicalSize() override {
27 | return physicalSize;
28 | }
29 |
30 | private:
31 | Size size;
32 | Size physicalSize;
33 | };
34 | };
35 |
36 | #endif //ELEMENTOR_GL_DISPLAY_H
37 |
--------------------------------------------------------------------------------
/src/library/platforms/gl/utility.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 15.08.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_GL_UTILITY_H
6 | #define ELEMENTOR_GL_UTILITY_H
7 |
8 | #include "../../Render.h"
9 |
10 | #include "GLFW/glfw3.h"
11 |
12 | namespace elementor::platforms::gl {
13 | Size getWindowSize(GLFWwindow* window);
14 |
15 | Position getWindowPosition(GLFWwindow* window);
16 |
17 | Rect getWindowRect(GLFWwindow* window);
18 |
19 | Size getMonitorSize(GLFWmonitor* monitor);
20 |
21 | Size getMonitorPhysicalSize(GLFWmonitor* monitor);
22 |
23 | Position getMonitorPosition(GLFWmonitor* monitor);
24 |
25 | Rect getMonitorRect(GLFWmonitor* monitor);
26 |
27 | GLFWmonitor* getWindowMonitor(GLFWwindow* window);
28 | };
29 |
30 |
31 | #endif //ELEMENTOR_GL_UTILITY_H
32 |
--------------------------------------------------------------------------------
/src/library/platforms/gl/GLPerfomance.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 15.08.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_GL_PERFOMANCE_H
6 | #define ELEMENTOR_GL_PERFOMANCE_H
7 |
8 | #include "elementor.h"
9 |
10 | #include "GLFW/glfw3.h"
11 |
12 | namespace elementor::platforms::gl {
13 | class GLPerfomance : public Perfomance {
14 | public:
15 | double getFPS() override {
16 | return lastFPS;
17 | }
18 |
19 | void incrementFramesCount() {
20 | framesCount++;
21 |
22 | double now = glfwGetTime();
23 | if ((now - framesLastTime) >= 1) {
24 | lastFPS = framesCount;
25 | framesLastTime = now;
26 | framesCount = 0;
27 | }
28 | }
29 |
30 | private:
31 | double framesLastTime;
32 | double framesCount;
33 | double lastFPS;
34 | };
35 | };
36 |
37 | #endif //ELEMENTOR_GL_PERFOMANCE_H
38 |
--------------------------------------------------------------------------------
/src/library/elements/include.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 02.06.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_ELEMENTS_INCLUDE_H
6 | #define ELEMENTOR_ELEMENTS_INCLUDE_H
7 |
8 | #include "Align.h"
9 | #include "Background.h"
10 | #include "Border.h"
11 | #include "Clickable.h"
12 | #include "Column.h"
13 | #include "Draggable.h"
14 | #include "FitContain.h"
15 | #include "FitCover.h"
16 | #include "Flex.h"
17 | #include "Flexible.h"
18 | #include "Focusable.h"
19 | #include "Height.h"
20 | #include "Hoverable.h"
21 | #include "Image.h"
22 | #include "Padding.h"
23 | #include "Paragraph.h"
24 | #include "ParagraphPlaceholder.h"
25 | #include "Ratio.h"
26 | #include "Rounded.h"
27 | #include "Row.h"
28 | #include "Scrollable.h"
29 | #include "Stack.h"
30 | #include "SVG.h"
31 | #include "Text.h"
32 | #include "Width.h"
33 |
34 | #endif //ELEMENTOR_ELEMENTS_INCLUDE_H
35 |
--------------------------------------------------------------------------------
/src/library/platforms/gl/GLPlatformContext.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 05.02.2024.
3 | //
4 |
5 | #ifndef ELEMENTOR_GL_PLATFORM_CONTEXT_H
6 | #define ELEMENTOR_GL_PLATFORM_CONTEXT_H
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | #include
13 |
14 | #include "elementor.h"
15 |
16 | namespace elementor {
17 | class GLPlatformContext {
18 | public:
19 | [[nodiscard]] virtual std::string getLocale() const = 0;
20 |
21 | virtual void setLocale(std::string locale) = 0;
22 |
23 | [[nodiscard]] virtual std::shared_ptr getClipboard() const = 0;
24 |
25 | [[nodiscard]] virtual std::shared_ptr getPerfomance() const = 0;
26 |
27 | [[nodiscard]] virtual sk_sp getSkFontManager() const = 0;
28 |
29 | virtual void requestNextFrame(const std::function& callback) = 0;
30 |
31 | virtual void requestNextFrame() = 0;
32 | };
33 | }
34 |
35 | #endif //ELEMENTOR_GL_PLATFORM_CONTEXT_H
36 |
--------------------------------------------------------------------------------
/src/library/utility.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 07.02.2024.
3 | //
4 |
5 | #ifndef ELEMENTOR_UTILITY_H
6 | #define ELEMENTOR_UTILITY_H
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include
14 |
15 | namespace elementor {
16 | inline std::string toUTF8(const std::u32string_view& source) {
17 | std::wstring_convert, char32_t> convertor;
18 | return convertor.to_bytes(source.data());
19 | }
20 |
21 | inline std::u32string fromUTF8(const std::string_view& source) {
22 | std::wstring_convert, char32_t> convertor;
23 | return convertor.from_bytes(source.data());
24 | }
25 |
26 | SkColor makeSkColorFromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
27 |
28 | SkColor makeSkColorFromRGB(uint8_t r, uint8_t g, uint8_t b);
29 |
30 | SkColor makeSkColorFromHex(std::string hex);
31 | };
32 |
33 |
34 | #endif //ELEMENTOR_UTILITY_H
35 |
--------------------------------------------------------------------------------
/src/library/elements/Background.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 13.04.2022.
3 | //
4 |
5 | #include "Background.h"
6 |
7 | namespace elementor::elements {
8 | Size Background::getSize(const Boundaries& boundaries) {
9 | if (doesNotHaveChild()) {
10 | return boundaries.max;
11 | }
12 |
13 | return getChild()->getSize(boundaries);
14 | }
15 |
16 | void Background::paintBackground(SkCanvas* canvas, const ElementRect& rect) {
17 | SkPaint paint;
18 | paint.setColor(color);
19 |
20 | SkRect skRect = SkRect::MakeXYWH(0, 0, rect.size.width, rect.size.height);
21 | canvas->drawRect(skRect, paint);
22 | }
23 |
24 | std::vector Background::getChildren(const ElementRect& rect) {
25 | if (doesNotHaveChild()) {
26 | return {};
27 | }
28 |
29 | Rect childRect = {
30 | .size = rect.size,
31 | .position = { .x = 0.0f, .y = 0.0f },
32 | };
33 |
34 | ElementWithRect childElementWithRect(child, childRect);
35 | return { childElementWithRect };
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/library/WithChildren.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 12.01.2024.
3 | //
4 |
5 | #ifndef ELEMENTOR_WITH_CHILDREN_H
6 | #define ELEMENTOR_WITH_CHILDREN_H
7 |
8 | #include
9 | #include
10 |
11 | #include "Element.h"
12 |
13 | namespace elementor {
14 | class WithChildren {
15 | public:
16 | [[nodiscard]] std::vector> getChildrenList() const {
17 | return children;
18 | }
19 |
20 | [[nodiscard]] size_t getChildrenSize() const {
21 | return children.size();
22 | }
23 |
24 | [[nodiscard]] std::shared_ptr getChild(int i) const {
25 | return children[i];
26 | }
27 |
28 | [[nodiscard]] int childIndex(const std::shared_ptr& child) const {
29 | for (int i = 0; i < children.size(); i++) {
30 | if (children[i] == child) {
31 | return i;
32 | }
33 | }
34 | return -1;
35 | }
36 |
37 | protected:
38 | std::vector> children;
39 | };
40 |
41 | }
42 |
43 | #endif //ELEMENTOR_WITH_CHILDREN_H
44 |
--------------------------------------------------------------------------------
/src/library/elements/FitCover.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 27.07.2022.
3 | //
4 |
5 | #include "FitCover.h"
6 |
7 | #include
8 |
9 | namespace elementor::elements {
10 | std::vector FitCover::getChildren(const ElementRect& rect) {
11 | if (doesNotHaveChild()) {
12 | return {};
13 | }
14 |
15 | Size realChildSize = child->getSize(InfiniteBoundaries);
16 |
17 | float ratio = realChildSize.width / realChildSize.height;
18 | Size childSize{
19 | .width = rect.size.width > rect.size.height ? rect.size.width : rect.size.height / ratio,
20 | .height = rect.size.width > rect.size.height ? rect.size.width / ratio : rect.size.height,
21 | };
22 |
23 | Position childPosition = {
24 | .x = (rect.size.width - childSize.width) / 2,
25 | .y = (rect.size.height - childSize.height) / 2
26 | };
27 |
28 | Rect childRect = { .size = childSize, .position = childPosition };
29 |
30 | ElementWithRect childElement(child, childRect);
31 | return { childElement };
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/library/platforms/gl/GLFontManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 15.08.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_GL_FONT_MANAGER_H
6 | #define ELEMENTOR_GL_FONT_MANAGER_H
7 |
8 | #include "elementor.h"
9 |
10 | #include
11 |
12 | namespace elementor::platforms::gl {
13 | class GLFontManager {
14 | public:
15 | GLFontManager() {
16 | skFontManager = sk_make_sp();
17 | }
18 |
19 | [[nodiscard]] sk_sp getSkFontManager() const {
20 | return skFontManager;
21 | }
22 |
23 | void registerFontFromSkData(sk_sp data) {
24 | skFontManager->registerTypeface(SkTypeface::MakeFromData(std::move(data)));
25 | }
26 |
27 | void registerFontFromPath(const std::string& path) {
28 | registerFontFromSkData(SkData::MakeFromFileName(path.c_str()));
29 | }
30 |
31 | private:
32 | sk_sp skFontManager;
33 | };
34 | };
35 |
36 |
37 | #endif //ELEMENTOR_GL_FONT_MANAGER_H
38 |
--------------------------------------------------------------------------------
/src/library/ApplicationHoverState.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 06.02.2024.
3 | //
4 |
5 | #ifndef ELEMENTOR_APPLICATION_HOVER_STATE_H
6 | #define ELEMENTOR_APPLICATION_HOVER_STATE_H
7 |
8 | #include
9 | #include
10 |
11 | #include "Event.h"
12 | #include "ApplicationContext.h"
13 | #include "ApplicationTree.h"
14 |
15 | namespace elementor {
16 | class ApplicationHoverState {
17 | public:
18 | ApplicationHoverState(
19 | const std::shared_ptr& applicationTree,
20 | const std::shared_ptr& cursor
21 | )
22 | : applicationTree(applicationTree), cursor(cursor) {
23 | }
24 |
25 | void tick();
26 |
27 | EventCallbackResponse onEvent(const std::shared_ptr& event);
28 |
29 | private:
30 | std::shared_ptr applicationTree;
31 | std::shared_ptr cursor;
32 |
33 | std::shared_ptr hoveredNode = nullptr;
34 |
35 | void setHoveredNode(const std::shared_ptr& newHoveredNode);
36 | };
37 | }
38 |
39 | #endif //ELEMENTOR_APPLICATION_HOVER_STATE_H
40 |
--------------------------------------------------------------------------------
/src/library/elements/Stack.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 03.02.2022.
3 | //
4 |
5 | #include "Stack.h"
6 |
7 | namespace elementor::elements {
8 | Size Stack::getSize(const Boundaries& boundaries) {
9 | Size size{ 0, 0 };
10 | for (const auto& child: children) {
11 | Size childSize = child->getSize(boundaries);
12 | size.width = std::max(size.height, childSize.width);
13 | size.height = std::max(size.height, childSize.height);
14 | }
15 | return fitSizeInBoundaries(size, boundaries);
16 | }
17 |
18 | std::vector Stack::getChildren(const ElementRect& rect) {
19 | std::vector childrenElements;
20 |
21 | Boundaries childBoundaries = {
22 | .min = ZeroSize,
23 | .max = rect.size
24 | };
25 |
26 | for (const auto& child: children) {
27 | Size childSize = child->getSize(childBoundaries);
28 |
29 | Rect childRect = {
30 | .size = childSize,
31 | .position = { .x = 0, .y = 0 }
32 | };
33 |
34 | ElementWithRect childElement(child, childRect);
35 | childrenElements.push_back(childElement);
36 | }
37 |
38 | return childrenElements;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/library/elements/Image.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 26.07.2022.
3 | //
4 |
5 | #include "Image.h"
6 |
7 | #include
8 |
9 | namespace elementor::elements {
10 | sk_sp Image::makeImageFromFile(const std::string& path) {
11 | sk_sp encodedData = SkData::MakeFromFileName(path.c_str());
12 | return SkImage::MakeFromEncoded(encodedData);
13 | }
14 |
15 | void Image::paintBackground(SkCanvas* canvas, const ElementRect& rect) {
16 | if (skImage == nullptr) {
17 | return;
18 | }
19 |
20 | SkRect skRect = SkRect::MakeXYWH(0, 0, rect.size.width, rect.size.height);
21 | canvas->drawImageRect(skImage, skRect, samplingOptions);
22 | }
23 |
24 | Size Image::getSize(const Boundaries& boundaries) {
25 | if (skImage == nullptr) {
26 | return boundaries.min;
27 | }
28 |
29 | float pixelScale = ctx->getPixelScale();
30 | float imageWidthScaled = skImage->width() * pixelScale;
31 | float imageHeightScaled = skImage->height() * pixelScale;
32 |
33 | Size size = { imageWidthScaled, imageHeightScaled };
34 | size = fitSizeInBoundaries(size, boundaries);
35 |
36 | return size;
37 | }
38 | }
--------------------------------------------------------------------------------
/src/library/Component.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 02.01.2023.
3 | //
4 |
5 | #ifndef ELEMENTOR_COMPONENT_H
6 | #define ELEMENTOR_COMPONENT_H
7 |
8 | #include
9 | #include
10 |
11 | #include "Render.h"
12 | #include "Element.h"
13 |
14 | namespace elementor::elements {
15 | class Component : public Element {
16 | public:
17 | explicit Component(const std::shared_ptr& ctx)
18 | : Element(ctx) {
19 | }
20 |
21 | Size getSize(const Boundaries& boundaries) override {
22 | if (element == nullptr) {
23 | return boundaries.max;
24 | }
25 |
26 | return element->getSize(boundaries);
27 | }
28 |
29 | std::vector getChildren(const ElementRect& rect) override {
30 | if (element == nullptr) {
31 | return {};
32 | }
33 |
34 | Rect elementRect = {
35 | .size = rect.size,
36 | .position = { .x = 0, .y = 0 },
37 | };
38 | ElementWithRect elementWithRect(this->element, elementRect);
39 | return { elementWithRect };
40 | }
41 |
42 | protected:
43 | std::shared_ptr element = nullptr;
44 | };
45 | }
46 |
47 | #endif //ELEMENTOR_COMPONENT_H
48 |
--------------------------------------------------------------------------------
/src/library/elements/Focusable.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 18.05.2022.
3 | //
4 |
5 | #include "Focusable.h"
6 |
7 | namespace elementor::elements {
8 | Size Focusable::getSize(const Boundaries& boundaries) {
9 | if (doesNotHaveChild()) {
10 | return boundaries.max;
11 | }
12 |
13 | return child->getSize(boundaries);
14 | }
15 |
16 | std::vector Focusable::getChildren(const ElementRect& rect) {
17 | if (doesNotHaveChild()) {
18 | return {};
19 | }
20 |
21 | Rect childRect = {
22 | .size = rect.size,
23 | .position = { .x = 0, .y = 0 },
24 | };
25 |
26 | ElementWithRect childElement(child, childRect);
27 | return { childElement };
28 | }
29 |
30 | std::vector > Focusable::getEventsHandlers() {
31 | return {
32 | FocusEvent::Handle([this](const auto& event) {
33 | focused = event->focused;
34 |
35 | pendingBlur = false;
36 | pendingFocus = false;
37 |
38 | if (callbackFocusChange.has_value()) {
39 | callbackFocusChange.value()(event->focused);
40 | }
41 |
42 | return EventCallbackResponse::None;
43 | })
44 | };
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/library/elements/Ratio.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 13.04.2022.
3 | //
4 |
5 | #include "Ratio.h"
6 |
7 | namespace elementor::elements {
8 | Size fitRatioWithin(float ratio, const Size& size) {
9 | if (ratio >= 1) {
10 | return {
11 | .width = size.width,
12 | .height = size.width / ratio
13 | };
14 | } else {
15 | return {
16 | .width = size.height * ratio,
17 | .height = size.height
18 | };
19 | }
20 | }
21 |
22 | Size Ratio::getSize(const Boundaries& boundaries) {
23 | return fitSizeInBoundaries(fitRatioWithin(ratio, boundaries.max), boundaries);
24 | }
25 |
26 | std::vector Ratio::getChildren(const ElementRect& rect) {
27 | if (doesNotHaveChild()) {
28 | return {};
29 | }
30 |
31 | Size childSize = fitRatioWithin(ratio, rect.size);
32 |
33 | Position childPosition = {
34 | .x = (rect.size.width - childSize.width) / 2,
35 | .y = (rect.size.height - childSize.height) / 2
36 | };
37 |
38 | Rect childRect = { .size = childSize, .position = childPosition };
39 |
40 | ElementWithRect childElement(child, childRect);
41 | return { childElement };
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/library/elements/Hoverable.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 18.05.2022.
3 | //
4 |
5 | #include "Hoverable.h"
6 |
7 | namespace elementor::elements {
8 | Size Hoverable::getSize(const Boundaries& boundaries) {
9 | if (doesNotHaveChild()) {
10 | return boundaries.max;
11 | }
12 |
13 | return child->getSize(boundaries);
14 | }
15 |
16 | std::vector Hoverable::getChildren(const ElementRect& rect) {
17 | if (doesNotHaveChild()) {
18 | return {};
19 | }
20 |
21 | Rect childRect = {
22 | .size = rect.size,
23 | .position = { .x = 0, .y = 0 },
24 | };
25 |
26 | ElementWithRect childElement(child, childRect);
27 | return { childElement };
28 | }
29 |
30 | std::vector > Hoverable::getEventsHandlers() {
31 | return {
32 | HoverEvent::Handle([this](const auto& event) {
33 | if (callbackLeave && hovered && !event->hovered) {
34 | hovered = false;
35 | return callbackLeave();
36 | }
37 |
38 | if (callbackEnter && !hovered && event->hovered) {
39 | hovered = true;
40 | return callbackEnter();
41 | }
42 |
43 | hovered = event->hovered;
44 | return EventCallbackResponse::None;
45 | })
46 | };
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/library/elements/Height.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 13.04.2022.
3 | //
4 |
5 | #include "Height.h"
6 |
7 | namespace elementor::elements {
8 | Size Height::getSize(const Boundaries& boundaries) {
9 | float pixelScale = ctx->getPixelScale();
10 | float heightScaled = height * pixelScale;
11 |
12 | if (doesNotHaveChild()) {
13 | return fitSizeInBoundaries({
14 | .width = boundaries.max.width,
15 | .height = heightScaled
16 | }, boundaries);
17 | }
18 |
19 | Boundaries childBoundaries = {
20 | .min = {
21 | .width = boundaries.min.width,
22 | .height = std::max(heightScaled, boundaries.min.height)
23 | },
24 | .max = {
25 | .width = boundaries.max.width,
26 | .height = std::max(std::min(heightScaled, boundaries.max.height), boundaries.min.height)
27 | }
28 | };
29 |
30 | return child->getSize(childBoundaries);
31 | }
32 |
33 | std::vector Height::getChildren(const ElementRect& rect) {
34 | if (doesNotHaveChild()) {
35 | return {};
36 | }
37 |
38 | Rect childRect = {
39 | .size = rect.size,
40 | .position = { .x = 0, .y = 0 },
41 | };
42 |
43 | ElementWithRect childElement(child, childRect);
44 | return { childElement };
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/library/elements/FitContain.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 27.07.2022.
3 | //
4 |
5 | #include "FitContain.h"
6 |
7 | #include
8 |
9 | namespace elementor::elements {
10 | Size fitSizeWithin(const Size& inner, const Size& outer) {
11 | float innerRatio = inner.width / inner.height;
12 | float outerRatio = outer.width / outer.height;
13 | float resizeFactor = (innerRatio >= outerRatio)
14 | ? (outer.width / inner.width)
15 | : (outer.height / inner.height);
16 |
17 | return {
18 | .width = inner.width * resizeFactor,
19 | .height = inner.height * resizeFactor
20 | };
21 | }
22 |
23 | std::vector FitContain::getChildren(const ElementRect& rect) {
24 | if (doesNotHaveChild()) {
25 | return {};
26 | }
27 |
28 | Size realChildSize = child->getSize(InfiniteBoundaries);
29 | Size childSize = fitSizeWithin(realChildSize, rect.size);
30 |
31 | Position childPosition = {
32 | .x = (rect.size.width - childSize.width) / 2,
33 | .y = (rect.size.height - childSize.height) / 2
34 | };
35 |
36 | Rect childRect = { .size = childSize, .position = childPosition };
37 |
38 | ElementWithRect childElement(child, childRect);
39 | return { childElement };
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/library/elements/Width.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 13.04.2022.
3 | //
4 |
5 | #include "Width.h"
6 |
7 | namespace elementor::elements {
8 | Size Width::getSize(const Boundaries& boundaries) {
9 | float pixelScale = ctx->getPixelScale();
10 | float widthScaled = width * pixelScale;
11 |
12 | if (doesNotHaveChild()) {
13 | return fitSizeInBoundaries({
14 | .width = std::max(widthScaled, boundaries.min.width),
15 | .height = boundaries.max.height
16 | }, boundaries);
17 | }
18 |
19 | Boundaries childBoundaries = {
20 | .min = {
21 | .width = std::max(widthScaled, boundaries.min.width),
22 | .height = boundaries.min.height,
23 | },
24 | .max = {
25 | .width = std::max(std::min(widthScaled, boundaries.max.width), boundaries.min.width),
26 | .height = boundaries.max.height,
27 | }
28 | };
29 |
30 | return child->getSize(childBoundaries);
31 | }
32 |
33 | std::vector Width::getChildren(const ElementRect& rect) {
34 | if (doesNotHaveChild()) {
35 | return {};
36 | }
37 |
38 | Rect childRect = {
39 | .size = rect.size,
40 | .position = { .x = 0, .y = 0 },
41 | };
42 |
43 | ElementWithRect childElement(child, childRect);
44 | return { childElement };
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/components/utility.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 04.02.2023.
3 | //
4 |
5 | #include "utility.h"
6 |
7 | namespace elementor::components {
8 | void openURL(std::string url) {
9 | #if defined(OS_HOST_WINDOWS)
10 | std::string command = "start " + url;
11 | #elif defined(OS_HOST_LINUX)
12 | std::string command = "xdg-open " + url;
13 | #elif defined(OS_HOST_MACOS)
14 | std::string command = "open " + url;
15 | #endif
16 |
17 | system(command.c_str());
18 | }
19 |
20 | tm now_tm() {
21 | time_t now = time(nullptr);
22 | return *localtime(&now);
23 | }
24 |
25 | std::string leftPadAndFit(const std::string& value, unsigned int size, const char paddingChar) {
26 | if (value.length() == size) {
27 | return value;
28 | } else if (value.length() > size) {
29 | return value.substr(value.length() - size);
30 | } else {
31 | return std::string(size - value.length(), paddingChar) + value;
32 | }
33 | }
34 |
35 | int daysInMonth(int month, int year) {
36 | if (month == 4 || month == 6 || month == 9 || month == 11) {
37 | return 30;
38 | } else if (month == 2) {
39 | if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
40 | return 29;
41 | } else {
42 | return 28;
43 | }
44 | } else {
45 | return 31;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/library/ApplicationFocusState.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 06.02.2024.
3 | //
4 |
5 | #ifndef ELEMENTOR_APPLICATION_FOCUS_STATE_H
6 | #define ELEMENTOR_APPLICATION_FOCUS_STATE_H
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | #include "Event.h"
13 | #include "ApplicationContext.h"
14 | #include "ApplicationTree.h"
15 |
16 | #include "elements/Focusable.h"
17 |
18 | namespace elementor {
19 | class ApplicationFocusState {
20 | public:
21 | explicit ApplicationFocusState(const std::shared_ptr& applicationTree)
22 | : applicationTree(applicationTree) {
23 | }
24 |
25 | void tick();
26 |
27 | EventCallbackResponse onEvent(const std::shared_ptr& event);
28 |
29 | private:
30 | std::shared_ptr applicationTree;
31 |
32 | std::vector> focusableNodes = {};
33 | std::shared_ptr focusedNode = nullptr;
34 |
35 | void setFocusedNode(const std::shared_ptr& newFocusedNode);
36 |
37 | int getFocusedNodeIndex();
38 |
39 | void focusIthNode(int i);
40 |
41 | void focusNextNode();
42 |
43 | void focusPreviousNode();
44 |
45 | void clearFocusedNodeIfRemoved();
46 |
47 | void clearFocusedNodeIfPendingBlur();
48 | };
49 | }
50 |
51 | #endif //ELEMENTOR_APPLICATION_FOCUS_STATE_H
52 |
--------------------------------------------------------------------------------
/src/library/elements/Ratio.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 29.05.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_RATIO_H
6 | #define ELEMENTOR_RATIO_H
7 |
8 | #include "../include.h"
9 |
10 | namespace elementor::elements {
11 | struct RatioProps {
12 | float ratio = 0;
13 | const std::shared_ptr & child = nullptr;
14 | };
15 |
16 | class Ratio : public Element, public WithChild {
17 | public:
18 | Ratio(const std::shared_ptr & ctx, const RatioProps& props)
19 | : Element(ctx) {
20 | setRatio(props.ratio);
21 | setChild(props.child);
22 | }
23 |
24 | static std::shared_ptr New(
25 | const std::shared_ptr & ctx,
26 | const RatioProps& props
27 | ) {
28 | return std::make_shared(ctx, props);
29 | }
30 |
31 | static std::shared_ptr New(const std::shared_ptr & ctx) {
32 | return New(ctx, {});
33 | }
34 |
35 | void setRatio(float newValue) {
36 | markChanged();
37 | ratio = newValue;
38 | }
39 |
40 | [[nodiscard]] float getRatio() const {
41 | return ratio;
42 | }
43 |
44 | void setChild(const std::shared_ptr & newChild) {
45 | markChanged();
46 | child = newChild;
47 | }
48 |
49 | Size getSize(const Boundaries& boundaries) override;
50 |
51 | std::vector getChildren(const ElementRect& rect) override;
52 |
53 | private:
54 | float ratio = 0;
55 | };
56 | }
57 |
58 |
59 | #endif //ELEMENTOR_RATIO_H
60 |
--------------------------------------------------------------------------------
/src/library/elements/FitContain.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 27.07.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_FIT_CONTAIN_H
6 | #define ELEMENTOR_FIT_CONTAIN_H
7 |
8 | #include "../include.h"
9 |
10 | namespace elementor::elements {
11 | struct FitContainProps {
12 | const std::shared_ptr & child = nullptr;
13 | };
14 |
15 | class FitContain : public Element, public WithChild {
16 | public:
17 | FitContain(const std::shared_ptr & ctx, const FitContainProps& props)
18 | : Element(ctx) {
19 | setChild(props.child);
20 | }
21 |
22 | static std::shared_ptr New(
23 | const std::shared_ptr & ctx,
24 | const FitContainProps& props
25 | ) {
26 | return std::make_shared(ctx, props);
27 | }
28 |
29 | static std::shared_ptr New(
30 | const std::shared_ptr & ctx,
31 | std::shared_ptr & elementRef,
32 | const FitContainProps& props
33 | ) {
34 | auto element = New(ctx, props);
35 | elementRef = element;
36 | return element;
37 | }
38 |
39 | static std::shared_ptr New(const std::shared_ptr & ctx) {
40 | return New(ctx, {});
41 | }
42 |
43 | void setChild(const std::shared_ptr & newChild) {
44 | markChanged();
45 | child = newChild;
46 | }
47 |
48 | std::vector getChildren(const ElementRect& rect) override;
49 | };
50 | }
51 |
52 | #endif //ELEMENTOR_FIT_CONTAIN_H
53 |
--------------------------------------------------------------------------------
/src/library/elements/Rounded.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 21.04.2022.
3 | //
4 |
5 | #include "Rounded.h"
6 |
7 | #include
8 |
9 | namespace elementor::elements {
10 | void Rounded::paintBackground(SkCanvas* canvas, const ElementRect& rect) {
11 | auto pixelScale = ctx->getPixelScale();
12 |
13 | float topLeft = rectRadius.topLeft * pixelScale;
14 | float topRight = rectRadius.topRight * pixelScale;
15 | float bottomRight = rectRadius.bottomRight * pixelScale;
16 | float bottomLeft = rectRadius.bottomLeft * pixelScale;
17 |
18 | SkVector corners[] = {{ topLeft, topLeft },
19 | { topRight, topRight },
20 | { bottomRight, bottomRight },
21 | { bottomLeft, bottomLeft }};
22 |
23 | SkRRect skRRect;
24 | SkRect skRect = SkRect::MakeXYWH(0, 0, rect.size.width, rect.size.height);
25 | skRRect.setRectRadii(skRect, corners);
26 |
27 | canvas->clipRRect(skRRect, SkClipOp::kIntersect, true);
28 | }
29 |
30 | Size Rounded::getSize(const Boundaries& boundaries) {
31 | if (doesNotHaveChild()) {
32 | return boundaries.max;
33 | }
34 |
35 | return child->getSize(boundaries);
36 | }
37 |
38 | std::vector Rounded::getChildren(const ElementRect& rect) {
39 | if (doesNotHaveChild()) {
40 | return {};
41 | }
42 |
43 | Rect childRect = {
44 | .size = rect.size,
45 | .position = { .x=0, .y=0 }
46 | };
47 | ElementWithRect childElement(child, childRect);
48 | return { childElement };
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/library/elements/Stack.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 03.02.2023.
3 | //
4 |
5 | #ifndef ELEMENTOR_STACK_H
6 | #define ELEMENTOR_STACK_H
7 |
8 | #include "../include.h"
9 |
10 | namespace elementor::elements {
11 | struct StackProps {
12 | const std::vector >& children = {};
13 | };
14 |
15 | class Stack : public Element, public WithChildren {
16 | public:
17 | Stack(const std::shared_ptr & ctx, const StackProps& props)
18 | : Element(ctx) {
19 | setChildren(props.children);
20 | }
21 |
22 | static std::shared_ptr New(
23 | const std::shared_ptr & ctx,
24 | const StackProps& props
25 | ) {
26 | return std::make_shared(ctx, props);
27 | }
28 |
29 | static std::shared_ptr New(
30 | const std::shared_ptr & ctx,
31 | std::shared_ptr & elementRef,
32 | const StackProps& props
33 | ) {
34 | auto element = New(ctx, props);
35 | elementRef = element;
36 | return element;
37 | }
38 |
39 | static std::shared_ptr New(const std::shared_ptr & ctx) {
40 | return New(ctx, {});
41 | }
42 |
43 | void setChildren(const std::vector >& newChildren) {
44 | markChanged();
45 | children = newChildren;
46 | }
47 |
48 | Size getSize(const Boundaries& boundaries) override;
49 |
50 | std::vector getChildren(const ElementRect& rect) override;
51 | };
52 | }
53 |
54 |
55 | #endif //ELEMENTOR_STACK_H
56 |
--------------------------------------------------------------------------------
/src/library/elements/FitCover.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 27.07.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_FIT_COVER_H
6 | #define ELEMENTOR_FIT_COVER_H
7 |
8 | #include "../include.h"
9 |
10 | namespace elementor::elements {
11 | struct FitCoverProps {
12 | const std::shared_ptr& child = nullptr;
13 | };
14 |
15 | class FitCover : public Element, public WithChild {
16 | public:
17 | FitCover(const std::shared_ptr& ctx, const FitCoverProps& props)
18 | : Element(ctx) {
19 | setChild(props.child);
20 | }
21 |
22 | static std::shared_ptr New(
23 | const std::shared_ptr& ctx,
24 | const FitCoverProps& props
25 | ) {
26 | return std::make_shared(ctx, props);
27 | }
28 |
29 | static std::shared_ptr New(
30 | const std::shared_ptr & ctx,
31 | std::shared_ptr & elementRef,
32 | const FitCoverProps& props
33 | ) {
34 | auto element = New(ctx, props);
35 | elementRef = element;
36 | return element;
37 | }
38 |
39 | static std::shared_ptr New(const std::shared_ptr& ctx) {
40 | return New(ctx, {});
41 | }
42 |
43 | void setChild(const std::shared_ptr & newChild) {
44 | markChanged();
45 | child = newChild;
46 | }
47 |
48 | std::vector getChildren(const ElementRect& rect) override;
49 |
50 | ClipBehavior getClipBehaviour() override {
51 | return ClipBehavior::AntiAlias;
52 | }
53 | };
54 | }
55 |
56 | #endif //ELEMENTOR_FIT_COVER_H
57 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2022 Artem Noskov
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are
5 | met:
6 |
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in
12 | the documentation and/or other materials provided with the
13 | distribution.
14 |
15 | * Neither the name of the copyright holder nor the names of its
16 | contributors may be used to endorse or promote products derived
17 | from this software without specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/src/library/Element.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 13.04.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_ELEMENT_H
6 | #define ELEMENTOR_ELEMENT_H
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include
14 | #include
15 |
16 | #include "Render.h"
17 | #include "ApplicationContext.h"
18 |
19 | namespace elementor {
20 | enum class ClipBehavior {
21 | None,
22 | Hard,
23 | AntiAlias,
24 | };
25 |
26 | class Element {
27 | public:
28 | explicit Element(const std::shared_ptr& ctx)
29 | : ctx(ctx) {
30 | }
31 |
32 | virtual ~Element() = default;
33 |
34 | virtual Size getSize(const Boundaries& boundaries) {
35 | return boundaries.max;
36 | }
37 |
38 | virtual void paintBackground(SkCanvas* canvas, const ElementRect& rect) {
39 | }
40 |
41 | virtual std::vector&, Rect>> getChildren(
42 | const ElementRect& rect
43 | ) {
44 | return {};
45 | }
46 |
47 | virtual ClipBehavior getClipBehaviour() {
48 | return ClipBehavior::None;
49 | }
50 |
51 | virtual bool popChanged() {
52 | if (changed) {
53 | changed = false;
54 | return true;
55 | } else {
56 | return false;
57 | }
58 | }
59 |
60 | protected:
61 | std::shared_ptr ctx;
62 | bool changed = true;
63 |
64 | virtual void markChanged() {
65 | changed = true;
66 | }
67 | };
68 |
69 | using ElementWithRect = std::tuple&, Rect>;
70 | }
71 |
72 | #endif //ELEMENTOR_ELEMENT_H
73 |
--------------------------------------------------------------------------------
/src/library/elements/Align.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 29.05.2022.
3 | //
4 |
5 | #include "Align.h"
6 |
7 | namespace elementor::elements {
8 | Size Align::getSize(const Boundaries& boundaries) {
9 | if (doesNotHaveChild()) {
10 | return boundaries.max;
11 | }
12 |
13 | Boundaries childBoundaries = {
14 | .min = {
15 | widthCoefficient.has_value() ? 0 : boundaries.min.width,
16 | heightCoefficient.has_value() ? 0 : boundaries.min.height,
17 | },
18 | .max = boundaries.max
19 | };
20 |
21 | Size childSize = child->getSize(childBoundaries);
22 | Size elementSize = fitSizeInBoundaries(childSize, boundaries);
23 |
24 | return elementSize;
25 | }
26 |
27 | std::vector Align::getChildren(const ElementRect& rect) {
28 | if (doesNotHaveChild()) {
29 | return {};
30 | }
31 |
32 | Boundaries childBoundaries = {
33 | .min = {
34 | .width = widthCoefficient.has_value() ? 0 : rect.size.width,
35 | .height = heightCoefficient.has_value() ? 0 : rect.size.height,
36 | },
37 | .max = rect.size,
38 | };
39 | Size childSize = child->getSize(childBoundaries);
40 |
41 | Position childPosition = {
42 | .x = rect.size.width * widthCoefficient.value_or(0) -
43 | childSize.width * widthChildCoefficient.value_or(widthCoefficient.value_or(0)),
44 | .y = rect.size.height * heightCoefficient.value_or(0) -
45 | childSize.height * heightChildCoefficient.value_or(heightCoefficient.value_or(0))
46 | };
47 |
48 | Rect childRect = { .size = childSize, .position = childPosition };
49 |
50 | ElementWithRect childElement(child, childRect);
51 | return { childElement };
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/library/ApplicationHoverState.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 06.02.2024.
3 | //
4 |
5 | #include "ApplicationHoverState.h"
6 |
7 | namespace elementor {
8 | void ApplicationHoverState::tick() {
9 | auto cursorPosition = cursor->getPosition();
10 | if (cursorPosition == InvalidPosition) {
11 | setHoveredNode(nullptr);
12 | return;
13 | }
14 |
15 | setHoveredNode(
16 | applicationTree->findLastNode(
17 | [=](const std::shared_ptr& node) {
18 | return node->getRect().contains(cursorPosition);
19 | }
20 | )
21 | );
22 | }
23 |
24 | bool isCursorCausedEvent(const std::shared_ptr& event) {
25 | return event->getName() == "mouse-button"
26 | || event->getName() == "mouse-move"
27 | || event->getName() == "scroll";
28 | }
29 |
30 | EventCallbackResponse ApplicationHoverState::onEvent(const std::shared_ptr& event) {
31 | if (hoveredNode && isCursorCausedEvent(event)) {
32 | return hoveredNode->bubbleEvent(event);
33 | }
34 |
35 | return EventCallbackResponse::None;
36 | }
37 |
38 | void ApplicationHoverState::setHoveredNode(const std::shared_ptr& newHoveredNode) {
39 | if (hoveredNode && newHoveredNode && hoveredNode->getElement() == newHoveredNode->getElement()
40 | || hoveredNode == nullptr && newHoveredNode == nullptr) {
41 | return;
42 | }
43 |
44 | if (hoveredNode) {
45 | auto hoverLeaveEvent = std::make_shared(false);
46 | hoveredNode->bubbleEvent(hoverLeaveEvent);
47 | hoveredNode = nullptr;
48 | }
49 |
50 | if (newHoveredNode) {
51 | auto hoverEnterEvent = std::make_shared(true);
52 | newHoveredNode->bubbleEvent(hoverEnterEvent);
53 | hoveredNode = newHoveredNode;
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/src/library/elements/Width.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 29.05.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_WIDTH_H
6 | #define ELEMENTOR_WIDTH_H
7 |
8 | #include "../include.h"
9 |
10 | namespace elementor::elements {
11 | struct WidthProps {
12 | float width = 0;
13 | const std::shared_ptr & child = nullptr;
14 | };
15 |
16 | class Width : public Element, public WithChild {
17 | public:
18 | Width(const std::shared_ptr & ctx, const WidthProps& props)
19 | : Element(ctx) {
20 | setWidth(props.width);
21 | setChild(props.child);
22 | }
23 |
24 | static std::shared_ptr New(
25 | const std::shared_ptr & ctx,
26 | const WidthProps& props
27 | ) {
28 | return std::make_shared(ctx, props);
29 | }
30 |
31 | static std::shared_ptr New(
32 | const std::shared_ptr & ctx,
33 | std::shared_ptr & elementRef,
34 | const WidthProps& props
35 | ) {
36 | auto element = New(ctx, props);
37 | elementRef = element;
38 | return element;
39 | }
40 |
41 | static std::shared_ptr New(const std::shared_ptr & ctx) {
42 | return New(ctx, {});
43 | }
44 |
45 | void setWidth(float newValue) {
46 | markChanged();
47 | width = newValue;
48 | }
49 |
50 | [[nodiscard]] float getWidth() const {
51 | return width;
52 | }
53 |
54 | void setChild(const std::shared_ptr & newChild) {
55 | markChanged();
56 | child = newChild;
57 | }
58 |
59 | Size getSize(const Boundaries& boundaries) override;
60 |
61 | std::vector getChildren(const ElementRect& rect) override;
62 |
63 | private:
64 | float width = 0;
65 | };
66 | }
67 |
68 |
69 | #endif //ELEMENTOR_WIDTH_H
70 |
--------------------------------------------------------------------------------
/src/library/elements/Flexible.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 18.04.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_FLEXIBLE_H
6 | #define ELEMENTOR_FLEXIBLE_H
7 |
8 | #include "../include.h"
9 |
10 | namespace elementor::elements {
11 | struct FlexibleProps {
12 | float grow = 1.0;
13 | const std::shared_ptr & child = nullptr;
14 | };
15 |
16 | class Flexible : public Element, public WithChild {
17 | public:
18 | Flexible(const std::shared_ptr & ctx, const FlexibleProps& props)
19 | : Element(ctx) {
20 | setGrow(props.grow);
21 | setChild(props.child);
22 | }
23 |
24 | static std::shared_ptr New(
25 | const std::shared_ptr & ctx,
26 | const FlexibleProps& props
27 | ) {
28 | return std::make_shared(ctx, props);
29 | }
30 |
31 | static std::shared_ptr New(
32 | const std::shared_ptr & ctx,
33 | std::shared_ptr & elementRef,
34 | const FlexibleProps& props
35 | ) {
36 | auto element = New(ctx, props);
37 | elementRef = element;
38 | return element;
39 | }
40 |
41 | static std::shared_ptr New(const std::shared_ptr & ctx) {
42 | return New(ctx, {});
43 | }
44 |
45 | void setGrow(float newGrow) {
46 | markChanged();
47 | grow = newGrow;
48 | }
49 |
50 | float getGrow() const {
51 | return grow;
52 | }
53 |
54 | void setChild(const std::shared_ptr & newChild) {
55 | markChanged();
56 | child = newChild;
57 | }
58 |
59 | Size getSize(const Boundaries& boundaries) override;
60 |
61 | std::vector getChildren(const ElementRect& rect) override;
62 |
63 | private:
64 | float grow = 1;
65 | };
66 | }
67 |
68 |
69 | #endif //ELEMENTOR_FLEXIBLE_H
70 |
--------------------------------------------------------------------------------
/src/library/elements/Height.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 29.05.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_HEIGHT_H
6 | #define ELEMENTOR_HEIGHT_H
7 |
8 | #include "../include.h"
9 |
10 | namespace elementor::elements {
11 | struct HeightProps {
12 | float height = 0;
13 | const std::shared_ptr & child = nullptr;
14 | };
15 |
16 | class Height : public Element, public WithChild {
17 | public:
18 | Height(const std::shared_ptr & ctx, const HeightProps& props)
19 | : Element(ctx) {
20 | setHeight(props.height);
21 | setChild(props.child);
22 | }
23 |
24 | static std::shared_ptr New(
25 | const std::shared_ptr & ctx,
26 | const HeightProps& props
27 | ) {
28 | return std::make_shared(ctx, props);
29 | }
30 |
31 | static std::shared_ptr New(
32 | const std::shared_ptr & ctx,
33 | std::shared_ptr & elementRef,
34 | const HeightProps& props
35 | ) {
36 | auto element = New(ctx, props);
37 | elementRef = element;
38 | return element;
39 | }
40 |
41 | static std::shared_ptr New(const std::shared_ptr & ctx) {
42 | return New(ctx, {});
43 | }
44 |
45 | void setHeight(float newValue) {
46 | markChanged();
47 | height = newValue;
48 | }
49 |
50 | [[nodiscard]] float getHeight() const {
51 | return height;
52 | }
53 |
54 | void setChild(const std::shared_ptr & newChild) {
55 | markChanged();
56 | child = newChild;
57 | }
58 |
59 | Size getSize(const Boundaries& boundaries) override;
60 |
61 | std::vector getChildren(const ElementRect& rect) override;
62 |
63 | private:
64 | float height = 0;
65 | };
66 | }
67 |
68 |
69 | #endif //ELEMENTOR_HEIGHT_H
70 |
--------------------------------------------------------------------------------
/src/library/elements/Row.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 18.04.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_ROW_H
6 | #define ELEMENTOR_ROW_H
7 |
8 | #include "../include.h"
9 |
10 | namespace elementor::elements {
11 |
12 | struct RowProps {
13 | float spacing = 0;
14 | const std::vector >& children = {};
15 | };
16 |
17 | class Row : public Element, public WithChildren {
18 | public:
19 | Row(const std::shared_ptr & ctx, const RowProps& props)
20 | : Element(ctx) {
21 | setSpacing(props.spacing);
22 | setChildren(props.children);
23 | }
24 |
25 | static std::shared_ptr New(
26 | const std::shared_ptr & ctx,
27 | const RowProps& props
28 | ) {
29 | return std::make_shared(ctx, props);
30 | }
31 |
32 | static std::shared_ptr New(
33 | const std::shared_ptr & ctx,
34 | std::shared_ptr & elementRef,
35 | const RowProps& props
36 | ) {
37 | auto element = New(ctx, props);
38 | elementRef = element;
39 | return element;
40 | }
41 |
42 | static std::shared_ptr New(const std::shared_ptr & ctx) {
43 | return New(ctx, {});
44 | }
45 |
46 | float getSpacing() const {
47 | return spacing;
48 | }
49 |
50 | void setSpacing(float newSpacing) {
51 | markChanged();
52 | spacing = newSpacing;
53 | }
54 |
55 | void setChildren(const std::vector >& newChildren) {
56 | markChanged();
57 | children = newChildren;
58 | }
59 |
60 | Size getSize(const Boundaries& boundaries) override;
61 |
62 | std::vector getChildren(const ElementRect& rect) override;
63 |
64 | private:
65 | float spacing = 0;
66 | };
67 | }
68 |
69 |
70 | #endif //ELEMENTOR_ROW_H
71 |
--------------------------------------------------------------------------------
/src/library/elements/Column.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 18.04.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_COLUMN_H
6 | #define ELEMENTOR_COLUMN_H
7 |
8 | #include "../include.h"
9 |
10 | namespace elementor::elements {
11 | class Column : public Element, public WithChildren {
12 | public:
13 | struct Props {
14 | float spacing = 0;
15 | const std::vector >& children = {};
16 | };
17 |
18 | Column(const std::shared_ptr & ctx, const Props& props)
19 | : Element(ctx) {
20 | setSpacing(props.spacing);
21 | setChildren(props.children);
22 | }
23 |
24 | static std::shared_ptr New(
25 | const std::shared_ptr & ctx,
26 | const Props& props
27 | ) {
28 | return std::make_shared(ctx, props);
29 | }
30 |
31 | static std::shared_ptr New(
32 | const std::shared_ptr & ctx,
33 | std::shared_ptr & elementRef,
34 | const Props& props
35 | ) {
36 | auto element = New(ctx, props);
37 | elementRef = element;
38 | return element;
39 | }
40 |
41 | static std::shared_ptr New(const std::shared_ptr & ctx) {
42 | return New(ctx, {});
43 | }
44 |
45 | [[nodiscard]] float getSpacing() const {
46 | return spacing;
47 | }
48 |
49 | void setSpacing(float newSpacing) {
50 | markChanged();
51 | spacing = newSpacing;
52 | }
53 |
54 | void setChildren(const std::vector >& newChildren) {
55 | markChanged();
56 | children = newChildren;
57 | }
58 |
59 | Size getSize(const Boundaries& boundaries) override;
60 |
61 | std::vector getChildren(const ElementRect& rect) override;
62 |
63 | private:
64 | float spacing = 0;
65 | };
66 | }
67 |
68 |
69 | #endif //ELEMENTOR_COLUMN_H
70 |
--------------------------------------------------------------------------------
/src/library/elements/Clickable.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 21.05.2022.
3 | //
4 |
5 | #include "Clickable.h"
6 |
7 | namespace elementor::elements {
8 | Size Clickable::getSize(const Boundaries& boundaries) {
9 | if (doesNotHaveChild()) {
10 | return boundaries.max;
11 | }
12 |
13 | return child->getSize(boundaries);
14 | }
15 |
16 | std::vector Clickable::getChildren(const ElementRect& rect) {
17 | if (doesNotHaveChild()) {
18 | return {};
19 | }
20 |
21 | Rect childRect = {
22 | .size = rect.size,
23 | .position = { .x = 0, .y = 0 }
24 | };
25 |
26 | ElementWithRect childElement(child, childRect);
27 | return { childElement };
28 | }
29 |
30 | std::vector > Clickable::getEventsHandlers() {
31 | return {
32 | HoverEvent::Handle([this](const auto& event) {
33 | hovered = event->hovered;
34 | return EventCallbackResponse::None;
35 | }),
36 | MouseButtonEvent::Handle([this](const auto& event) {
37 | if (!hovered || event->action != KeyAction::Release) {
38 | return EventCallbackResponse::None;
39 | }
40 |
41 | if (callbackButton.has_value()) {
42 | auto callback = callbackButton.value();
43 | EventCallbackResponse callbackResponse = callback(event->button, event->mods);
44 | if (callbackResponse != EventCallbackResponse::None) {
45 | return callbackResponse;
46 | }
47 | }
48 |
49 | if (event->button == MouseButton::Left && callbackClick.has_value()) {
50 | auto callback = callbackClick.value();
51 | EventCallbackResponse callbackResponse = callback(event->mods);
52 | if (callbackResponse != EventCallbackResponse::None) {
53 | return callbackResponse;
54 | }
55 | }
56 |
57 | return EventCallbackResponse::None;
58 | })
59 | };
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/components/FPSLabel.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 03.08.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_COMPONENTS_FPS_LABEL_H
6 | #define ELEMENTOR_COMPONENTS_FPS_LABEL_H
7 |
8 | #include "utility.h"
9 | #include "elementor.h"
10 |
11 | namespace elementor::components {
12 | class FPSLabel : public Component {
13 | public:
14 | explicit FPSLabel(const std::shared_ptr& ctx)
15 | : Component(ctx) {
16 | element = Rounded::New(ctx, {
17 | .all = 3,
18 | .child = Background::New(ctx, {
19 | .color = "#e8e8e8cc",
20 | .child = Padding::New(ctx, {
21 | .all = 8,
22 | .child = Row::New(ctx, {
23 | .spacing = 4,
24 | .children = {
25 | Text::New(ctx, {
26 | .text = "FPS: ",
27 | .fontColor = "#000",
28 | .fontSize = 16.0f,
29 | .fontFamily = "Arial",
30 | }),
31 | Height::New(ctx, {
32 | .height = 14,
33 | .child = Width::New(ctx, {
34 | .width = 30,
35 | .child = Text::New(ctx, fpsText, {
36 | .text = "0",
37 | .fontColor = "#000",
38 | .fontSize = 16,
39 | .fontWeight = 500,
40 | .fontFamily = "Fira Code",
41 | }),
42 | })
43 | })
44 | }
45 | })
46 | })
47 | })
48 | });
49 |
50 | updateFPS();
51 | }
52 |
53 | static std::shared_ptr New(const std::shared_ptr& ctx) {
54 | return std::make_shared(ctx);
55 | }
56 |
57 | private:
58 | std::shared_ptr fpsText;
59 |
60 | void updateFPS() {
61 | auto fps = ctx->getPerfomance()->getFPS();
62 | fpsText->setText(std::to_string((int)fps));
63 |
64 | ctx->requestNextFrame([this]() {
65 | updateFPS();
66 | });
67 | }
68 | };
69 | }
70 |
71 | #endif //ELEMENTOR_COMPONENTS_FPS_LABEL_H
72 |
--------------------------------------------------------------------------------
/src/components/Slot.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 01.02.2024.
3 | //
4 |
5 | #ifndef ELEMENTOR_COMPONENTS_SLOT_H
6 | #define ELEMENTOR_COMPONENTS_SLOT_H
7 |
8 | #include "elementor.h"
9 |
10 | namespace elementor::elements {
11 | struct SlotProps {
12 | const std::shared_ptr& child = nullptr;
13 | };
14 |
15 | class Slot : public Element, public WithChild {
16 | public:
17 | Slot(const std::shared_ptr& ctx, const SlotProps& props)
18 | : Element(ctx) {
19 | }
20 |
21 | static std::shared_ptr New(
22 | const std::shared_ptr& ctx,
23 | const SlotProps& props
24 | ) {
25 | return std::make_shared(ctx, props);
26 | }
27 |
28 | static std::shared_ptr New(
29 | const std::shared_ptr& ctx,
30 | std::shared_ptr& elementRef,
31 | const SlotProps& props
32 | ) {
33 | auto element = New(ctx, props);
34 | elementRef = element;
35 | return element;
36 | }
37 |
38 | static std::shared_ptr New(const std::shared_ptr& ctx) {
39 | return New(ctx, {});
40 | }
41 |
42 | void setChild(const std::shared_ptr & newChild) {
43 | markChanged();
44 | child = newChild;
45 | }
46 |
47 | Size getSize(const Boundaries& boundaries) override {
48 | if (doesNotHaveChild()) {
49 | return boundaries.max;
50 | }
51 |
52 | return child->getSize(boundaries);
53 | }
54 |
55 | std::vector getChildren(const ElementRect& rect) override {
56 | if (doesNotHaveChild()) {
57 | return {};
58 | }
59 |
60 | Rect childRect = {
61 | .size = rect.size,
62 | .position = { .x = 0.0f, .y = 0.0f },
63 | };
64 |
65 | ElementWithRect childElementWithRect(child, childRect);
66 | return { childElementWithRect };
67 | }
68 | };
69 | }
70 |
71 |
72 | #endif //ELEMENTOR_COMPONENTS_SLOT_H
73 |
--------------------------------------------------------------------------------
/src/library/elements/Column.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 13.04.2022.
3 | //
4 |
5 | #include "Column.h"
6 |
7 | namespace elementor::elements {
8 | Size Column::getSize(const Boundaries& boundaries) {
9 | float maxWidth = 0;
10 | float totalHeight = 0;
11 | for (const auto& childElement: children) {
12 | Boundaries childBoundaries = {
13 | .min = { .width = boundaries.min.width, .height = 0 },
14 | .max = boundaries.max
15 | };
16 | Size childSize = childElement->getSize(childBoundaries);
17 |
18 | maxWidth = std::max(childSize.width, maxWidth);
19 | totalHeight += childSize.height;
20 | }
21 |
22 | auto pixelScale = ctx->getPixelScale();
23 | auto spacingScaled = spacing * pixelScale;
24 |
25 | totalHeight += ((float)children.size() - 1) * spacingScaled;
26 |
27 | Size elementSize = {
28 | .width = maxWidth,
29 | .height = totalHeight,
30 | };
31 | elementSize = fitSizeInBoundaries(elementSize, boundaries);
32 |
33 | return elementSize;
34 | }
35 |
36 | std::vector Column::getChildren(const ElementRect& rect) {
37 | std::vector childrenElements;
38 |
39 | auto pixelScale = ctx->getPixelScale();
40 | auto spacingScaled = spacing * pixelScale;
41 |
42 | float yPosition = 0;
43 | for (const auto& child: children) {
44 | Boundaries childBoundaries = {
45 | .min = { .width = rect.size.width, .height = 0 },
46 | .max = rect.size
47 | };
48 | Size childSize = child->getSize(childBoundaries);
49 |
50 | Rect childRect = {
51 | .size = childSize,
52 | .position = {
53 | .x = 0,
54 | .y = yPosition,
55 | }
56 | };
57 |
58 | ElementWithRect childElement(child, childRect);
59 | childrenElements.push_back(childElement);
60 |
61 | yPosition += childSize.height;
62 | yPosition += spacingScaled;
63 | }
64 |
65 | return childrenElements;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/library/elements/Row.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 13.04.2022.
3 | //
4 |
5 | #include "Row.h"
6 |
7 | namespace elementor::elements {
8 | Size Row::getSize(const Boundaries& boundaries) {
9 | float maxHeight = 0;
10 | float totalWidth = 0;
11 | for (const auto& childElement: children) {
12 | Boundaries childBoundaries = {
13 | .min = { .width = 0, .height = boundaries.min.height },
14 | .max = boundaries.max
15 | };
16 | Size childSize = childElement->getSize(childBoundaries);
17 |
18 | maxHeight = std::max(childSize.height, maxHeight);
19 | totalWidth += childSize.width;
20 | }
21 |
22 | auto pixelScale = ctx->getPixelScale();
23 | auto spacingScaled = spacing * pixelScale;
24 |
25 | totalWidth += ((float)children.size() - 1) * spacingScaled;
26 |
27 | Size elementSize = {
28 | .width = totalWidth,
29 | .height = maxHeight,
30 | };
31 | elementSize = fitSizeInBoundaries(elementSize, boundaries);
32 |
33 | return elementSize;
34 | }
35 |
36 | std::vector Row::getChildren(const ElementRect& rect) {
37 | std::vector childrenElements;
38 |
39 | auto pixelScale = ctx->getPixelScale();
40 | auto spacingScaled = spacing * pixelScale;
41 |
42 | float xPosition = 0;
43 | for (const auto& child: children) {
44 | Boundaries childBoundaries = {
45 | .min = { .width = 0, .height = rect.size.height },
46 | .max = rect.size
47 | };
48 | Size childSize = child->getSize(childBoundaries);
49 |
50 | Rect childRect = {
51 | .size = child->getSize(childBoundaries),
52 | .position = {
53 | .x = xPosition,
54 | .y = 0,
55 | }
56 | };
57 |
58 | ElementWithRect childElement(child, childRect);
59 | childrenElements.push_back(childElement);
60 |
61 | xPosition += childSize.width;
62 | xPosition += spacingScaled;
63 | }
64 |
65 | return childrenElements;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/library/platforms/gl/GLCursor.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 15.08.2022.
3 | //
4 |
5 | #ifndef ELEMENTOR_GL_CURSOR_H
6 | #define ELEMENTOR_GL_CURSOR_H
7 |
8 | #include "elementor.h"
9 |
10 | #include "GLFW/glfw3.h"
11 |
12 | #include "GLPlatformContext.h"
13 |
14 | namespace elementor::platforms::gl {
15 | class GLCursor : public Cursor {
16 | public:
17 | GLCursor(GLFWwindow* window)
18 | : window(window) {
19 | }
20 |
21 | void set(CursorShape shape) override {
22 | currentShape = shape;
23 | }
24 |
25 | CursorShape get() override {
26 | return currentShape;
27 | }
28 |
29 | Position getPosition() override {
30 | return position;
31 | }
32 |
33 | void setPosition(Position newValue) {
34 | position = newValue;
35 | }
36 |
37 | void updateCursor() {
38 | if (appliedShape != currentShape) {
39 | auto cursor = glfwCreateStandardCursor(mapCursorShapeToInt(currentShape));
40 | glfwSetCursor(window, cursor);
41 | appliedShape = currentShape;
42 | }
43 | }
44 |
45 | private:
46 | GLFWwindow* window;
47 |
48 | CursorShape currentShape = CursorShape::Default;
49 | CursorShape appliedShape = CursorShape::Default;
50 |
51 | Position position = { .x = -1, .y = -1 };
52 |
53 | static int mapCursorShapeToInt(CursorShape shape) {
54 | switch (shape) {
55 | case CursorShape::Default:
56 | case CursorShape::Arrow:
57 | return GLFW_ARROW_CURSOR;
58 | case CursorShape::IBeam:
59 | return GLFW_IBEAM_CURSOR;
60 | case CursorShape::Crosshair:
61 | return GLFW_CROSSHAIR_CURSOR;
62 | case CursorShape::Hand:
63 | return GLFW_HAND_CURSOR;
64 | case CursorShape::HorizontalResize:
65 | return GLFW_HRESIZE_CURSOR;
66 | case CursorShape::VerticalResize:
67 | return GLFW_VRESIZE_CURSOR;
68 | default:
69 | return GLFW_ARROW_CURSOR;
70 | }
71 | }
72 | };
73 | };
74 |
75 | #endif //ELEMENTOR_GL_CURSOR_H
76 |
--------------------------------------------------------------------------------
/src/components/Outline.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 01.02.2024.
3 | //
4 |
5 | #include "Outline.h"
6 |
7 | namespace elementor::components {
8 | Size Outline::getSize(const Boundaries& boundaries) {
9 | if (doesNotHaveChild()) {
10 | return boundaries.max;
11 | }
12 |
13 | return getChild()->getSize(boundaries);
14 | }
15 |
16 | std::vector Outline::getChildren(const ElementRect& rect) {
17 | if (doesNotHaveChild()) {
18 | return {};
19 | }
20 |
21 | std::vector children;
22 |
23 | if (focused) {
24 | auto pixelScale = ctx->getPixelScale();
25 | auto offsetScaled = offset * pixelScale;
26 |
27 | Rect borderRect = {
28 | .size = {
29 | .width = rect.size.width + offsetScaled * 2,
30 | .height = rect.size.height + offsetScaled * 2,
31 | },
32 | .position = {
33 | .x = -1 * offsetScaled,
34 | .y = -1 * offsetScaled
35 | },
36 | };
37 | auto borderAsElement = std::dynamic_pointer_cast(border);
38 | ElementWithRect borderElementWithRect(borderAsElement, borderRect);
39 | children.push_back(borderElementWithRect);
40 | }
41 |
42 | Rect childRect = {
43 | .size = rect.size,
44 | .position = { .x = 0.0f, .y = 0.0f },
45 | };
46 | ElementWithRect childElementWithRect(child, childRect);
47 | children.push_back(childElementWithRect);
48 |
49 | return children;
50 | }
51 |
52 | void Outline::setFocused(bool newFocused) {
53 | markChanged();
54 | focused = newFocused;
55 | }
56 |
57 | std::vector> Outline::getEventsHandlers() {
58 | return {
59 | FocusInEvent::Handle([this](const auto& event) {
60 | setFocused(true);
61 | return EventCallbackResponse::None;
62 | }),
63 | FocusOutEvent::Handle([this](const auto& event) {
64 | setFocused(false);
65 | return EventCallbackResponse::None;
66 | })
67 | };
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/library/Render.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem 21 18.05.2022.
3 | //
4 |
5 | #include "Render.h"
6 |
7 | #include
8 |
9 | namespace elementor {
10 | bool Rect::contains(float x, float y) const {
11 | return (
12 | position.x < x &&
13 | position.x + size.width > x &&
14 | position.y < y &&
15 | position.y + size.height > y
16 | );
17 | }
18 |
19 | bool Rect::contains(Position point) const {
20 | return contains(point.x, point.y);
21 | }
22 |
23 | Rect unionOfRects(const Rect& a, const Rect& b) {
24 | Rect result{};
25 | result.position.x = std::max(a.position.x, b.position.x);
26 | result.position.y = std::max(a.position.y, b.position.y);
27 | result.size.width = std::max(
28 | std::min(a.position.x + a.size.width, b.position.x + b.size.width) - result.position.x, 0.0f
29 | );
30 | result.size.height = std::max(
31 | std::min(a.position.y + a.size.height, b.position.y + b.size.height) - result.position.y, 0.0f
32 | );
33 | return result;
34 | }
35 |
36 | bool ElementRect::visibleContains(float x, float y) const {
37 | return (
38 | visiblePosition.x < x &&
39 | visiblePosition.x + visibleSize.width > x &&
40 | visiblePosition.y < y &&
41 | visiblePosition.y + visibleSize.height > y
42 | );
43 | }
44 |
45 | bool ElementRect::visibleContains(Position point) const {
46 | return visibleContains(point.x, point.y);
47 | }
48 |
49 | Position ElementRect::absolutePositionToContained(Position absolutePosition) const {
50 | return {
51 | .x = absolutePosition.x - position.x,
52 | .y = absolutePosition.y - position.y,
53 | };
54 | }
55 |
56 | Size fitSizeInBoundaries(Size size, Boundaries boundaries) {
57 | return {
58 | .width = std::min(std::max(size.width, boundaries.min.width), boundaries.max.width),
59 | .height = std::min(std::max(size.height, boundaries.min.height), boundaries.max.height)
60 | };
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/library/platforms/gl/GLEventLoop.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 13.01.2024.
3 | //
4 |
5 | #ifndef ELEMENTOR_GL_EVENT_LOOP_H
6 | #define ELEMENTOR_GL_EVENT_LOOP_H
7 |
8 | #include
9 |
10 | #include "GLFW/glfw3.h"
11 |
12 | #include "elementor.h"
13 |
14 | namespace elementor::platforms::gl {
15 | class GLEventLoop {
16 | public:
17 | explicit GLEventLoop(const std::function& callback)
18 | : callback(callback) {
19 | }
20 |
21 | void run() {
22 | running = true;
23 |
24 | for (;;) {
25 | D(
26 | const char* glfwErrorDescription;
27 | int glfwErrorCode = glfwGetError(&glfwErrorDescription);
28 | if (glfwErrorCode != 0 || glfwErrorDescription) {
29 | D_LOG("GLFW error: " << glfwErrorDescription << " (" << glfwErrorCode << ")" << std::endl);
30 | }
31 | );
32 |
33 | glfwWaitEvents();
34 |
35 | D(
36 | glfwErrorCode = glfwGetError(&glfwErrorDescription);
37 | if (glfwErrorCode != 0 || glfwErrorDescription) {
38 | D_LOG("GLFW error: " << glfwErrorDescription << " (" << glfwErrorCode << ")" << std::endl);
39 | }
40 | );
41 |
42 | tryCallCallback();
43 | if (shouldBreak) {
44 | break;
45 | }
46 | }
47 |
48 | running = false;
49 | }
50 |
51 | void pend() {
52 | glfwPostEmptyEvent();
53 | tryCallCallback();
54 | }
55 |
56 | private:
57 | bool running = false;
58 |
59 | std::function callback;
60 |
61 | std::chrono::steady_clock::time_point lastCallbackCall = std::chrono::steady_clock::now();
62 | bool shouldBreak = false;
63 |
64 | void tryCallCallback() {
65 | if (!running) {
66 | return;
67 | }
68 |
69 | auto now = std::chrono::steady_clock::now();
70 |
71 | if (now - lastCallbackCall > std::chrono::milliseconds(1)) {
72 | lastCallbackCall = now;
73 | shouldBreak |= callback();
74 | }
75 | }
76 | };
77 | }
78 |
79 | #endif //ELEMENTOR_GL_EVENT_LOOP_H
80 |
--------------------------------------------------------------------------------
/src/examples/counter/Counter.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by admin on 17.02.2024.
3 | //
4 |
5 | #ifndef EXAMPLES_COUNTER_H
6 | #define EXAMPLES_COUNTER_H
7 |
8 | #include "../elementor.h"
9 |
10 | class Counter : public Component {
11 | public:
12 | explicit Counter(const std::shared_ptr& ctx)
13 | : Component(ctx) {
14 | element = Background::New(ctx, {
15 | .color = "#fff",
16 | .child = Flex::New(ctx, {
17 | .spacing = 4,
18 | .alignment = FlexAlignment::Center,
19 | .crossAlignment = FlexCrossAlignment::Center,
20 | .children = {
21 | Rounded::New(ctx, {
22 | .all = 6,
23 | .child = Background::New(ctx, {
24 | .color = "#ebf0f0",
25 | .child = Padding::New(ctx, {
26 | .all = 8,
27 | .child = Width::New(ctx, {
28 | .width = 50,
29 | .child = Align::New(ctx, {
30 | .width = { 1, 1 },
31 | .child = Text::New(ctx, countText, {
32 | .text = std::to_string(count),
33 | .fontColor = "#000",
34 | .fontSize = 14,
35 | .fontFamily = "Fira Code",
36 | })
37 | })
38 | })
39 | })
40 | })
41 | }),
42 | TextButton::New(ctx, {
43 | .text = "Count",
44 | .fontColor = "#fff",
45 | .backgroundColor = "#ff5020",
46 | .onClick = [this] {
47 | incCount();
48 | return EventCallbackResponse::None;
49 | }
50 | })
51 | }
52 | })
53 | });
54 | }
55 |
56 | static std::shared_ptr New(const std::shared_ptr& ctx) {
57 | return std::make_shared(ctx);
58 | }
59 |
60 | private:
61 | int count = 0;
62 |
63 | std::shared_ptr countText;
64 |
65 | void setCount(int newValue) {
66 | count = newValue;
67 | countText->setText(std::to_string(count));
68 | }
69 |
70 | void incCount() {
71 | setCount(count + 1);
72 | }
73 | };
74 |
75 | #endif //EXAMPLES_COUNTER_H
76 |
--------------------------------------------------------------------------------
/src/components/Outline.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by noartem on 02.02.2023.
3 | //
4 |
5 | #ifndef ELEMENTOR_COMPONENTS_OUTLINE_H
6 | #define ELEMENTOR_COMPONENTS_OUTLINE_H
7 |
8 | #include "utility.h"
9 | #include "elementor.h"
10 |
11 | namespace elementor::components {
12 | struct OutlineProps {
13 | BorderProps border;
14 | float offset = 0.0f;
15 | const std::shared_ptr & child = nullptr;
16 | };
17 |
18 | class Outline : public Element, public WithChild, public WithEventsHandlers {
19 | public:
20 | explicit Outline(const std::shared_ptr & ctx, const OutlineProps& props)
21 | : Element(ctx) {
22 | offset = props.offset;
23 | border = Border::New(ctx, props.border);
24 | setChild(props.child);
25 | }
26 |
27 | static std::shared_ptr New(
28 | const std::shared_ptr & ctx,
29 | std::shared_ptr