Add a display server and graphical user interface #38
@ -1,4 +1,6 @@
|
||||
#include <ui/App.h>
|
||||
#include <ui/Container.h>
|
||||
#include <ui/Image.h>
|
||||
#include <ui/Layout.h>
|
||||
|
||||
Result<int> luna_main(int argc, char** argv)
|
||||
@ -17,6 +19,12 @@ Result<int> luna_main(int argc, char** argv)
|
||||
ui::HorizontalLayout layout(ui::AdjustHeight::Yes, ui::AdjustWidth::No);
|
||||
window->set_main_widget(layout);
|
||||
|
||||
ui::Container container({ 0, 0, 50, 50 }, ui::VerticalAlignment::Center, ui::HorizontalAlignment::Center);
|
||||
layout.add_widget(container);
|
||||
|
||||
auto image = TRY(ui::ImageWidget::load("/usr/share/icons/32x32/start-icon.tga"));
|
||||
container.set_widget(*image);
|
||||
|
||||
window->draw();
|
||||
|
||||
return app.run();
|
||||
|
@ -13,6 +13,8 @@ set(SOURCES
|
||||
src/App.cpp
|
||||
src/Window.cpp
|
||||
src/Layout.cpp
|
||||
src/Alignment.cpp
|
||||
src/Container.cpp
|
||||
)
|
||||
|
||||
add_library(ui ${SOURCES})
|
||||
|
30
libui/include/ui/Alignment.h
Normal file
30
libui/include/ui/Alignment.h
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @file Alignment.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief UI component alignment.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <ui/Rect.h>
|
||||
|
||||
namespace ui
|
||||
{
|
||||
enum class VerticalAlignment
|
||||
{
|
||||
Top,
|
||||
Center,
|
||||
Bottom
|
||||
};
|
||||
|
||||
enum class HorizontalAlignment
|
||||
{
|
||||
Left,
|
||||
Center,
|
||||
Right
|
||||
};
|
||||
|
||||
Rect align(Rect container, Rect contained, VerticalAlignment valign, HorizontalAlignment halign);
|
||||
}
|
31
libui/include/ui/Container.h
Normal file
31
libui/include/ui/Container.h
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* @file Container.h
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief A container widget to pad and align objects inside it.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <ui/Alignment.h>
|
||||
#include <ui/Widget.h>
|
||||
|
||||
namespace ui
|
||||
{
|
||||
class Container : public Widget
|
||||
{
|
||||
public:
|
||||
Container(Rect rect, VerticalAlignment valign, HorizontalAlignment halign);
|
||||
|
||||
void set_widget(Widget& widget);
|
||||
|
||||
Result<EventResult> handle_mousemove(Point position) override;
|
||||
Result<void> draw(Canvas& canvas) override;
|
||||
|
||||
private:
|
||||
Widget* m_widget;
|
||||
VerticalAlignment m_valign;
|
||||
HorizontalAlignment m_halign;
|
||||
};
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
#include <luna/Buffer.h>
|
||||
#include <luna/SharedPtr.h>
|
||||
#include <os/Path.h>
|
||||
#include <ui/Widget.h>
|
||||
|
||||
namespace ui
|
||||
{
|
||||
@ -77,4 +78,16 @@ namespace ui
|
||||
TGAHeader m_tga_header;
|
||||
Buffer m_image_data;
|
||||
};
|
||||
|
||||
class ImageWidget final : public Widget
|
||||
{
|
||||
public:
|
||||
static Result<OwnedPtr<ImageWidget>> load(const os::Path& path);
|
||||
|
||||
Result<EventResult> handle_mousemove(Point position) override;
|
||||
Result<void> draw(Canvas& canvas) override;
|
||||
|
||||
private:
|
||||
SharedPtr<Image> m_image;
|
||||
};
|
||||
}
|
||||
|
40
libui/src/Alignment.cpp
Normal file
40
libui/src/Alignment.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @file Alignment.cpp
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief UI component alignment.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ui/Alignment.h>
|
||||
|
||||
namespace ui
|
||||
{
|
||||
Rect align(Rect container, Rect contained, VerticalAlignment valign, HorizontalAlignment halign)
|
||||
{
|
||||
Rect result;
|
||||
result.width = contained.width;
|
||||
result.height = contained.height;
|
||||
result.pos.y = container.pos.y;
|
||||
result.pos.x = container.pos.x;
|
||||
|
||||
switch (valign)
|
||||
{
|
||||
case VerticalAlignment::Top: break;
|
||||
case VerticalAlignment::Center: result.pos.y += (container.height - contained.height) / 2; break;
|
||||
case VerticalAlignment::Bottom: result.pos.y += container.height - contained.height; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch (halign)
|
||||
{
|
||||
case HorizontalAlignment::Left: break;
|
||||
case HorizontalAlignment::Center: result.pos.x += (container.width - contained.width) / 2; break;
|
||||
case HorizontalAlignment::Right: result.pos.x += container.width - contained.width; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
39
libui/src/Container.cpp
Normal file
39
libui/src/Container.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file Container.cpp
|
||||
* @author apio (cloudapio.eu)
|
||||
* @brief A container widget to pad and align objects inside it.
|
||||
*
|
||||
* @copyright Copyright (c) 2023, the Luna authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ui/Container.h>
|
||||
|
||||
namespace ui
|
||||
{
|
||||
Container::Container(Rect rect, VerticalAlignment valign, HorizontalAlignment halign)
|
||||
: m_valign(valign), m_halign(halign)
|
||||
{
|
||||
m_rect = rect;
|
||||
}
|
||||
|
||||
void Container::set_widget(Widget& widget)
|
||||
{
|
||||
m_widget = &widget;
|
||||
widget.rect() = ui::align(m_rect, widget.rect(), m_valign, m_halign);
|
||||
}
|
||||
|
||||
Result<EventResult> Container::handle_mousemove(Point position)
|
||||
{
|
||||
return m_widget->handle_mousemove(position);
|
||||
}
|
||||
|
||||
Result<void> Container::draw(Canvas& canvas)
|
||||
{
|
||||
auto rect = ui::Rect { m_widget->rect().pos.x - m_rect.pos.x, m_widget->rect().pos.y - m_rect.pos.y,
|
||||
m_widget->rect().width, m_widget->rect().height };
|
||||
auto subcanvas = canvas.subcanvas(rect);
|
||||
return m_widget->draw(subcanvas);
|
||||
}
|
||||
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <os/File.h>
|
||||
#include <ui/Alignment.h>
|
||||
#include <ui/Image.h>
|
||||
|
||||
namespace ui
|
||||
@ -30,4 +31,23 @@ namespace ui
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
Result<OwnedPtr<ImageWidget>> ImageWidget::load(const os::Path& path)
|
||||
{
|
||||
auto widget = TRY(make_owned<ImageWidget>());
|
||||
widget->m_image = TRY(Image::load(path));
|
||||
widget->m_rect = { 0, 0, widget->m_image->width(), widget->m_image->height() };
|
||||
return widget;
|
||||
}
|
||||
|
||||
Result<EventResult> ImageWidget::handle_mousemove(Point)
|
||||
{
|
||||
return EventResult::DidNotHandle;
|
||||
}
|
||||
|
||||
Result<void> ImageWidget::draw(Canvas& canvas)
|
||||
{
|
||||
canvas.subcanvas({ 0, 0, m_image->width(), m_image->height() }).fill(m_image->pixels(), m_image->width());
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user