opuntiaOS - an operating system targeting x86 and ARMv7
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

[userland][system] Init of AppList

+432 -4
+1
build/userland/BUILD.gn
··· 96 96 "//userland/applications/calculator:calculator", 97 97 "//userland/applications/terminal:terminal", 98 98 "//userland/shell/onesh:onesh", 99 + "//userland/system/applist:applist", 99 100 "//userland/system/dock:dock", 100 101 "//userland/system/homescreen:homescreen", 101 102 "//userland/system/init:init",
+2
build/userland/TEMPLATE.gni
··· 21 21 "asmflags", 22 22 "ldflags", 23 23 "public_deps", 24 + "include_dirs", 24 25 ]) 25 26 } 26 27 ··· 59 60 "asmflags", 60 61 "ldflags", 61 62 "public_deps", 63 + "include_dirs", 62 64 ]) 63 65 } 64 66
+24
userland/system/applist/AppDelegate.cpp
··· 1 + #include "AppListView.h" 2 + #include "AppListViewController.h" 3 + #include "AppListWindow.h" 4 + #include <libui/AppDelegate.h> 5 + 6 + class AppDelegate : public UI::AppDelegate { 7 + public: 8 + AppDelegate() = default; 9 + virtual ~AppDelegate() = default; 10 + 11 + LG::Size preferred_desktop_window_size() const override { return LG::Size(400, 300); } 12 + 13 + bool application() override 14 + { 15 + auto& window = std::opuntiaos::construct<AppListWindow>(); 16 + window.set_bitmap_format(LG::PixelBitmapFormat::RGBA); 17 + auto& dock_view = window.create_superview<AppListView, AppListViewController>(); 18 + return true; 19 + } 20 + 21 + private: 22 + }; 23 + 24 + SET_APP_DELEGATE(AppDelegate);
+64
userland/system/applist/AppListView.cpp
··· 1 + #include "AppListView.h" 2 + #include "IconView.h" 3 + #include <algorithm> 4 + #include <cstdlib> 5 + #include <libfoundation/EventLoop.h> 6 + #include <libfoundation/KeyboardMapping.h> 7 + #include <libg/Color.h> 8 + #include <libg/ImageLoaders/PNGLoader.h> 9 + #include <libui/App.h> 10 + #include <libui/Context.h> 11 + #include <unistd.h> 12 + 13 + static AppListView* this_view; 14 + 15 + AppListView::AppListView(UI::View* superview, const LG::Rect& frame) 16 + : UI::View(superview, frame) 17 + { 18 + auto& dock_stack_view = add_subview<UI::StackView>(bounds()); 19 + dock_stack_view.set_spacing(padding()); 20 + dock_stack_view.set_background_color(LG::Color::Opaque); 21 + dock_stack_view.set_axis(UI::LayoutConstraints::Axis::Horizontal); 22 + dock_stack_view.set_distribution(UI::StackView::Distribution::EqualCentering); 23 + m_dock_stackview = &dock_stack_view; 24 + } 25 + 26 + AppListView::AppListView(UI::View* superview, UI::Window* window, const LG::Rect& frame) 27 + : UI::View(superview, window, frame) 28 + { 29 + auto& label = add_subview<UI::Label>(LG::Rect(16, 16, 16, 24)); 30 + label.set_text_color(LG::Color::DarkSystemText); 31 + label.set_text("App List"); 32 + label.set_font(LG::Font::system_font(LG::Font::SystemTitleSize)); 33 + label.set_width(label.preferred_width()); 34 + 35 + auto& dock_stack_view = add_subview<UI::StackView>(LG::Rect(0, 50, bounds().width(), bounds().height())); 36 + dock_stack_view.set_spacing(padding()); 37 + dock_stack_view.set_background_color(LG::Color::Opaque); 38 + dock_stack_view.set_axis(UI::LayoutConstraints::Axis::Horizontal); 39 + dock_stack_view.set_distribution(UI::StackView::Distribution::EqualCentering); 40 + m_dock_stackview = &dock_stack_view; 41 + } 42 + 43 + void AppListView::display(const LG::Rect& rect) 44 + { 45 + LG::Context ctx = UI::graphics_current_context(); 46 + ctx.add_clip(rect); 47 + 48 + ctx.set_fill_color(background_color()); 49 + ctx.fill_rounded(bounds(), layer().corner_mask()); 50 + } 51 + 52 + void AppListView::new_dock_entity(const std::string& exec_path, const std::string& icon_path, const std::string& bundle_id) 53 + { 54 + LG::PNG::PNGLoader loader; 55 + 56 + auto& icon_view = m_dock_stackview->add_arranged_subview<IconView>(); 57 + icon_view.add_constraint(UI::Constraint(icon_view, UI::Constraint::Attribute::Height, UI::Constraint::Relation::Equal, icon_view_size())); 58 + icon_view.add_constraint(UI::Constraint(icon_view, UI::Constraint::Attribute::Width, UI::Constraint::Relation::Equal, icon_view_size())); 59 + icon_view.entity().set_icon(loader.load_from_file(icon_path + "/48x48.png")); 60 + icon_view.entity().set_path_to_exec(std::move(exec_path)); 61 + icon_view.entity().set_bundle_id(std::move(bundle_id)); 62 + m_icon_views.push_back(&icon_view); 63 + set_needs_layout(); 64 + }
+32
userland/system/applist/AppListView.h
··· 1 + #pragma once 2 + #include "DockEntity.h" 3 + #include "IconView.h" 4 + #include "WindowEntity.h" 5 + #include <libg/Font.h> 6 + #include <libui/StackView.h> 7 + #include <libui/View.h> 8 + #include <list> 9 + #include <string> 10 + 11 + class AppListView : public UI::View { 12 + UI_OBJECT(); 13 + 14 + public: 15 + AppListView(UI::View* superview, const LG::Rect& frame); 16 + AppListView(UI::View* superview, UI::Window* window, const LG::Rect& frame); 17 + 18 + static constexpr size_t padding() { return 0; } 19 + static constexpr size_t dock_view_height() { return 46; } 20 + static constexpr int icon_size() { return 48; } 21 + static constexpr int icon_view_size() { return (int)60; } 22 + 23 + void display(const LG::Rect& rect) override; 24 + 25 + void new_dock_entity(const std::string& exec_path, const std::string& icon_path, const std::string& bundle_id); 26 + 27 + private: 28 + void launch(const DockEntity& ent); 29 + 30 + UI::StackView* m_dock_stackview {}; 31 + std::list<IconView*> m_icon_views {}; 32 + };
+40
userland/system/applist/AppListViewController.h
··· 1 + /* 2 + * Copyright (C) 2020-2021 The opuntiaOS Project Authors. 3 + * + Contributed by Nikita Melekhin <nimelehin@gmail.com> 4 + * 5 + * Use of this source code is governed by a BSD-style license that can be 6 + * found in the LICENSE file. 7 + */ 8 + 9 + #pragma once 10 + #include "AppListView.h" 11 + #include <libui/App.h> 12 + #include <libui/Button.h> 13 + #include <libui/Label.h> 14 + #include <libui/View.h> 15 + #include <libui/ViewController.h> 16 + #include <libui/Window.h> 17 + #include <memory> 18 + #include <sys/types.h> 19 + 20 + class AppListViewController : public UI::ViewController<AppListView> { 21 + public: 22 + AppListViewController(AppListView& view) 23 + : UI::ViewController<AppListView>(view) 24 + { 25 + } 26 + virtual ~AppListViewController() = default; 27 + 28 + virtual void view_did_load() override 29 + { 30 + view().set_background_color(LG::Color::LightSystemWhiteOpaque); 31 + view().layer().set_corner_mask(LG::CornerMask(4, LG::CornerMask::Masked, LG::CornerMask::NonMasked)); 32 + view().new_dock_entity("/Applications/about.app/Content/about", "/res/icons/apps/about.icon", "com.opuntia.about"); 33 + view().new_dock_entity("/Applications/terminal.app/Content/terminal", "/res/icons/apps/terminal.icon", "com.opuntia.terminal"); 34 + view().new_dock_entity("/Applications/activity_monitor.app/Content/activity_monitor", "/res/icons/apps/activity_monitor.icon", "com.opuntia.activity_monitor"); 35 + view().new_dock_entity("/Applications/calculator.app/Content/calculator", "/res/icons/apps/calculator.icon", "com.opuntia.calculator"); 36 + view().set_needs_display(); 37 + } 38 + 39 + private: 40 + };
+7
userland/system/applist/AppListWindow.cpp
··· 1 + #include "AppListWindow.h" 2 + #include "AppListView.h" 3 + 4 + void AppListWindow::receive_event(std::unique_ptr<LFoundation::Event> event) 5 + { 6 + Window::receive_event(std::move(event)); 7 + }
+15
userland/system/applist/AppListWindow.h
··· 1 + #pragma once 2 + 3 + #include <libg/Size.h> 4 + #include <libui/Screen.h> 5 + #include <libui/Window.h> 6 + 7 + class AppListWindow : public UI::Window { 8 + public: 9 + AppListWindow() 10 + : UI::Window("AppList", LG::Size(320, 400), UI::WindowType::AppList) 11 + { 12 + } 13 + 14 + void receive_event(std::unique_ptr<LFoundation::Event> event) override; 15 + };
+18
userland/system/applist/BUILD.gn
··· 1 + import("//build/userland/TEMPLATE.gni") 2 + 3 + opuntiaOS_executable("applist") { 4 + install_path = "System/" 5 + sources = [ 6 + "AppDelegate.cpp", 7 + "AppListView.cpp", 8 + "AppListWindow.cpp", 9 + "IconView.cpp", 10 + ] 11 + configs = [ "//build/userland:userland_flags" ] 12 + deplibs = [ 13 + "libcxx", 14 + "libfoundation", 15 + "libg", 16 + "libui", 17 + ] 18 + }
+29
userland/system/applist/DockEntity.h
··· 1 + #pragma once 2 + #include "WindowEntity.h" 3 + #include <libg/PixelBitmap.h> 4 + #include <list> 5 + #include <string> 6 + 7 + class DockEntity { 8 + public: 9 + DockEntity() = default; 10 + 11 + void set_icon(LG::PixelBitmap&& icon) { m_icon = std::move(icon); } 12 + const LG::PixelBitmap& icon() const { return m_icon; } 13 + 14 + void set_path_to_exec(const std::string& path) { m_path_to_exec = path; } 15 + const std::string& path_to_exec() const { return m_path_to_exec; } 16 + 17 + void set_bundle_id(const std::string& bid) { m_bundle_id = bid; } 18 + const std::string& bundle_id() const { return m_bundle_id; } 19 + 20 + void add_window(const WindowEntity& went) { m_windows.push_front(went); } 21 + const std::list<WindowEntity>& windows() const { return m_windows; } 22 + std::list<WindowEntity>& windows() { return m_windows; } 23 + 24 + private: 25 + LG::PixelBitmap m_icon; 26 + std::string m_path_to_exec {}; 27 + std::string m_bundle_id {}; 28 + std::list<WindowEntity> m_windows {}; 29 + };
+72
userland/system/applist/IconView.cpp
··· 1 + #include "IconView.h" 2 + #include "AppListView.h" 3 + #include <libui/App.h> 4 + #include <libui/Context.h> 5 + #include <libui/Label.h> 6 + #include <libui/Screen.h> 7 + #include <libui/Window.h> 8 + 9 + IconView::IconView(View* superview, const LG::Rect& frame) 10 + : View(superview, frame) 11 + { 12 + } 13 + 14 + void IconView::display(const LG::Rect& rect) 15 + { 16 + const int padding = 4; 17 + const int offset_x = (AppListView::icon_view_size() - AppListView::icon_size()) / 2; 18 + const int offset_y = (AppListView::icon_view_size() - AppListView::icon_size()) / 2; 19 + LG::Context ctx = UI::graphics_current_context(); 20 + ctx.add_clip(rect); 21 + 22 + if (is_hovered()) { 23 + auto rect = LG::Rect(padding, padding, AppListView::icon_view_size() - 2 * padding, AppListView::icon_view_size() - 2 * padding); 24 + ctx.set_fill_color(LG::Color::White); 25 + ctx.fill_rounded(rect, LG::CornerMask(6)); 26 + ctx.set_fill_color(LG::Color(120, 129, 133, 60)); 27 + ctx.draw_box_shading(rect, LG::Shading(LG::Shading::Type::Box, 0, 2), LG::CornerMask(6)); 28 + } 29 + 30 + ctx.draw({ offset_x, offset_y }, m_launch_entity.icon()); 31 + 32 + ctx.set_fill_color(LG::Color(120, 129, 133)); 33 + const int underline_y = AppListView::icon_view_size() - underline_height() - padding; 34 + if (entity().windows().size() > 1) { 35 + const int len = 10; 36 + ctx.fill({ (AppListView::icon_view_size() - len) / 2, underline_y, len - underline_height(), underline_height() }); 37 + ctx.fill({ (AppListView::icon_view_size() - len) / 2 + len, underline_y, underline_height(), underline_height() }); 38 + } else if (entity().windows().size() > 0) { 39 + const int len = 10; 40 + ctx.fill({ (AppListView::icon_view_size() - len) / 2, underline_y, len, underline_height() }); 41 + } 42 + } 43 + 44 + void IconView::on_click() 45 + { 46 + if (entity().windows().size() == 0) { 47 + launch(); 48 + return; 49 + } else { 50 + auto demo_menu = UI::Menu(); 51 + for (auto& win : entity().windows()) { 52 + auto title = win.title(); 53 + int this_window_id = window()->id(); 54 + int target_window_id = win.window_id(); 55 + 56 + if (win.is_minimized()) { 57 + title += " - minimized"; 58 + } 59 + 60 + demo_menu.add_item(UI::MenuItem(title, [this, this_window_id, target_window_id] { 61 + auto& app = UI::App::the(); 62 + AskBringToFrontMessage msg(app.connection().key(), this_window_id, target_window_id); 63 + // this->entity().set_minimized(false); 64 + app.connection().send_async_message(msg); 65 + })); 66 + } 67 + demo_menu.add_item(UI::MenuItem("New window", [this] { 68 + launch(); 69 + })); 70 + window()->popup_manager().show({ frame().min_x(), (int)UI::Screen::main().bounds().height() - (int)AppListView::dock_view_height() - 4 }, demo_menu); 71 + } 72 + }
+46
userland/system/applist/IconView.h
··· 1 + #pragma once 2 + #include "DockEntity.h" 3 + #include "WindowEntity.h" 4 + #include <libg/Font.h> 5 + #include <libui/Label.h> 6 + #include <libui/PopupMenu.h> 7 + #include <libui/View.h> 8 + #include <list> 9 + #include <string> 10 + #include <unistd.h> 11 + 12 + class IconView : public UI::View { 13 + UI_OBJECT(); 14 + 15 + public: 16 + IconView(View* superview, const LG::Rect& frame); 17 + 18 + void display(const LG::Rect& rect) override; 19 + void mouse_down(const LG::Point<int>& location) override { on_click(); } 20 + 21 + static constexpr size_t underline_height() { return 3; } 22 + 23 + void set_title(const std::string& title) 24 + { 25 + if (!m_label) { 26 + return; 27 + } 28 + m_label->set_text(title); 29 + } 30 + 31 + DockEntity& entity() { return m_launch_entity; } 32 + const DockEntity& entity() const { return m_launch_entity; } 33 + 34 + private: 35 + void on_click(); 36 + void launch() 37 + { 38 + if (fork() == 0) { 39 + execve(m_launch_entity.path_to_exec().c_str(), 0, 0); 40 + std::abort(); 41 + } 42 + } 43 + 44 + UI::Label* m_label; 45 + DockEntity m_launch_entity; 46 + };
+43
userland/system/applist/WindowEntity.h
··· 1 + #pragma once 2 + #include <libg/PixelBitmap.h> 3 + #include <string> 4 + 5 + class WindowEntity { 6 + public: 7 + enum Status : uint32_t { 8 + Minimized = (1 << 0), 9 + }; 10 + 11 + WindowEntity() 12 + : m_window_id(0) 13 + , m_title() 14 + { 15 + } 16 + 17 + WindowEntity(int window_id) 18 + : m_window_id(window_id) 19 + , m_title() 20 + { 21 + } 22 + 23 + bool operator==(const WindowEntity& other) const { return m_window_id == other.m_window_id; } 24 + bool operator!=(const WindowEntity& other) const { return m_window_id != other.m_window_id; } 25 + 26 + int window_id() const { return m_window_id; } 27 + 28 + bool is_minimized() const { return has_attr(Status::Minimized); } 29 + void set_minimized(bool b) { b ? set_attr(Status::Minimized) : rem_attr(Status::Minimized); } 30 + 31 + const std::string& title() const { return m_title; } 32 + void set_title(const std::string& title) { m_title = title; } 33 + void set_title(std::string&& title) { m_title = std::move(title); } 34 + 35 + private: 36 + inline bool has_attr(Status mode) const { return ((m_window_status & (uint32_t)mode) == (uint32_t)mode); } 37 + inline void set_attr(Status mode) { m_window_status |= (uint32_t)mode; } 38 + inline void rem_attr(Status mode) { m_window_status = m_window_status & (~(uint32_t)mode); } 39 + 40 + int m_window_id { 0 }; 41 + uint32_t m_window_status { 0 }; 42 + std::string m_title {}; 43 + };
+14
userland/system/dock/AppListView.cpp
··· 31 31 } 32 32 33 33 ctx.draw({ offset_x, offset_y }, m_icon); 34 + } 35 + 36 + void AppListView::on_click() 37 + { 38 + int this_window_id = window()->id(); 39 + 40 + if (m_target_window_id == INVALID) { 41 + return; 42 + } 43 + 44 + auto& app = UI::App::the(); 45 + AskBringToFrontMessage msg(app.connection().key(), this_window_id, m_target_window_id); 46 + // this->entity().set_minimized(false); 47 + app.connection().send_async_message(msg); 34 48 }
+8 -1
userland/system/dock/AppListView.h
··· 12 12 class AppListView : public UI::View { 13 13 UI_OBJECT(); 14 14 15 + static constexpr int INVALID = -1; 16 + 15 17 public: 16 18 AppListView(View* superview, const LG::Rect& frame); 17 19 20 + void set_target_window_id(int winid) { m_target_window_id = winid; } 21 + 18 22 void display(const LG::Rect& rect) override; 19 - void mouse_down(const LG::Point<int>& location) override { } 23 + void mouse_down(const LG::Point<int>& location) override { on_click(); } 20 24 21 25 private: 26 + void on_click(); 27 + 28 + int m_target_window_id { INVALID }; 22 29 LG::PixelBitmap m_icon; 23 30 };
+9 -1
userland/system/dock/DockView.cpp
··· 42 42 auto& icon_view = m_dock_stackview->add_arranged_subview<AppListView>(); 43 43 icon_view.add_constraint(UI::Constraint(icon_view, UI::Constraint::Attribute::Height, UI::Constraint::Relation::Equal, icon_view_size())); 44 44 icon_view.add_constraint(UI::Constraint(icon_view, UI::Constraint::Attribute::Width, UI::Constraint::Relation::Equal, icon_view_size())); 45 + m_applist_view = &icon_view; 45 46 } 46 47 47 48 void DockView::display(const LG::Rect& rect) ··· 79 80 return nullptr; 80 81 } 81 82 82 - void DockView::on_window_create(const std::string& bundle_id, const std::string& icon_path, int window_id) 83 + void DockView::on_window_create(const std::string& bundle_id, const std::string& icon_path, int window_id, int window_type) 83 84 { 84 85 // Don't add an icon of dock (self). 85 86 if (window()->id() == window_id) { 87 + return; 88 + } 89 + 90 + if (window_type == WindowType::AppList) { 91 + if (m_applist_view) { 92 + m_applist_view->set_target_window_id(window_id); 93 + } 86 94 return; 87 95 } 88 96
+3 -1
userland/system/dock/DockView.h
··· 1 1 #pragma once 2 + #include "AppListView.h" 2 3 #include "DockEntity.h" 3 4 #include "IconView.h" 4 5 #include "WindowEntity.h" ··· 23 24 void display(const LG::Rect& rect) override; 24 25 25 26 WindowEntity* find_window_entry(int window_id); 26 - void on_window_create(const std::string& bundle_id, const std::string& icon_path, int window_id); 27 + void on_window_create(const std::string& bundle_id, const std::string& icon_path, int window_id, int window_type); 27 28 void on_window_remove(int window_id); 28 29 void on_window_minimize(int window_id); 29 30 void set_icon(int window_id, const std::string& path); ··· 37 38 void launch(const DockEntity& ent); 38 39 39 40 UI::StackView* m_dock_stackview {}; 41 + AppListView* m_applist_view {}; 40 42 std::list<IconView*> m_icon_views {}; 41 43 };
+1 -1
userland/system/dock/DockWindow.cpp
··· 6 6 if (event->type() == UI::Event::Type::NotifyWindowCreateEvent) { 7 7 UI::NotifyWindowCreateEvent& own_event = *(UI::NotifyWindowCreateEvent*)event.get(); 8 8 DockView* it = (DockView*)superview(); 9 - it->on_window_create(own_event.bundle_id(), own_event.icon_path(), own_event.window_id()); 9 + it->on_window_create(own_event.bundle_id(), own_event.icon_path(), own_event.window_id(), own_event.window_type()); 10 10 } 11 11 if (event->type() == UI::Event::Type::NotifyWindowStatusChangedEvent) { 12 12 UI::NotifyWindowStatusChangedEvent& own_event = *(UI::NotifyWindowStatusChangedEvent*)event.get();
+4
userland/system/dock/DockWindow.h
··· 9 9 DockWindow() 10 10 : UI::Window("Dock", LG::Size(UI::Screen::main().bounds().width(), 46), UI::WindowType::Homescreen) 11 11 { 12 + if (fork() == 0) { 13 + execve("/System/applist", 0, 0); 14 + std::abort(); 15 + } 12 16 } 13 17 14 18 void receive_event(std::unique_ptr<LFoundation::Event> event) override;