opuntiaOS - an operating system targeting x86 and ARMv7
at master 2.8 kB view raw
1/* 2 * Copyright (C) 2020-2022 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#include <libfoundation/EventLoop.h> 10#include <libui/Button.h> 11#include <libui/Context.h> 12 13namespace UI { 14 15Button::Button(View* superview, const LG::Rect& frame) 16 : Control(superview, frame) 17{ 18 set_background_color(LG::Color::LightSystemButton); 19} 20 21void Button::display(const LG::Rect& rect) 22{ 23 LG::Context& ctx = graphics_current_context(); 24 ctx.add_clip(rect); 25 26 ctx.set_fill_color(background_color()); 27 if (m_button_type == Type::System) { 28 if (is_hovered()) { 29 ctx.set_fill_color(background_color().darken(8)); 30 } 31 } 32 ctx.fill_rounded(bounds(), LG::CornerMask(4)); 33 34 size_t content_width = text_width(); 35 size_t content_height = text_height(); 36 LG::Point<int> text_start { content_edge_insets().left(), std::max(content_edge_insets().top(), int(bounds().height() - content_height) / 2) }; 37 if (alignment() == Text::Alignment::Center) { 38 text_start.set_x((bounds().width() - content_width) / 2); 39 } else if (alignment() == Text::Alignment::Right) { 40 text_start.set_x(bounds().width() - content_width); 41 } 42 43 auto& f = font(); 44 const size_t letter_spacing = f.glyph_spacing(); 45 46 ctx.set_fill_color(title_color()); 47 for (int i = 0; i < m_title.size(); i++) { 48 ctx.draw(text_start, f.glyph_bitmap(m_title[i])); 49 text_start.offset_by(f.glyph_width(m_title[i]) + letter_spacing, 0); 50 } 51} 52 53void Button::mouse_entered(const LG::Point<int>& location) 54{ 55 send_actions(UI::Event::Type::MouseEnterEvent); 56 View::mouse_entered(location); 57} 58 59void Button::mouse_exited() 60{ 61 send_actions(UI::Event::Type::MouseLeaveEvent); 62 View::mouse_exited(); 63} 64 65void Button::mouse_down(const LG::Point<int>& location) 66{ 67 send_actions(UI::Event::Type::MouseDownEvent); 68 View::mouse_down(location); 69} 70 71void Button::mouse_up() 72{ 73 send_actions(UI::Event::Type::MouseUpEvent); 74 View::mouse_up(); 75} 76 77void Button::recalc_bounds() 78{ 79 size_t new_width = text_width() + content_edge_insets().left() + content_edge_insets().right(); 80 size_t new_height = text_height() + content_edge_insets().top() + content_edge_insets().bottom(); 81 set_width(new_width); 82 set_height(new_height); 83} 84 85size_t Button::text_width() 86{ 87 size_t width = 0; 88 auto& f = font(); 89 const size_t letter_spacing = f.glyph_spacing(); 90 91 for (int i = 0; i < m_title.size(); i++) { 92 width += f.glyph_width(m_title[i]); 93 } 94 width += std::max(size_t(0), m_title.size() - 1) * letter_spacing; 95 return width; 96} 97 98size_t Button::text_height() const 99{ 100 return font().glyph_height(); 101} 102 103} // namespace UI