Squash commits for public release

This commit is contained in:
2025-02-12 09:54:05 -05:00
commit 7118adc514
1108 changed files with 80873 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
#include "HomeScreenView.h"
#include "HomeScreenViewController.h"
#include "HomeScreenWindow.h"
#include <libui/AppDelegate.h>
class AppDelegate : public UI::AppDelegate {
public:
AppDelegate() = default;
virtual ~AppDelegate() = default;
LG::Size preferred_desktop_window_size() const override { return LG::Size(400, 300); }
bool application() override
{
auto& window = std::xos::construct<HomeScreenWindow>(window_size());
window.set_bitmap_format(LG::PixelBitmapFormat::RGBA); // Turning on Alpha channel
auto& dock_view = window.create_superview<HomeScreenView, HomeScreenViewController>();
return true;
}
private:
};
SET_APP_DELEGATE(AppDelegate);

View File

@@ -0,0 +1,33 @@
#include "AppListView.h"
#include <libg/ImageLoaders/PNGLoader.h>
#include <libui/App.h>
#include <libui/Context.h>
#include <libui/Label.h>
#include <libui/Screen.h>
#include <libui/Window.h>
AppListView::AppListView(View* superview, const LG::Rect& frame)
: View(superview, frame)
{
// TODO: Drag-like animation is needed here.
auto& label = add_subview<UI::Label>(bounds());
label.set_text("Swipe up to open AppList");
label.set_alignment(UI::Text::Alignment::Center);
}
void AppListView::display(const LG::Rect& rect)
{
}
void AppListView::on_click()
{
int this_window_id = window()->id();
if (m_target_window_id == INVALID) {
return;
}
auto& app = UI::App::the();
AskBringToFrontMessage msg(app.connection().key(), this_window_id, m_target_window_id);
app.connection().send_async_message(msg);
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include <libg/Font.h>
#include <libui/Label.h>
#include <libui/PopupMenu.h>
#include <libui/View.h>
#include <list>
#include <string>
#include <unistd.h>
class AppListView : public UI::View {
UI_OBJECT();
static constexpr int INVALID = -1;
public:
AppListView(View* superview, const LG::Rect& frame);
void set_target_window_id(int winid) { m_target_window_id = winid; }
void display(const LG::Rect& rect) override;
void mouse_up() override { on_click(); }
void on_click();
private:
int m_target_window_id { INVALID };
LG::PixelBitmap m_icon;
};

View File

@@ -0,0 +1,18 @@
import("//build/userland/TEMPLATE.gni")
xOS_executable("homescreen") {
install_path = "System/"
sources = [
"AppDelegate.cpp",
"AppListView.cpp",
"HomeScreenView.cpp",
"IconView.cpp",
]
configs = [ "//build/userland:userland_flags" ]
deplibs = [
"libcxx",
"libfoundation",
"libg",
"libui",
]
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include <libg/PixelBitmap.h>
#include <string>
class FastLaunchEntity {
public:
FastLaunchEntity() = default;
void set_icon(LG::PixelBitmap&& icon) { m_icon = std::move(icon); }
const LG::PixelBitmap& icon() const { return m_icon; }
void set_path_to_exec(std::string&& path) { m_path_to_exec = std::move(path); }
const std::string& path_to_exec() const { return m_path_to_exec; }
private:
LG::PixelBitmap m_icon;
std::string m_path_to_exec {};
};

View File

@@ -0,0 +1,24 @@
#pragma once
#include <libg/PixelBitmap.h>
class HomeScreenEntity {
public:
HomeScreenEntity() = default;
HomeScreenEntity(int window_id)
: m_window_id(window_id)
{
}
bool operator==(const HomeScreenEntity& other) const { return m_window_id == other.m_window_id; }
bool operator!=(const HomeScreenEntity& other) const { return m_window_id != other.m_window_id; }
int window_id() const { return m_window_id; }
void set_icon(LG::PixelBitmap&& icon) { m_icon = std::move(icon); }
const LG::PixelBitmap& icon() const { return m_icon; }
private:
int m_window_id { 0 };
LG::PixelBitmap m_icon;
int m_window_status { 0 };
};

View File

@@ -0,0 +1,127 @@
#include "HomeScreenView.h"
#include "AppListView.h"
#include "IconView.h"
#include <algorithm>
#include <cstdlib>
#include <libfoundation/EventLoop.h>
#include <libfoundation/KeyboardMapping.h>
#include <libg/Color.h>
#include <libg/ImageLoaders/PNGLoader.h>
#include <libui/App.h>
#include <libui/Context.h>
#include <libui/StackView.h>
#include <unistd.h>
static HomeScreenView* this_view;
HomeScreenView::HomeScreenView(UI::View* superview, const LG::Rect& frame)
: UI::View(superview, frame)
{
}
HomeScreenView::HomeScreenView(UI::View* superview, UI::Window* window, const LG::Rect& frame)
: UI::View(superview, window, frame)
{
LG::Rect homegrid_frame = LG::Rect(0, grid_padding(), bounds().width(), bounds().height() - grid_padding() - dock_height_with_padding());
auto& vstack_view = add_subview<UI::StackView>(homegrid_frame);
vstack_view.set_background_color(LG::Color::Opaque);
vstack_view.set_axis(UI::LayoutConstraints::Axis::Vertical);
vstack_view.set_distribution(UI::StackView::Distribution::EqualSpacing);
vstack_view.set_alignment(UI::StackView::Alignment::Center);
for (int i = 0; i < grid_entities_per_column(); i++) {
auto& hstack_view = vstack_view.add_arranged_subview<UI::StackView>();
hstack_view.set_background_color(LG::Color::Opaque);
hstack_view.set_distribution(UI::StackView::Distribution::EqualSpacing);
vstack_view.add_constraint(UI::Constraint(hstack_view, UI::Constraint::Attribute::Left, UI::Constraint::Relation::Equal, vstack_view, UI::Constraint::Attribute::Left, 1, grid_padding()));
vstack_view.add_constraint(UI::Constraint(hstack_view, UI::Constraint::Attribute::Right, UI::Constraint::Relation::Equal, vstack_view, UI::Constraint::Attribute::Right, 1, -grid_padding()));
vstack_view.add_constraint(UI::Constraint(hstack_view, UI::Constraint::Attribute::Height, UI::Constraint::Relation::Equal, icon_view_size()));
m_grid_stackviews.push_back(&hstack_view);
}
int dock_offsety = bounds().height() - dock_height_with_padding();
auto& dock_subview = add_subview<UI::View>(LG::Rect(0, dock_offsety, bounds().width(), dock_height_with_padding()));
dock_subview.layer().set_corner_mask(LG::CornerMask(16, LG::CornerMask::Masked, LG::CornerMask::NonMasked));
dock_subview.set_background_color(LG::Color::LightSystemOpaque128);
dock_subview.add_gesture_recognizer<UI::SwipeGestureRecognizer>([this](const UI::GestureRecognizer* recon) {
if (recon->state() == UI::GestureRecognizer::State::Ended) {
if (m_applist_view) {
m_applist_view->on_click();
}
}
});
LG::Rect applist_frame = homegrid_frame;
applist_frame.set_x(grid_padding());
applist_frame.set_width(bounds().width() - 2 * grid_padding());
applist_frame.set_y(bounds().height() - dock_height_with_padding() + grid_padding());
applist_frame.set_height(applist_height());
auto& applist_view = add_subview<AppListView>(applist_frame);
m_applist_view = &applist_view;
LG::Rect dock_frame = homegrid_frame;
dock_frame.set_y(applist_frame.max_y() + (dock_height() - icon_size()) / 2);
dock_frame.set_height(dock_height());
auto& dock_stack_view = add_subview<UI::StackView>(dock_frame);
dock_stack_view.set_spacing(12); // TODO: Set spacing which depends on screen width.
dock_stack_view.set_background_color(LG::Color::Opaque);
dock_stack_view.set_axis(UI::LayoutConstraints::Axis::Horizontal);
dock_stack_view.set_distribution(UI::StackView::Distribution::EqualCentering);
m_dock_stackview = &dock_stack_view;
vstack_view.set_needs_layout();
}
void HomeScreenView::display(const LG::Rect& rect)
{
LG::Context ctx = UI::graphics_current_context();
ctx.add_clip(rect);
ctx.set_fill_color(LG::Color(0, 0, 0, 0));
ctx.fill(bounds());
}
void HomeScreenView::new_grid_entity(const std::string& title, const std::string& icon_path, std::string&& exec_path)
{
// TODO: Add pages.
LG::PNG::PNGLoader loader;
int row_to_put_to = 0;
for (int i = 0; i < grid_entities_per_column(); i++) {
if (m_grid_stackviews[i]->subviews().size() < grid_entities_per_row()) {
row_to_put_to = i;
break;
}
}
auto& icon_view = m_grid_stackviews[row_to_put_to]->add_arranged_subview<IconView>();
icon_view.add_constraint(UI::Constraint(icon_view, UI::Constraint::Attribute::Height, UI::Constraint::Relation::Equal, icon_view_size()));
icon_view.add_constraint(UI::Constraint(icon_view, UI::Constraint::Attribute::Width, UI::Constraint::Relation::Equal, icon_view_size()));
icon_view.set_title(title);
icon_view.entity().set_icon(loader.load_from_file(icon_path + "/48x48.png"));
icon_view.entity().set_path_to_exec(std::move(exec_path));
set_needs_layout();
}
void HomeScreenView::new_fast_launch_entity(const std::string& title, const std::string& icon_path, std::string&& exec_path)
{
if (m_dock_stackview->subviews().size() >= grid_entities_per_row()) {
return;
}
LG::PNG::PNGLoader loader;
auto& icon_view = m_dock_stackview->add_arranged_subview<IconView>();
icon_view.add_constraint(UI::Constraint(icon_view, UI::Constraint::Attribute::Height, UI::Constraint::Relation::Equal, icon_view_size()));
icon_view.add_constraint(UI::Constraint(icon_view, UI::Constraint::Attribute::Width, UI::Constraint::Relation::Equal, icon_view_size()));
icon_view.entity().set_icon(loader.load_from_file(icon_path + "/48x48.png"));
icon_view.entity().set_path_to_exec(std::move(exec_path));
set_needs_layout();
}
void HomeScreenView::on_window_create(const std::string& bundle_id, const std::string& icon_path, int window_id, int window_type)
{
if (window_type == WindowType::AppList) {
if (m_applist_view) {
m_applist_view->set_target_window_id(window_id);
}
return;
}
}

View File

@@ -0,0 +1,42 @@
#pragma once
#include "AppListView.h"
#include "FastLaunchEntity.h"
#include "HomeScreenEntity.h"
#include <libg/Font.h>
#include <libui/StackView.h>
#include <libui/View.h>
#include <list>
#include <string>
#include <vector>
class HomeScreenView : public UI::View {
UI_OBJECT();
public:
HomeScreenView(UI::View* superview, const LG::Rect& frame);
HomeScreenView(UI::View* superview, UI::Window* window, const LG::Rect& frame);
static constexpr int dock_height() { return 70; }
static constexpr int applist_height() { return 22; }
static constexpr int dock_height_with_padding() { return dock_height() + applist_height() + 2 * grid_padding() + 4; }
static constexpr int grid_entities_size() { return 48; }
static constexpr int icon_size() { return 48; }
static constexpr int icon_view_size() { return 62; }
static constexpr int grid_padding() { return 16; }
static constexpr int grid_entities_per_row() { return 4; }
static constexpr int grid_entities_per_column() { return 5; }
void display(const LG::Rect& rect) override;
void on_window_create(const std::string& bundle_id, const std::string& icon_path, int window_id, int window_type);
void new_grid_entity(const std::string& title, const std::string& icon_path, std::string&& exec_path);
void new_fast_launch_entity(const std::string& title, const std::string& icon_path, std::string&& exec_path);
private:
std::vector<UI::StackView*> m_grid_stackviews;
UI::StackView* m_dock_stackview {};
AppListView* m_applist_view {};
std::list<FastLaunchEntity> m_grid_entites {};
std::list<FastLaunchEntity> m_fast_launch_entites {};
};

View File

@@ -0,0 +1,40 @@
#pragma once
#include "HomeScreenView.h"
#include <libui/App.h>
#include <libui/Button.h>
#include <libui/Label.h>
#include <libui/StackView.h>
#include <libui/View.h>
#include <libui/ViewController.h>
#include <libui/Window.h>
#include <memory>
#include <sys/types.h>
class HomeScreenViewController : public UI::ViewController<HomeScreenView> {
public:
HomeScreenViewController(HomeScreenView& view)
: UI::ViewController<HomeScreenView>(view)
{
}
virtual ~HomeScreenViewController() = default;
void init_data()
{
view().new_fast_launch_entity("About", "/res/icons/apps/about.icon", "/Applications/about.app/Content/about"); // FIXME: Parse some init file
view().new_fast_launch_entity("Terminal", "/res/icons/apps/terminal.icon", "/Applications/terminal.app/Content/terminal");
view().new_fast_launch_entity("Calculator", "/res/icons/apps/calculator.icon", "/Applications/calculator.app/Content/calculator");
view().new_grid_entity("About", "/res/icons/apps/about.icon", "/Applications/about.app/Content/about"); // FIXME: Parse some init file
view().new_grid_entity("Terminal", "/res/icons/apps/terminal.icon", "/Applications/terminal.app/Content/terminal");
view().new_grid_entity("Monitor", "/res/icons/apps/activity_monitor.icon", "/Applications/activity_monitor.app/Content/activity_monitor");
view().new_grid_entity("Calculator", "/res/icons/apps/calculator.icon", "/Applications/calculator.app/Content/calculator");
}
virtual void view_did_load() override
{
view().set_background_color(LG::Color(255, 255, 255, 135));
init_data();
view().set_needs_display();
}
private:
};

View File

@@ -0,0 +1,34 @@
#pragma once
#include "HomeScreenView.h"
#include <libg/Size.h>
#include <libui/Window.h>
class HomeScreenWindow : public UI::Window {
public:
HomeScreenWindow(const LG::Size& size)
: UI::Window("Homescreen", size, UI::WindowType::Homescreen)
{
if (fork() == 0) {
for (int i = 3; i < 32; i++) {
close(i);
}
execlp("/System/applist", "/System/applist", NULL);
std::abort();
}
}
void receive_event(std::unique_ptr<LFoundation::Event> event) override
{
switch (event->type()) {
case UI::Event::Type::NotifyWindowCreateEvent: {
UI::NotifyWindowCreateEvent& own_event = *(UI::NotifyWindowCreateEvent*)event.get();
HomeScreenView* it = (HomeScreenView*)superview();
it->on_window_create(own_event.bundle_id(), own_event.icon_path(), own_event.window_id(), own_event.window_type());
break;
}
}
Window::receive_event(std::move(event));
}
};

View File

@@ -0,0 +1,19 @@
#include "IconView.h"
#include "HomeScreenView.h"
#include <libui/Context.h>
#include <libui/Label.h>
IconView::IconView(View* superview, const LG::Rect& frame)
: View(superview, frame)
{
m_label = &add_subview<UI::Label>(LG::Rect(0, HomeScreenView::icon_view_size() - 12, HomeScreenView::icon_view_size(), 12));
m_label->set_alignment(UI::Text::Alignment::Center);
}
void IconView::display(const LG::Rect& rect)
{
const int offset_x = (HomeScreenView::icon_view_size() - HomeScreenView::icon_size()) / 2;
LG::Context ctx = UI::graphics_current_context();
ctx.add_clip(rect);
ctx.draw({ offset_x, 0 }, m_launch_entity.icon());
}

View File

@@ -0,0 +1,45 @@
#pragma once
#include "FastLaunchEntity.h"
#include "HomeScreenEntity.h"
#include <libg/Font.h>
#include <libui/Label.h>
#include <libui/View.h>
#include <list>
#include <string>
#include <unistd.h>
class IconView : public UI::View {
UI_OBJECT();
public:
IconView(View* superview, const LG::Rect& frame);
void display(const LG::Rect& rect) override;
void mouse_up() override { launch(m_launch_entity.path_to_exec()); }
void set_title(const std::string& title)
{
if (!m_label) {
return;
}
m_label->set_text(title);
}
FastLaunchEntity& entity() { return m_launch_entity; }
const FastLaunchEntity& entity() const { return m_launch_entity; }
private:
void launch(const std::string& path_to_exec)
{
if (fork() == 0) {
for (int i = 3; i < 32; i++) {
close(i);
}
execlp(path_to_exec.c_str(), path_to_exec.c_str(), NULL);
std::abort();
}
}
UI::Label* m_label;
FastLaunchEntity m_launch_entity;
};