From c34b9191f258ddc15c5b45c000cd0266aed9dead Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Mon, 29 Jul 2024 21:26:17 -0400 Subject: window borders --- applications/goldman/makefile | 2 +- applications/goldman/source/renderer.cpp | 17 +++++-- applications/goldman/source/renderer.hpp | 10 ++-- applications/goldman/source/socket.cpp | 8 ++-- applications/goldman/source/window.cpp | 78 ++++++++++++++++++++++++++++++++ applications/goldman/source/window.hpp | 12 ++++- applications/hello/source/main.cpp | 16 ++++++- 7 files changed, 128 insertions(+), 15 deletions(-) create mode 100644 applications/goldman/source/window.cpp (limited to 'applications') diff --git a/applications/goldman/makefile b/applications/goldman/makefile index c6de0e7..0d07717 100644 --- a/applications/goldman/makefile +++ b/applications/goldman/makefile @@ -1,5 +1,5 @@ SOURCES = \ - main.cpp renderer.cpp input.cpp socket.cpp + main.cpp renderer.cpp input.cpp socket.cpp window.cpp build/%.cpp.o: source/%.cpp @mkdir -p $(@D) diff --git a/applications/goldman/source/renderer.cpp b/applications/goldman/source/renderer.cpp index 629c375..7a5e6b5 100644 --- a/applications/goldman/source/renderer.cpp +++ b/applications/goldman/source/renderer.cpp @@ -52,9 +52,11 @@ void renderer::do_render() { for (auto it = windows.begin(); it != windows.end(); ++it) double_buffer.copy_from( - (*it)->contents, (*it)->x, (*it)->y, 0, 0, - std::min((*it)->contents.width, double_buffer.width - (*it)->x), - std::min((*it)->contents.height, double_buffer.height - (*it)->y)); + (*it)->contents_with_decorations, (*it)->x, (*it)->y, 0, 0, + std::min((*it)->contents_with_decorations.width, + double_buffer.width - (*it)->x), + std::min((*it)->contents_with_decorations.height, + double_buffer.height - (*it)->y)); double_buffer.convert_from( cursor_background, cursor, cursor_x, cursor_y, 0, 0, @@ -93,10 +95,15 @@ void renderer::bump_cursor(int x_offset, int y_offset) { } -void renderer::add_window(const window *w) { +void renderer::add_window(window *w) { + if (windows.size() != 0) + windows.back()->draw_decorations(false); + w->draw_decorations(true); windows.push_back(w); } -void renderer::remove_window(const window *w) { +void renderer::remove_window(window *w) { windows.remove(w); + if (windows.size() != 0) + windows.back()->draw_decorations(true); } diff --git a/applications/goldman/source/renderer.hpp b/applications/goldman/source/renderer.hpp index 14a5964..91afe88 100644 --- a/applications/goldman/source/renderer.hpp +++ b/applications/goldman/source/renderer.hpp @@ -18,7 +18,7 @@ class renderer { int cursor_y; //bottom to top - std::list windows; + std::list windows; std::mutex mut; @@ -55,7 +55,11 @@ public: void bump_cursor(int x_offset, int y_offset); - void add_window(const window *w); - void remove_window(const window *w); + void add_window(window *w); + void remove_window(window *w); + + inline bool is_top(window *w) { + return windows.size() != 0 && w == windows.back(); + } }; diff --git a/applications/goldman/source/socket.cpp b/applications/goldman/source/socket.cpp index 9ebd644..aa9b85e 100644 --- a/applications/goldman/source/socket.cpp +++ b/applications/goldman/source/socket.cpp @@ -43,12 +43,13 @@ struct socket_state { euler::syscall::stream_result::success) return false; - if (packet.width > __INT_MAX__ || packet.height > __INT_MAX__) + if (packet. width > __INT_MAX__ - window::decorations_extra_width || + packet.height > __INT_MAX__ - window::decorations_extra_height) return false; r->lock(); - w->contents = daguerre::image( - packet.width, packet.height); + w->set_size(packet.width, packet.height); + w->draw_decorations(r->is_top(w)); r->unlock(); return true; @@ -69,6 +70,7 @@ struct socket_state { r->lock(); w->title = std::move(title); + w->draw_decorations(r->is_top(w)); r->unlock(); r->dispatch_render(); return true; diff --git a/applications/goldman/source/window.cpp b/applications/goldman/source/window.cpp new file mode 100644 index 0000000..fe5212a --- /dev/null +++ b/applications/goldman/source/window.cpp @@ -0,0 +1,78 @@ +#include +#include "renderer.hpp" +#include "window.hpp" +#include + +//TODO: make these statically intialized once that is implemented +bool have_initialized_decoration_stuff; +daguerre::fixed_font *title_font; +daguerre::hilbert_color border_color_top; +daguerre::hilbert_color border_color_not_top; +daguerre::hilbert_color title_color; + +void window::set_size(int width, int height) { + contents_with_decorations = + daguerre::image(width + 4, height + 18); + contents = daguerre::image( + width, height, + &contents_with_decorations.at(2, 16), + contents_with_decorations.buffer_pitch, false); +} + +void title_converter( + daguerre::hilbert_color &out, const bool &in, const bool &top) { + out = in ? title_color : top ? border_color_top : border_color_not_top; +} + +void window::draw_decorations(bool top) { + + //TODO: handle error loading font. + //see also comment on title_font declaration. + if (!have_initialized_decoration_stuff) { + title_font = new daguerre::fixed_font( + *daguerre::try_load_psf("/assets/terminus/6x12.psf")); + assert(title_font->glyph_height == 12); + border_color_top = euler::syscall::encode_color(0x00, 0x3f, 0xff); + border_color_not_top = euler::syscall::encode_color(0x22, 0x22, 0x22); + title_color = euler::syscall::encode_color(0xff, 0xff, 0xff); + have_initialized_decoration_stuff = true; + } + + static_assert( decorations_extra_width == 4); + static_assert(decorations_extra_height == 18); + + auto border_color = top ? border_color_top : border_color_not_top; + + contents_with_decorations.fill(border_color, 0, 0, + contents_with_decorations.width, 16); + contents_with_decorations.fill( + border_color, 0, contents_with_decorations.height - 2, + contents_with_decorations.width, 2); + contents_with_decorations.fill(border_color, 0, 16, + 2, contents_with_decorations.height - 18); + contents_with_decorations.fill(border_color, + contents_with_decorations.width - 2, 16, + 2, contents_with_decorations.height - 18); + + //TODO: make UTF-8--safe + unsigned max_title_length = + contents_with_decorations.width / title_font->glyph_width; + std::string *title_to_draw; + std::string shortened_title; + if (title.size() > max_title_length) { + shortened_title.resize(max_title_length - 3); + memcpy(shortened_title.data(), title.data(), max_title_length - 3); + shortened_title[max_title_length - 3] = '.'; + shortened_title[max_title_length - 2] = '.'; + shortened_title[max_title_length - 1] = '.'; + title_to_draw = &shortened_title; + } + else + title_to_draw = &title; + + contents_with_decorations.render_text(*title_font, top, + contents_with_decorations.width / 2 - + (title_to_draw->size() * title_font->glyph_width) / 2, + 2, title_to_draw->data(), title_converter); + +} diff --git a/applications/goldman/source/window.hpp b/applications/goldman/source/window.hpp index 4d5b0e1..5c2d7a0 100644 --- a/applications/goldman/source/window.hpp +++ b/applications/goldman/source/window.hpp @@ -4,6 +4,10 @@ struct window { + static constexpr int decorations_extra_width = 4; + static constexpr int decorations_extra_height = 18; + + daguerre::image contents_with_decorations; daguerre::image contents; int x; @@ -13,6 +17,12 @@ struct window { std::string title; - window() : x(0), y(0), is_shown(false) {} + void set_size(int width, int height); + void draw_decorations(bool top); + + inline window() : x(0), y(0), is_shown(false) { + set_size(0, 0); + draw_decorations(false); + } }; diff --git a/applications/hello/source/main.cpp b/applications/hello/source/main.cpp index 1f45407..b297721 100644 --- a/applications/hello/source/main.cpp +++ b/applications/hello/source/main.cpp @@ -7,18 +7,30 @@ daguerre::fixed_font *font; int main(int, char **) { font = new daguerre::fixed_font( - daguerre::try_load_psf("/assets/terminus-bold-18x10.psf").value()); + daguerre::try_load_psf("/assets/terminus/10x18-bold.psf").value()); pake::widgets::fixed_text *text = new pake::widgets::fixed_text("Hello, world!", font, euler::syscall::encode_color(0xaa, 0xaa, 0xaa), - euler::syscall::encode_color(0x00, 0x00, 0x00)); + euler::syscall::encode_color(0x00, 0x00, 0x00), + pake::halign::center, pake::valign::center); pake::window w(300, 200, "Hello"); w.set_root(std::unique_ptr(text)); w.render_and_send_to_compositor(); w.show(); + pake::widgets::fixed_text *text2 = + new pake::widgets::fixed_text("H!", font, + euler::syscall::encode_color(0xaa, 0xaa, 0xaa), + euler::syscall::encode_color(0x00, 0x00, 0x00), + pake::halign::center, pake::valign::center); + + pake::window w2(100, 50, "Hello 2"); + w2.set_root(std::unique_ptr(text2)); + w2.render_and_send_to_compositor(); + w2.show(); + //TODO: call event loop euler::syscall::stream_handle h1, h2; -- cgit v1.2.3