opuntiaOS - an operating system targeting x86 and ARMv7
at master 2.4 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 "Popup.h" 10#include "../../Constants/Colors.h" 11#include "../../Managers/WindowManager.h" 12#include "../Helpers/TextDrawer.h" 13#include <algorithm> 14 15namespace WinServer { 16 17Popup* s_WinServer_Popup_the = nullptr; 18 19Popup::Popup() 20{ 21 s_WinServer_Popup_the = this; 22} 23 24void Popup::on_set_data() 25{ 26 size_t max_width = 0; 27 size_t max_height = 0; 28 for (auto& item : m_data) { 29 max_width = std::max(max_width, Helpers::text_width(item.text, m_font)); 30 max_height += m_font.glyph_height() + spacing(); 31 } 32 max_width = std::max(max_width, min_width()); 33 bounds().set_width(max_width + 2 * spacing()); 34 bounds().set_height(max_height + spacing()); 35} 36 37void Popup::draw(LG::Context& ctx) 38{ 39 if (!visible()) { 40 return; 41 } 42 43 ctx.set_fill_color(LG::Color::LightSystemOpaque); 44 ctx.fill_rounded(bounds(), LG::CornerMask(LG::CornerMask::SystemRadius)); 45 46 ctx.set_fill_color(Color::Shadow); 47 ctx.draw_box_shading(bounds(), LG::Shading(LG::Shading::Type::Box, 0, LG::Shading::SystemSpread), LG::CornerMask(LG::CornerMask::SystemRadius)); 48 49 const size_t line_height = (m_font.glyph_height() + spacing()); 50 int height = bounds().min_y() + spacing(); 51 52 for (int i = 0; i < m_data.size(); i++) { 53 if (i == m_hovered_item) { 54 ctx.set_fill_color(LG::Color::White); 55 ctx.fill_rounded(LG::Rect(bounds().min_x() + 4, height - spacing() / 2, bounds().width() - 8, line_height), LG::CornerMask(2)); 56 } 57 ctx.set_fill_color(LG::Color::DarkSystemText); 58 Helpers::draw_text(ctx, { bounds().min_x() + spacing(), height }, m_data[i].text, m_font); 59 height += line_height; 60 } 61} 62 63void Popup::set_preferred_origin(const LG::Point<int>& origin) 64{ 65 auto& wm = WindowManager::the(); 66 LG::Point<int> pos; 67 int x = origin.x(); 68 int y = origin.y(); 69 70 if (origin.y() + bounds().height() > wm.visible_area().max_y()) { 71 y = origin.y() - bounds().height(); 72 } 73 if (origin.x() + bounds().width() > wm.visible_area().max_x()) { 74 x = origin.x() - bounds().width(); 75 } 76 pos.set_x(x); 77 pos.set_y(y); 78 m_bounds.set_origin(std::move(pos)); 79} 80 81} // namespace WinServer