Compare commits
5 Commits
9a9c7e577a
...
b3dc027ba0
Author | SHA1 | Date | |
---|---|---|---|
b3dc027ba0 | |||
041d15a547 | |||
3d46e56386 | |||
d4e834f734 | |||
54afd7c2b0 |
@ -15,6 +15,26 @@ void sigchld_handler(int)
|
||||
wait(nullptr);
|
||||
}
|
||||
|
||||
Result<void> create_widget_group_for_app(ui::HorizontalLayout& layout, Slice<StringView> args, StringView icon)
|
||||
{
|
||||
auto* button = new (std::nothrow) ui::Button({ 0, 0, 50, 50 });
|
||||
if (!button) return err(ENOMEM);
|
||||
layout.add_widget(*button);
|
||||
|
||||
auto* container = new (std::nothrow)
|
||||
ui::Container({ 0, 0, 50, 50 }, ui::VerticalAlignment::Center, ui::HorizontalAlignment::Center);
|
||||
if (!container) return err(ENOMEM);
|
||||
button->set_widget(*container);
|
||||
button->set_action([=] { os::Process::spawn(args[0], args, false); });
|
||||
|
||||
auto image = TRY(ui::ImageWidget::load(icon));
|
||||
container->set_widget(*image);
|
||||
|
||||
image.leak();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<int> luna_main(int argc, char** argv)
|
||||
{
|
||||
ui::App app;
|
||||
@ -30,34 +50,17 @@ Result<int> luna_main(int argc, char** argv)
|
||||
app.set_main_window(window);
|
||||
window->set_background(TASKBAR_COLOR);
|
||||
|
||||
ui::HorizontalLayout layout(ui::AdjustHeight::Yes, ui::AdjustWidth::No);
|
||||
ui::HorizontalLayout layout(ui::Margins { 0, 0, 0, 0 }, ui::AdjustHeight::Yes, ui::AdjustWidth::No);
|
||||
window->set_main_widget(layout);
|
||||
|
||||
ui::Button term_button({ 0, 0, 50, 50 });
|
||||
layout.add_widget(term_button);
|
||||
StringView terminal_command[] = { "/usr/bin/terminal" };
|
||||
TRY(create_widget_group_for_app(layout, { terminal_command, 1 }, "/usr/share/icons/32x32/app-terminal.tga"));
|
||||
|
||||
ui::Container term_container({ 0, 0, 50, 50 }, ui::VerticalAlignment::Center, ui::HorizontalAlignment::Center);
|
||||
term_button.set_widget(term_container);
|
||||
term_button.set_action([] {
|
||||
StringView args[] = { "/usr/bin/terminal" };
|
||||
os::Process::spawn("/usr/bin/terminal", Slice<StringView> { args, 1 }, false);
|
||||
});
|
||||
StringView about_command[] = { "/usr/bin/about" };
|
||||
TRY(create_widget_group_for_app(layout, { about_command, 1 }, "/usr/share/icons/32x32/app-about.tga"));
|
||||
|
||||
auto term_image = TRY(ui::ImageWidget::load("/usr/share/icons/32x32/app-terminal.tga"));
|
||||
term_container.set_widget(*term_image);
|
||||
|
||||
ui::Button about_button({ 0, 0, 50, 50 });
|
||||
layout.add_widget(about_button);
|
||||
|
||||
ui::Container about_container({ 0, 0, 50, 50 }, ui::VerticalAlignment::Center, ui::HorizontalAlignment::Center);
|
||||
about_button.set_widget(about_container);
|
||||
about_button.set_action([] {
|
||||
StringView args[] = { "/usr/bin/about" };
|
||||
os::Process::spawn("/usr/bin/about", Slice<StringView> { args, 1 }, false);
|
||||
});
|
||||
|
||||
auto about_image = TRY(ui::ImageWidget::load("/usr/share/icons/32x32/app-about.tga"));
|
||||
about_container.set_widget(*about_image);
|
||||
StringView gol_command[] = { "/usr/bin/gol" };
|
||||
TRY(create_widget_group_for_app(layout, { gol_command, 1 }, "/usr/share/icons/32x32/app-gol.tga"));
|
||||
|
||||
window->draw();
|
||||
|
||||
|
BIN
base/usr/share/icons/32x32/app-gol.tga
Normal file
BIN
base/usr/share/icons/32x32/app-gol.tga
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
@ -49,6 +49,13 @@ template <typename T> class OwnedPtr
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
T* leak()
|
||||
{
|
||||
T* ptr = m_ptr;
|
||||
m_ptr = nullptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
T* operator->() const
|
||||
{
|
||||
return m_ptr;
|
||||
|
68
libui/include/ui/Action.h
Normal file
68
libui/include/ui/Action.h
Normal file
@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
#include <luna/Heap.h>
|
||||
|
||||
namespace ui
|
||||
{
|
||||
class Action
|
||||
{
|
||||
public:
|
||||
Action()
|
||||
{
|
||||
m_action = nullptr;
|
||||
}
|
||||
|
||||
Action(Action&& other) : m_action(other.m_action)
|
||||
{
|
||||
other.m_action = nullptr;
|
||||
}
|
||||
|
||||
template <typename T> Action(T&& function)
|
||||
{
|
||||
m_action = new (std::nothrow) ActionImpl<T>(move(function));
|
||||
}
|
||||
|
||||
template <typename T> Action& operator=(T&& function)
|
||||
{
|
||||
if (m_action) delete m_action;
|
||||
m_action = new (std::nothrow) ActionImpl<T>(move(function));
|
||||
return *this;
|
||||
}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
check(m_action);
|
||||
return m_action->call();
|
||||
}
|
||||
|
||||
~Action()
|
||||
{
|
||||
if (m_action) delete m_action;
|
||||
}
|
||||
|
||||
private:
|
||||
class ActionBase
|
||||
{
|
||||
public:
|
||||
virtual void call() = 0;
|
||||
virtual ~ActionBase() = default;
|
||||
};
|
||||
|
||||
template <typename T> class ActionImpl final : public ActionBase
|
||||
{
|
||||
public:
|
||||
ActionImpl(T&& function) : m_function(move(function))
|
||||
{
|
||||
}
|
||||
|
||||
void call()
|
||||
{
|
||||
return m_function();
|
||||
}
|
||||
|
||||
private:
|
||||
T m_function;
|
||||
};
|
||||
|
||||
ActionBase* m_action;
|
||||
};
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <ui/Action.h>
|
||||
#include <ui/Widget.h>
|
||||
|
||||
namespace ui
|
||||
@ -18,7 +19,7 @@ namespace ui
|
||||
Button(Rect rect);
|
||||
|
||||
void set_widget(Widget& widget);
|
||||
void set_action(void (*action)(void));
|
||||
void set_action(Action&& action);
|
||||
|
||||
Result<EventResult> handle_mouse_move(Point position) override;
|
||||
Result<EventResult> handle_mouse_leave() override;
|
||||
@ -31,6 +32,6 @@ namespace ui
|
||||
bool m_hovered { false };
|
||||
bool m_clicked { false };
|
||||
Widget* m_child;
|
||||
void (*m_action)(void);
|
||||
Action m_action;
|
||||
};
|
||||
}
|
||||
|
@ -25,10 +25,19 @@ namespace ui
|
||||
Yes
|
||||
};
|
||||
|
||||
struct Margins
|
||||
{
|
||||
int left;
|
||||
int right;
|
||||
int top;
|
||||
int bottom;
|
||||
};
|
||||
|
||||
class HorizontalLayout final : public Widget
|
||||
{
|
||||
public:
|
||||
HorizontalLayout(AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::Yes);
|
||||
HorizontalLayout(Margins margins = Margins { 0, 0, 0, 0 }, AdjustHeight adjust_height = AdjustHeight::Yes,
|
||||
AdjustWidth adjust_width = AdjustWidth::Yes);
|
||||
|
||||
Result<EventResult> handle_mouse_move(Point position) override;
|
||||
Result<EventResult> handle_mouse_leave() override;
|
||||
@ -42,6 +51,7 @@ namespace ui
|
||||
|
||||
private:
|
||||
Vector<Widget*> m_widgets;
|
||||
Margins m_margins;
|
||||
AdjustHeight m_adjust_height;
|
||||
AdjustWidth m_adjust_width;
|
||||
int m_used_width { 0 };
|
||||
@ -50,7 +60,8 @@ namespace ui
|
||||
class VerticalLayout final : public Widget
|
||||
{
|
||||
public:
|
||||
VerticalLayout(AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::Yes);
|
||||
VerticalLayout(Margins margins = Margins { 0, 0, 0, 0 }, AdjustHeight adjust_height = AdjustHeight::Yes,
|
||||
AdjustWidth adjust_width = AdjustWidth::Yes);
|
||||
|
||||
Result<EventResult> handle_mouse_move(Point position) override;
|
||||
Result<EventResult> handle_mouse_leave() override;
|
||||
@ -64,6 +75,7 @@ namespace ui
|
||||
|
||||
private:
|
||||
Vector<Widget*> m_widgets;
|
||||
Margins m_margins;
|
||||
AdjustHeight m_adjust_height;
|
||||
AdjustWidth m_adjust_width;
|
||||
int m_used_height { 0 };
|
||||
|
@ -24,9 +24,9 @@ namespace ui
|
||||
widget.set_parent(this);
|
||||
}
|
||||
|
||||
void Button::set_action(void (*action)(void))
|
||||
void Button::set_action(Action&& action)
|
||||
{
|
||||
m_action = action;
|
||||
m_action = move(action);
|
||||
}
|
||||
|
||||
Result<EventResult> Button::handle_mouse_move(Point position)
|
||||
|
@ -12,8 +12,8 @@
|
||||
|
||||
namespace ui
|
||||
{
|
||||
HorizontalLayout::HorizontalLayout(AdjustHeight adjust_height, AdjustWidth adjust_width)
|
||||
: m_adjust_height(adjust_height), m_adjust_width(adjust_width)
|
||||
HorizontalLayout::HorizontalLayout(Margins margins, AdjustHeight adjust_height, AdjustWidth adjust_width)
|
||||
: m_margins(margins), m_adjust_height(adjust_height), m_adjust_width(adjust_width)
|
||||
{
|
||||
}
|
||||
|
||||
@ -95,8 +95,8 @@ namespace ui
|
||||
|
||||
if (m_adjust_width == AdjustWidth::No)
|
||||
{
|
||||
widget.rect().pos.x = m_rect.pos.x + m_used_width;
|
||||
m_used_width += widget.rect().width;
|
||||
widget.rect().pos.x = m_rect.pos.x + m_used_width + m_margins.left;
|
||||
m_used_width += m_margins.left + widget.rect().width + m_margins.right;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -104,24 +104,27 @@ namespace ui
|
||||
div_t result = div(m_rect.width, (int)m_widgets.size());
|
||||
for (auto w : m_widgets)
|
||||
{
|
||||
w->rect().pos.x = m_rect.pos.x + used_width;
|
||||
w->rect().width = result.quot;
|
||||
w->rect().pos.x = m_rect.pos.x + used_width + m_margins.left;
|
||||
w->rect().width = result.quot - (m_margins.left + m_margins.right);
|
||||
used_width += result.quot;
|
||||
}
|
||||
m_widgets[m_widgets.size() - 1]->rect().width += result.rem;
|
||||
}
|
||||
|
||||
widget.rect().pos.y = m_rect.pos.y;
|
||||
widget.rect().pos.y = m_rect.pos.y + m_margins.top;
|
||||
|
||||
if (m_adjust_height == AdjustHeight::Yes) { widget.rect().height = m_rect.height; }
|
||||
if (m_adjust_height == AdjustHeight::Yes)
|
||||
{
|
||||
widget.rect().height = m_rect.height - (m_margins.top + m_margins.bottom);
|
||||
}
|
||||
|
||||
widget.set_parent(this);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
VerticalLayout::VerticalLayout(AdjustHeight adjust_height, AdjustWidth adjust_width)
|
||||
: m_adjust_height(adjust_height), m_adjust_width(adjust_width)
|
||||
VerticalLayout::VerticalLayout(Margins margins, AdjustHeight adjust_height, AdjustWidth adjust_width)
|
||||
: m_margins(margins), m_adjust_height(adjust_height), m_adjust_width(adjust_width)
|
||||
{
|
||||
}
|
||||
|
||||
@ -203,8 +206,8 @@ namespace ui
|
||||
|
||||
if (m_adjust_height == AdjustHeight::No)
|
||||
{
|
||||
widget.rect().pos.y = m_rect.pos.y + m_used_height;
|
||||
m_used_height += widget.rect().height;
|
||||
widget.rect().pos.y = m_rect.pos.y + m_used_height + m_margins.top;
|
||||
m_used_height += m_margins.top + widget.rect().height + m_margins.bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -212,16 +215,19 @@ namespace ui
|
||||
div_t result = div(m_rect.height, (int)m_widgets.size());
|
||||
for (auto w : m_widgets)
|
||||
{
|
||||
w->rect().pos.y = m_rect.pos.y + used_height;
|
||||
w->rect().height = result.quot;
|
||||
w->rect().pos.y = m_rect.pos.y + used_height + m_margins.top;
|
||||
w->rect().height = result.quot - (m_margins.top + m_margins.bottom);
|
||||
used_height += result.quot;
|
||||
}
|
||||
m_widgets[m_widgets.size() - 1]->rect().height += result.rem;
|
||||
}
|
||||
|
||||
widget.rect().pos.x = m_rect.pos.x;
|
||||
widget.rect().pos.x = m_rect.pos.x + m_margins.left;
|
||||
|
||||
if (m_adjust_width == AdjustWidth::Yes) { widget.rect().width = m_rect.width; }
|
||||
if (m_adjust_width == AdjustWidth::Yes)
|
||||
{
|
||||
widget.rect().width = m_rect.width - (m_margins.left + m_margins.right);
|
||||
}
|
||||
|
||||
widget.set_parent(this);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user