forked from Bananymous/banan-os
				
			
		
			
				
	
	
		
			120 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
| #pragma once
 | |
| 
 | |
| #include "Utils.h"
 | |
| 
 | |
| #include <BAN/RefPtr.h>
 | |
| #include <BAN/String.h>
 | |
| #include <BAN/Vector.h>
 | |
| 
 | |
| #include <LibFont/Font.h>
 | |
| #include <LibGUI/Window.h>
 | |
| 
 | |
| class Window : public BAN::RefCounted<Window>
 | |
| {
 | |
| public:
 | |
| 	struct Cursor
 | |
| 	{
 | |
| 		uint32_t width;
 | |
| 		uint32_t height;
 | |
| 		BAN::Vector<uint32_t> pixels;
 | |
| 	};
 | |
| 
 | |
| public:
 | |
| 	Window(int fd, const LibFont::Font& font)
 | |
| 		: m_font(font)
 | |
| 		, m_client_fd(fd)
 | |
| 	{ }
 | |
| 
 | |
| 	~Window();
 | |
| 
 | |
| 	void set_position(Position position)
 | |
| 	{
 | |
| 		m_client_area.x = position.x;
 | |
| 		m_client_area.y = position.y;
 | |
| 	}
 | |
| 
 | |
| 	int client_fd() const { return m_client_fd; }
 | |
| 	long smo_key() const { return m_smo_key; }
 | |
| 
 | |
| 	int32_t client_x() const { return m_client_area.x; }
 | |
| 	int32_t client_y() const { return m_client_area.y; }
 | |
| 	int32_t client_width() const { return m_client_area.width; }
 | |
| 	int32_t client_height() const { return m_client_area.height; }
 | |
| 	Rectangle client_size() const { return { 0, 0, client_width(), client_height() }; }
 | |
| 	Rectangle client_area() const { return m_client_area; }
 | |
| 
 | |
| 	int32_t title_bar_x() const { return client_x(); }
 | |
| 	int32_t title_bar_y() const { return m_attributes.title_bar ? client_y() - title_bar_height() : client_y(); }
 | |
| 	int32_t title_bar_width() const { return client_width(); }
 | |
| 	int32_t title_bar_height() const { return m_attributes.title_bar ? m_title_bar_height : 0; }
 | |
| 	Rectangle title_bar_size() const { return { 0, 0, title_bar_width(), title_bar_height() }; }
 | |
| 	Rectangle title_bar_area() const { return { title_bar_x(), title_bar_y(), title_bar_width(), title_bar_height() }; }
 | |
| 
 | |
| 	int32_t full_x() const { return title_bar_x(); }
 | |
| 	int32_t full_y() const { return title_bar_y(); }
 | |
| 	int32_t full_width() const { return client_width(); }
 | |
| 	int32_t full_height() const { return client_height() + title_bar_height(); }
 | |
| 	Rectangle full_size() const { return { 0, 0, full_width(), full_height() }; }
 | |
| 	Rectangle full_area() const { return { full_x(), full_y(), full_width(), full_height() }; }
 | |
| 
 | |
| 	bool has_cursor() const { return m_cursor.has_value(); }
 | |
| 	const Cursor& cursor() const { return m_cursor.value(); }
 | |
| 	void set_cursor(Cursor&& cursor) { m_cursor = BAN::move(cursor); }
 | |
| 	void remove_cursor() { m_cursor.clear(); }
 | |
| 
 | |
| 	LibGUI::Window::Attributes get_attributes() const { return m_attributes; };
 | |
| 	void set_attributes(LibGUI::Window::Attributes attributes) { m_attributes = attributes; };
 | |
| 
 | |
| 	Rectangle get_min_size() const { return m_min_size; }
 | |
| 	void set_min_size(Rectangle min_size) { m_min_size = min_size.get_bounding_box({ 0, 0, m_title_bar_height, 0 }); }
 | |
| 
 | |
| 	Rectangle get_max_size() const { return m_max_size; }
 | |
| 	void set_max_size(Rectangle max_size) { m_max_size = max_size; }
 | |
| 
 | |
| 	BAN::ErrorOr<void> set_title(BAN::StringView title) { m_title.clear(); TRY(m_title.append(title)); TRY(prepare_title_bar()); return {}; }
 | |
| 
 | |
| 	const uint32_t* framebuffer() const { return m_fb_addr; }
 | |
| 
 | |
| 	uint32_t title_bar_pixel(int32_t abs_x, int32_t abs_y, Position cursor) const
 | |
| 	{
 | |
| 		ASSERT(title_bar_area().contains({ abs_x, abs_y }));
 | |
| 
 | |
| 		if (auto close_button = close_button_area(); close_button.contains({ abs_x, abs_y }))
 | |
| 			return close_button.contains(cursor) ? 0xFFFF0000 : 0xFFD00000;
 | |
| 
 | |
| 		int32_t rel_x = abs_x - title_bar_x();
 | |
| 		int32_t rel_y = abs_y - title_bar_y();
 | |
| 		return m_title_bar_data[rel_y * title_bar_width() + rel_x];
 | |
| 	}
 | |
| 
 | |
| 	Circle close_button_area() const { return { title_bar_x() + title_bar_width() - title_bar_height() / 2, title_bar_y() + title_bar_height() / 2, title_bar_height() * 3 / 8 }; }
 | |
| 	Rectangle title_text_area() const { return { title_bar_x(), title_bar_y(), title_bar_width() - title_bar_height(), title_bar_height() }; }
 | |
| 
 | |
| 	BAN::ErrorOr<void> initialize(BAN::StringView title, uint32_t width, uint32_t height);
 | |
| 	BAN::ErrorOr<void> resize(uint32_t width, uint32_t height);
 | |
| 
 | |
| private:
 | |
| 	BAN::ErrorOr<void> prepare_title_bar();
 | |
| 
 | |
| private:
 | |
| 	static constexpr int32_t m_title_bar_height { 20 };
 | |
| 
 | |
| 	const LibFont::Font& m_font;
 | |
| 
 | |
| 	const int   m_client_fd      { -1 };
 | |
| 	Rectangle   m_client_area    { 0, 0, 0, 0 };
 | |
| 	Rectangle   m_min_size       { 0, 0, m_title_bar_height, 0 };
 | |
| 	Rectangle   m_max_size       { 0, 0, 10'000, 10'000 };
 | |
| 	long        m_smo_key        { 0 };
 | |
| 	uint32_t*   m_fb_addr        { nullptr };
 | |
| 	BAN::String m_title;
 | |
| 
 | |
| 	BAN::Optional<Cursor> m_cursor;
 | |
| 
 | |
| 	BAN::Vector<uint32_t> m_title_bar_data;
 | |
| 
 | |
| 	LibGUI::Window::Attributes m_attributes { LibGUI::Window::default_attributes };
 | |
| 
 | |
| 	friend class BAN::RefPtr<Window>;
 | |
| };
 |