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,76 @@
#include "Window.h"
#include "../../Managers/WindowManager.h"
#include <utility>
namespace WinServer::Desktop {
Window::Window(int connection_id, int id, CreateWindowMessage& msg)
: BaseWindow(connection_id, id, msg)
, m_frame(*this)
{
m_bounds = LG::Rect(0, 0, msg.width() + frame().left_border_size() + frame().right_border_size(), msg.height() + frame().top_border_size() + frame().bottom_border_size());
m_content_bounds = LG::Rect(m_frame.left_border_size(), m_frame.top_border_size(), msg.width(), msg.height());
m_content_bitmap = LG::PixelBitmap(m_buffer.data(), content_bounds().width(), content_bounds().height());
// Creating standard menubar directory entry.
m_menubar_content.push_back(MenuDir(m_app_name, 0));
m_menubar_content[0].add_item(PopupItem { PopupItem::InternalId, "Minimize others", [this](int) { WindowManager::the().minimize_windows([this](Window* win) { return win != this; }); } });
m_menubar_content[0].add_item(PopupItem { PopupItem::InternalId, "Minimize", [this](int) { WindowManager::the().minimize_window(*this); } });
m_menubar_content[0].add_item(PopupItem { PopupItem::InternalId, "Close", [this](int) { WindowManager::the().close_window(*this); } });
}
Window::Window(Window&& win)
: BaseWindow(std::move(win))
, m_frame(*this, std::move(win.m_frame.control_panel_buttons()), std::move(win.m_frame.window_control_buttons()))
, m_corner_mask(std::move(win.m_corner_mask))
, m_menubar_content(std::move(win.m_menubar_content))
{
}
void Window::make_frame()
{
uint32_t x = m_bounds.min_x();
uint32_t y = m_bounds.min_y();
uint32_t content_width = m_content_bounds.width();
uint32_t content_height = m_content_bounds.height();
m_bounds = LG::Rect(x, y, content_width + frame().left_border_size() + frame().right_border_size(), content_height + frame().top_border_size() + frame().bottom_border_size());
m_content_bounds = LG::Rect(x + m_frame.left_border_size(), y + m_frame.top_border_size(), content_width, content_height);
m_frame.set_visible(true);
}
void Window::make_frameless()
{
uint32_t x = m_bounds.min_x();
uint32_t y = m_bounds.min_y();
uint32_t content_width = m_content_bounds.width();
uint32_t content_height = m_content_bounds.height();
m_bounds = LG::Rect(x, y, content_width, content_height);
m_content_bounds = LG::Rect(x, y, content_width, content_height);
m_frame.set_visible(false);
}
void Window::recalc_bounds(const LG::Size& size)
{
m_content_bounds.set_width(size.width());
m_content_bounds.set_height(size.height());
m_bounds.set_width(size.width() + frame().left_border_size() + frame().right_border_size());
m_bounds.set_height(size.height() + frame().top_border_size() + frame().bottom_border_size());
}
void Window::did_size_change(const LG::Size& size)
{
recalc_bounds(size);
}
void Window::on_style_change()
{
WindowManager::the().on_window_style_change(*this);
}
void Window::on_menubar_change()
{
WindowManager::the().on_window_menubar_change(*this);
}
} // namespace WinServer

View File

@@ -0,0 +1,47 @@
#pragma once
#include "../../Components/Base/BaseWindow.h"
#include "../../Components/MenuBar/MenuItem.h"
#include "../../IPC/Connection.h"
#include "WindowFrame.h"
#include <libfoundation/SharedBuffer.h>
#include <libg/PixelBitmap.h>
#include <libg/Rect.h>
#include <sys/types.h>
#include <utility>
namespace WinServer::Desktop {
class Window : public BaseWindow {
public:
Window(int connection_id, int id, CreateWindowMessage& msg);
Window(Window&& win);
inline WindowFrame& frame() { return m_frame; }
inline const WindowFrame& frame() const { return m_frame; }
inline const LG::CornerMask& corner_mask() const { return m_corner_mask; }
inline std::vector<MenuDir>& menubar_content() { return m_menubar_content; }
inline const std::vector<MenuDir>& menubar_content() const { return m_menubar_content; }
void on_menubar_change();
virtual void did_app_title_change() override { m_frame.on_set_app_title(); }
virtual void did_icon_path_change() override { m_frame.on_set_icon(); }
virtual void did_size_change(const LG::Size& size) override;
inline void set_style(StatusBarStyle style) { m_frame.set_style(style), on_style_change(); }
void make_frame();
void make_frameless();
private:
void recalc_bounds(const LG::Size& size);
void on_style_change();
WindowFrame m_frame;
LG::CornerMask m_corner_mask { LG::CornerMask::SystemRadius, LG::CornerMask::NonMasked, LG::CornerMask::Masked };
std::vector<MenuDir> m_menubar_content;
};
} // namespace WinServer

View File

@@ -0,0 +1,232 @@
#include "WindowFrame.h"
#include "../../Components/Elements/Button.h"
#include "../../Managers/WindowManager.h"
#include "Window.h"
#include <libg/Font.h>
#include <libg/ImageLoaders/PNGLoader.h>
#include <libg/Rect.h>
#include <utility>
#define CONTROL_PANEL_CLOSE 0x0
#define CONTROL_PANEL_MAXIMIZE 0x1
#define CONTROL_PANEL_MINIMIZE 0x2
namespace WinServer::Desktop {
static const uint32_t s_close_button_glyph_data[10] = {
0b1100000011,
0b1110000111,
0b0111001110,
0b0011111100,
0b0001111000,
0b0001111000,
0b0011111100,
0b0111001110,
0b1110000111,
0b1100000011,
};
static const uint32_t s_maximise_button_glyph_data[10] = {
0b1111100000,
0b1111000000,
0b1110000000,
0b1100000000,
0b1000000000,
0b0000000001,
0b0000000011,
0b0000000111,
0b0000001111,
0b0000011111
};
static const uint32_t s_minimise_button_glyph_data[10] = {
0b0000000000,
0b0000000000,
0b0000000000,
0b0000000000,
0b0000000000,
0b0000000000,
0b0000000000,
0b0000000000,
0b1111111111,
0b1111111111
};
WindowFrame::WindowFrame(Window& window)
: m_window(window)
, m_window_control_buttons()
, m_control_panel_buttons()
{
set_style(StatusBarStyle::StandardLight);
LG::GlyphMetrics metrics = {
.width = 10,
.height = 10,
.top_bearing = 10,
.left_bearing = 0,
.baseline = 0,
.advance = 10,
.font_size = 10
};
auto* close = new Button();
close->set_icon(LG::Glyph(s_close_button_glyph_data, metrics, LG::Glyph::ConstDataMarker {}));
auto* maximize = new Button();
maximize->set_icon(LG::Glyph(s_maximise_button_glyph_data, metrics, LG::Glyph::ConstDataMarker {}));
auto* minimize = new Button();
minimize->set_icon(LG::Glyph(s_minimise_button_glyph_data, metrics, LG::Glyph::ConstDataMarker {}));
close->set_title_color(LG::Color(196, 128, 128));
m_window_control_buttons.push_back(close);
m_window_control_buttons.push_back(maximize);
m_window_control_buttons.push_back(minimize);
}
WindowFrame::WindowFrame(Window& window, std::vector<Button*>&& control_panel_buttons, std::vector<Button*>&& window_control_buttons)
: m_window(window)
, m_window_control_buttons(std::move(window_control_buttons))
, m_control_panel_buttons(std::move(control_panel_buttons))
{
}
void WindowFrame::on_set_app_title()
{
m_app_title_width = Helpers::text_width(m_window.app_title(), LG::Font::system_font());
if (style().show_text()) {
WinServer::Compositor::the().invalidate(bounds());
}
}
void WindowFrame::add_control(const std::string& title)
{
auto* new_control = new Button();
new_control->set_title(title);
m_control_panel_buttons.push_back(new_control);
WinServer::Compositor::the().invalidate(bounds());
}
void WindowFrame::draw(LG::Context& ctx)
{
if (!visible()) {
return;
}
int x = m_window.bounds().min_x();
int y = m_window.bounds().min_y();
size_t width = m_window.bounds().width();
size_t height = m_window.bounds().height();
int left_x = x + left_border_size();
int right_x = x + width - right_border_size();
int bottom_y = y + height - bottom_border_size();
// Drawing frame and shadings
int shadow_spread = LG::Shading::SystemSpread;
ctx.set_fill_color(style().color());
ctx.fill_rounded(LG::Rect(x + left_border_size(), y + std_top_border_frame_size(), width - 2 * left_border_size(), top_border_size() - std_top_border_frame_size()), LG::CornerMask(4, true, false));
ctx.set_fill_color(Color::Shadow);
const auto shading_rect = LG::Rect(x + left_border_size(), y + std_top_border_frame_size(), width - 2 * left_border_size(), height - std_top_border_frame_size() - std_bottom_border_size());
ctx.draw_box_shading(shading_rect, LG::Shading(LG::Shading::Type::Box, 0, shadow_spread), LG::CornerMask(LG::CornerMask::SystemRadius));
// Drawing labels, icons.
// Drawing positions are calculated using a start of the frame.
ctx.set_fill_color(m_text_colors[(int)active()]);
if (style().show_text()) {
Helpers::draw_text(ctx, { left_x + spacing(), y + text_y_offset() }, m_window.app_title(), LG::Font::system_font());
}
int start_controls_offset = m_app_title_width + 2 * spacing();
int start_controls = left_x + start_controls_offset;
for (int i = 0; i < m_control_panel_buttons.size(); i++) {
m_control_panel_buttons[i]->display(ctx, { start_controls, y + text_y_offset() });
start_controls += spacing() + m_control_panel_buttons[i]->bounds().width();
}
int start_buttons = right_x - spacing() - m_window_control_buttons[0]->bounds().width();
for (int i = 0; i < m_window_control_buttons.size(); i++) {
if (active() && i == 0) {
ctx.set_fill_color(m_window_control_buttons[i]->title_color());
} else {
ctx.set_fill_color(m_text_colors[(int)active()]);
}
m_window_control_buttons[i]->display(ctx, { start_buttons, y + button_y_offset() });
start_buttons += -spacing() - m_window_control_buttons[i]->bounds().width();
}
}
void WindowFrame::invalidate(WinServer::Compositor& compositor) const
{
if (!visible()) {
return;
}
int x = m_window.bounds().min_x();
int y = m_window.bounds().min_y();
size_t width = m_window.bounds().width();
size_t height = m_window.bounds().height();
int right_x = x + width - right_border_size();
int bottom_y = y + height - bottom_border_size();
compositor.invalidate(LG::Rect(x, y, width, top_border_size()));
compositor.invalidate(LG::Rect(x, y, left_border_size(), height));
compositor.invalidate(LG::Rect(right_x, y, right_border_size(), height));
compositor.invalidate(LG::Rect(x, bottom_y, width, bottom_border_size()));
}
void WindowFrame::receive_tap_event(const LG::Point<int>& tap)
{
// Calculating buttons' positions
size_t width = m_window.bounds().width();
int right_x = width - right_border_size();
int start_buttons = right_x - spacing() - m_window_control_buttons[0]->bounds().width();
for (int button_id = 0; button_id < m_window_control_buttons.size(); button_id++) {
auto button_frame = m_window_control_buttons[button_id]->bounds();
button_frame.offset_by(start_buttons, button_y_offset());
if (button_frame.contains(tap)) {
handle_control_panel_tap(button_id);
return;
}
start_buttons += -spacing() - button_frame.width();
}
}
const LG::Rect WindowFrame::bounds() const
{
const auto& bounds = m_window.bounds();
return LG::Rect(bounds.min_x(), bounds.min_y(), bounds.width(), top_border_size());
}
void WindowFrame::handle_control_panel_tap(int button_id)
{
auto& wm = WindowManager::the();
switch (button_id) {
case CONTROL_PANEL_CLOSE:
wm.close_window(m_window);
break;
case CONTROL_PANEL_MAXIMIZE:
wm.maximize_window(m_window);
break;
case CONTROL_PANEL_MINIMIZE:
wm.minimize_window(m_window);
break;
default:
break;
}
}
void WindowFrame::set_style(StatusBarStyle ts)
{
m_style = ts;
if (m_style.dark_text()) {
m_text_colors[0] = Color::InactiveText;
m_text_colors[1] = LG::Color::DarkSystemText;
} else {
m_text_colors[0] = Color::InactiveText;
m_text_colors[1] = LG::Color::LightSystemText;
}
}
void WindowFrame::on_set_icon()
{
}
} // namespace WinServer

View File

@@ -0,0 +1,87 @@
#pragma once
#include "../../Components/Elements/Button.h"
#include "../../Constants/Colors.h"
#include "../../IPC/Event.h"
#include <libapi/window_server/MessageContent/MenuBar.h>
#include <libfoundation/EventReceiver.h>
#include <libg/Context.h>
#include <libg/PixelBitmap.h>
namespace WinServer {
class Compositor;
}
namespace WinServer::Desktop {
class Window;
class WindowFrame {
public:
explicit WindowFrame(Window& window);
WindowFrame(Window& window, std::vector<Button*>&& control_panel_buttons, std::vector<Button*>&& window_control_buttons);
~WindowFrame() = default;
void draw(LG::Context&);
static constexpr size_t std_app_header_size() { return 26; }
static constexpr size_t std_top_border_frame_size() { return 4; }
static constexpr size_t std_top_border_size() { return std_top_border_frame_size() + std_app_header_size(); }
static constexpr size_t std_bottom_border_size() { return 4; }
static constexpr size_t std_left_border_size() { return 4; }
static constexpr size_t std_right_border_size() { return 4; }
inline size_t top_border_size() const { return m_top_border_size; }
inline size_t bottom_border_size() const { return std_bottom_border_size(); }
inline size_t left_border_size() const { return std_left_border_size(); }
inline size_t right_border_size() const { return std_right_border_size(); }
const LG::Rect bounds() const;
void receive_tap_event(const LG::Point<int>& tap);
void on_set_app_title();
void add_control(const std::string& title);
inline std::vector<Button*>& window_control_buttons() { return m_window_control_buttons; }
inline const std::vector<Button*>& window_control_buttons() const { return m_window_control_buttons; }
inline std::vector<Button*>& control_panel_buttons() { return m_control_panel_buttons; }
inline const std::vector<Button*>& control_panel_buttons() const { return m_control_panel_buttons; }
void handle_control_panel_tap(int button_id);
inline StatusBarStyle style() const { return m_style; }
void set_style(StatusBarStyle ts);
void set_visible(bool visible)
{
m_top_border_size = visible ? std_top_border_size() : 0;
m_visible = visible;
}
bool visible() const { return m_visible; }
void set_active(bool active) { m_active = active; }
bool active() const { return m_active; }
void invalidate(WinServer::Compositor& compositor) const;
void on_set_icon();
static constexpr int spacing() { return 8; }
static constexpr int icon_width() { return 12; }
static constexpr int icon_y_offset() { return 7 + std_top_border_frame_size(); }
static constexpr int text_y_offset() { return 9 + std_top_border_frame_size(); }
static constexpr int button_y_offset() { return 8 + std_top_border_frame_size(); }
private:
Window& m_window;
std::vector<Button*> m_window_control_buttons;
std::vector<Button*> m_control_panel_buttons;
LG::Color m_text_colors[2];
LG::Color m_color { LG::Color::LightSystemBackground };
size_t m_top_border_size { std_top_border_size() };
size_t m_app_title_width { 0 };
bool m_visible { true };
bool m_active { true };
StatusBarStyle m_style;
};
} // namespace WinServer

View File

@@ -0,0 +1,14 @@
#pragma once
#include "../Desktop/Window.h"
#include "../Mobile/Window.h"
namespace WinServer {
#ifdef TARGET_DESKTOP
using Window = Desktop::Window;
#elif TARGET_MOBILE
using Window = Mobile::Window;
#endif
} // namespace WinServer

View File

@@ -0,0 +1,25 @@
#include "Window.h"
#include "../../Managers/WindowManager.h"
#include <utility>
namespace WinServer::Mobile {
Window::Window(int connection_id, int id, CreateWindowMessage& msg)
: BaseWindow(connection_id, id, msg)
{
m_bounds = LG::Rect(0, 0, msg.width(), msg.height());
m_content_bounds = LG::Rect(0, 0, msg.width(), msg.height());
m_content_bitmap = LG::PixelBitmap(m_buffer.data(), content_bounds().width(), content_bounds().height());
}
Window::Window(Window&& win)
: BaseWindow(std::move(win))
{
}
void Window::on_style_change()
{
WindowManager::the().on_window_style_change(*this);
}
} // namespace WinServer

View File

@@ -0,0 +1,27 @@
#pragma once
#include "../../Components/Base/BaseWindow.h"
#include "../../Components/MenuBar/MenuItem.h"
#include "../../IPC/Connection.h"
#include <libfoundation/SharedBuffer.h>
#include <libg/PixelBitmap.h>
#include <libg/Rect.h>
#include <sys/types.h>
#include <utility>
namespace WinServer::Mobile {
class Window : public BaseWindow {
public:
Window(int connection_id, int id, CreateWindowMessage& msg);
Window(Window&& win);
inline void set_style(StatusBarStyle ts) { m_style = ts, on_style_change(); }
inline StatusBarStyle style() { return m_style; }
private:
void on_style_change();
StatusBarStyle m_style { StatusBarStyle::StandardLight };
};
} // namespace WinServer