Serenity Operating System
at master 98 lines 2.5 kB view raw
1/* 2 * Copyright (c) 2018-2023, Andreas Kling <kling@serenityos.org> 3 * Copyright (c) 2021, Julius Heijmen <julius.heijmen@gmail.com> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#include <AK/DeprecatedString.h> 9#include <LibGUI/Icon.h> 10#include <LibGfx/Bitmap.h> 11 12namespace GUI { 13 14Icon::Icon() 15 : m_impl(IconImpl::create()) 16{ 17} 18 19Icon::Icon(IconImpl const& impl) 20 : m_impl(const_cast<IconImpl&>(impl)) 21{ 22} 23 24Icon::Icon(Icon const& other) 25 : m_impl(other.m_impl) 26{ 27} 28 29Icon::Icon(RefPtr<Gfx::Bitmap const>&& bitmap) 30 : Icon() 31{ 32 if (bitmap) { 33 VERIFY(bitmap->width() == bitmap->height()); 34 int size = bitmap->width(); 35 set_bitmap_for_size(size, move(bitmap)); 36 } 37} 38 39Icon::Icon(RefPtr<Gfx::Bitmap const>&& bitmap1, RefPtr<Gfx::Bitmap const>&& bitmap2) 40 : Icon(move(bitmap1)) 41{ 42 if (bitmap2) { 43 VERIFY(bitmap2->width() == bitmap2->height()); 44 int size = bitmap2->width(); 45 set_bitmap_for_size(size, move(bitmap2)); 46 } 47} 48 49Gfx::Bitmap const* IconImpl::bitmap_for_size(int size) const 50{ 51 auto it = m_bitmaps.find(size); 52 if (it != m_bitmaps.end()) 53 return it->value.ptr(); 54 55 int best_diff_so_far = INT32_MAX; 56 Gfx::Bitmap const* best_fit = nullptr; 57 for (auto& it : m_bitmaps) { 58 int abs_diff = abs(it.key - size); 59 if (abs_diff < best_diff_so_far) { 60 best_diff_so_far = abs_diff; 61 best_fit = it.value.ptr(); 62 } 63 } 64 return best_fit; 65} 66 67void IconImpl::set_bitmap_for_size(int size, RefPtr<Gfx::Bitmap const>&& bitmap) 68{ 69 if (!bitmap) { 70 m_bitmaps.remove(size); 71 return; 72 } 73 m_bitmaps.set(size, move(bitmap)); 74} 75 76Icon Icon::default_icon(StringView name) 77{ 78 return MUST(try_create_default_icon(name)); 79} 80 81ErrorOr<Icon> Icon::try_create_default_icon(StringView name) 82{ 83 RefPtr<Gfx::Bitmap> bitmap16; 84 RefPtr<Gfx::Bitmap> bitmap32; 85 if (auto bitmap_or_error = Gfx::Bitmap::load_from_file(DeprecatedString::formatted("/res/icons/16x16/{}.png", name)); !bitmap_or_error.is_error()) 86 bitmap16 = bitmap_or_error.release_value(); 87 if (auto bitmap_or_error = Gfx::Bitmap::load_from_file(DeprecatedString::formatted("/res/icons/32x32/{}.png", name)); !bitmap_or_error.is_error()) 88 bitmap32 = bitmap_or_error.release_value(); 89 90 if (!bitmap16 && !bitmap32) { 91 dbgln("Default icon not found: {}", name); 92 return Error::from_string_literal("Default icon not found"); 93 } 94 95 return Icon(move(bitmap16), move(bitmap32)); 96} 97 98}