From 8f170ff1f029ab7fd2fab60ae39b0961070b985a Mon Sep 17 00:00:00 2001 From: apio Date: Thu, 3 Aug 2023 12:19:45 +0200 Subject: [PATCH] libui: Add a GUI and graphics library --- CMakeLists.txt | 1 + libui/CMakeLists.txt | 15 ++++++++++++++ libui/include/ui/Canvas.h | 30 +++++++++++++++++++++++++++ libui/include/ui/Color.h | 34 +++++++++++++++++++++++++++++++ libui/include/ui/Point.h | 13 ++++++++++++ libui/include/ui/Rect.h | 18 ++++++++++++++++ libui/src/Canvas.cpp | 43 +++++++++++++++++++++++++++++++++++++++ libui/src/Color.cpp | 0 libui/src/Rect.cpp | 18 ++++++++++++++++ tools/install-headers.sh | 2 ++ tools/sources.sh | 2 +- 11 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 libui/CMakeLists.txt create mode 100644 libui/include/ui/Canvas.h create mode 100644 libui/include/ui/Color.h create mode 100644 libui/include/ui/Point.h create mode 100644 libui/include/ui/Rect.h create mode 100644 libui/src/Canvas.cpp create mode 100644 libui/src/Color.cpp create mode 100644 libui/src/Rect.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9740c155..05f81c8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,7 @@ endif() add_subdirectory(libluna) add_subdirectory(libos) +add_subdirectory(libui) add_subdirectory(libc) add_subdirectory(kernel) add_subdirectory(apps) diff --git a/libui/CMakeLists.txt b/libui/CMakeLists.txt new file mode 100644 index 00000000..b9bf2e94 --- /dev/null +++ b/libui/CMakeLists.txt @@ -0,0 +1,15 @@ +# The UI and graphics library for Luna. + +file(GLOB HEADERS include/ui/*.h) + +set(SOURCES + ${HEADERS} + src/Canvas.cpp + src/Color.cpp + src/Rect.cpp +) + +add_library(ui ${SOURCES}) +target_compile_options(ui PRIVATE ${COMMON_FLAGS}) +target_include_directories(ui PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include/) +target_include_directories(ui PUBLIC ${LUNA_BASE}/usr/include) diff --git a/libui/include/ui/Canvas.h b/libui/include/ui/Canvas.h new file mode 100644 index 00000000..c90f0ae7 --- /dev/null +++ b/libui/include/ui/Canvas.h @@ -0,0 +1,30 @@ +#pragma once +#include +#include +#include +#include +#include + +namespace ui +{ + /** + * @brief A drawable surface. + */ + struct Canvas + { + int width; + int height; + int stride; + u8* ptr; + + static Canvas create(u8* ptr, int width, int height); + Result subcanvas(Point begin, int width, int height, bool clamp); + + Rect rect() + { + return Rect { .begin = { 0, 0 }, .width = width, .height = height }; + } + + void fill(Color color); + }; +}; diff --git a/libui/include/ui/Color.h b/libui/include/ui/Color.h new file mode 100644 index 00000000..95a8d974 --- /dev/null +++ b/libui/include/ui/Color.h @@ -0,0 +1,34 @@ +#pragma once +#include + +namespace ui +{ + /** + * @brief A 32-bit RGBA color. + */ + struct Color + { + union { + u32 raw; + u8 colors[4]; + }; + + static constexpr Color from_u32(u32 raw) + { + return Color { .raw = raw }; + } + + static constexpr Color from_rgba(u8 red, u8 green, u8 blue, u8 alpha) + { + return Color { .colors = { blue, green, red, alpha } }; + } + + static constexpr Color from_rgb(u8 red, u8 green, u8 blue) + { + return from_rgba(red, green, blue, 0xff); + } + }; + + static constexpr Color WHITE = Color::from_rgb(0xff, 0xff, 0xff); + static constexpr Color BLACK = Color::from_rgb(0x00, 0x00, 0x00); +}; diff --git a/libui/include/ui/Point.h b/libui/include/ui/Point.h new file mode 100644 index 00000000..146ea0b8 --- /dev/null +++ b/libui/include/ui/Point.h @@ -0,0 +1,13 @@ +#pragma once + +namespace ui +{ + /** + * @brief A point in 2D space. + */ + struct Point + { + int x { 0 }; + int y { 0 }; + }; +} diff --git a/libui/include/ui/Rect.h b/libui/include/ui/Rect.h new file mode 100644 index 00000000..6d2bdec6 --- /dev/null +++ b/libui/include/ui/Rect.h @@ -0,0 +1,18 @@ +#pragma once +#include + +namespace ui +{ + /** + * @brief A simple rectangle. + */ + struct Rect + { + Point begin; + int width; + int height; + + bool contains(Point point); + Point normalize(Point point); + }; +} diff --git a/libui/src/Canvas.cpp b/libui/src/Canvas.cpp new file mode 100644 index 00000000..812610c0 --- /dev/null +++ b/libui/src/Canvas.cpp @@ -0,0 +1,43 @@ +#include +#include + +namespace ui +{ + Canvas Canvas::create(u8* ptr, int width, int height) + { + return Canvas { .width = width, .height = height, .stride = width, .ptr = ptr }; + } + + Result Canvas::subcanvas(Point begin, int w, int h, bool clamp) + { + if (!clamp) + { + if (begin.x + w > width) return err(ERANGE); + if (begin.y + h > height) return err(ERANGE); + } + else + { + if (begin.x + w > width) w = width - begin.x; + if (begin.y + h > height) h = height - begin.y; + } + + u8* p = ptr + begin.x * sizeof(Color) + (begin.y * sizeof(Color) * stride); + + return Canvas { .width = w, .height = h, .stride = stride, .ptr = p }; + } + + void Canvas::fill(Color color) + { + u8* p = ptr; + for (int i = 0; i < height; i++) + { + u32* colorp = (u32*)p; + for (int j = 0; j < width; j++) + { + *colorp = color.raw; + colorp++; + } + p += stride * sizeof(Color); + } + } +} diff --git a/libui/src/Color.cpp b/libui/src/Color.cpp new file mode 100644 index 00000000..e69de29b diff --git a/libui/src/Rect.cpp b/libui/src/Rect.cpp new file mode 100644 index 00000000..5d180eab --- /dev/null +++ b/libui/src/Rect.cpp @@ -0,0 +1,18 @@ +#include + +namespace ui +{ + bool Rect::contains(Point point) + { + return point.x >= begin.x && point.y >= begin.y && point.x <= begin.x + width && point.y <= begin.y + height; + } + + Point Rect::normalize(Point point) + { + if (point.x < begin.x) point.x = begin.x; + if (point.y < begin.y) point.y = begin.y; + if (point.x > begin.x + width) point.x = begin.x + width; + if (point.y > begin.y + height) point.y = begin.y + height; + return point; + } +}; diff --git a/tools/install-headers.sh b/tools/install-headers.sh index e7f919dd..999936d2 100755 --- a/tools/install-headers.sh +++ b/tools/install-headers.sh @@ -8,10 +8,12 @@ cd $LUNA_ROOT mkdir -p $LUNA_BASE mkdir -p $LUNA_BASE/usr/include mkdir -p $LUNA_BASE/usr/include/luna +mkdir -p $LUNA_BASE/usr/include/ui mkdir -p $LUNA_BASE/usr/include/os mkdir -p $LUNA_BASE/usr/include/moon cp --preserve=timestamps -RT libc/include/ $LUNA_BASE/usr/include cp --preserve=timestamps -RT libluna/include/luna/ $LUNA_BASE/usr/include/luna +cp --preserve=timestamps -RT libui/include/ui/ $LUNA_BASE/usr/include/ui cp --preserve=timestamps -RT libos/include/os/ $LUNA_BASE/usr/include/os cp --preserve=timestamps -RT kernel/src/api/ $LUNA_BASE/usr/include/moon diff --git a/tools/sources.sh b/tools/sources.sh index fcbd49e1..752d1883 100755 --- a/tools/sources.sh +++ b/tools/sources.sh @@ -4,7 +4,7 @@ source $(dirname $0)/env.sh cd $LUNA_ROOT -FOLDERS=(kernel libc libos libluna apps shell tests) +FOLDERS=(kernel libc libos libui libluna apps shell tests) SOURCES=($(find ${FOLDERS[@]} -type f -name "*.cpp")) SOURCES+=($(find ${FOLDERS[@]} -type f -name "*.h"))