Mon, 23 Sep 2024 23:22:27 +0200
add headerbar toggle button (GTK)
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2017 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "pch.h" #include "icons.h" #include <stdlib.h> #include <string.h> #include "util.h" #include <Windows.h> #include <Shellapi.h> using namespace winrt; using namespace Microsoft::UI::Xaml; using namespace Microsoft::UI::Xaml::Controls; using namespace Windows::UI::Xaml::Interop; using namespace winrt::Windows::Foundation; using namespace winrt::Microsoft::UI::Xaml::Controls::Primitives; using namespace winrt::Microsoft::UI::Xaml::Media::Imaging; //using namespace Windows::Storage::Streams; static UiIcon* sys_folder_icon16; static UiIcon* sys_file_icon16; static UiIcon* sys_folder_icon32; static UiIcon* sys_file_icon32; std::unordered_map<std::string, Symbol> ui_symbol_icons = { {"Accept", Symbol::Accept }, {"Account", Symbol::Account }, {"Add", Symbol::Add }, {"AddFriend", Symbol::AddFriend }, {"Admin", Symbol::Admin }, {"AlignCenter", Symbol::AlignCenter }, {"AlignLeft", Symbol::AlignLeft }, {"AlignRight", Symbol::AlignRight }, {"AllApps", Symbol::AllApps }, {"Attach", Symbol::Attach }, {"AttachCamera", Symbol::AttachCamera }, {"Audio", Symbol::Audio }, {"Back", Symbol::Back }, {"BackToWindow", Symbol::BackToWindow }, {"BlockContact", Symbol::BlockContact }, {"Bold", Symbol::Bold }, {"Bookmarks", Symbol::Bookmarks }, {"BrowsePhotos", Symbol::BrowsePhotos }, {"Bullets", Symbol::Bullets }, {"Calculator", Symbol::Calculator }, {"Calendar", Symbol::Calendar }, {"CalendarDay", Symbol::CalendarDay }, {"CalendarReply", Symbol::CalendarReply }, {"CalendarWeek", Symbol::CalendarWeek }, {"Camera", Symbol::Camera }, {"Cancel", Symbol::Cancel }, {"Caption", Symbol::Caption }, {"CellPhone", Symbol::CellPhone }, {"Character", Symbol::Character }, {"Clear", Symbol::Clear }, {"ClearSelection", Symbol::ClearSelection }, {"Clock", Symbol::Clock }, {"ClosedCaption", Symbol::ClosedCaption }, {"ClosePane", Symbol::ClosePane }, {"Comment", Symbol::Comment }, {"Contact", Symbol::Contact }, {"Contact2", Symbol::Contact2 }, {"ContactInfo", Symbol::ContactInfo }, {"ContactPresence", Symbol::ContactPresence }, {"Copy", Symbol::Copy }, {"Crop", Symbol::Crop }, {"Cut", Symbol::Cut }, {"Delete", Symbol::Delete }, {"Directions", Symbol::Directions }, {"DisableUpdates", Symbol::DisableUpdates }, {"DisconnectDrive", Symbol::DisconnectDrive }, {"Dislike", Symbol::Dislike }, {"DockBottom", Symbol::DockBottom }, {"DockLeft", Symbol::DockLeft }, {"DockRight", Symbol::DockRight }, {"Document", Symbol::Document }, {"Download", Symbol::Download }, {"Edit", Symbol::Edit }, {"Emoji", Symbol::Emoji }, {"Emoji2", Symbol::Emoji2 }, {"Favorite", Symbol::Favorite }, {"Filter", Symbol::Filter }, {"Find", Symbol::Find }, {"Flag", Symbol::Flag }, {"Folder", Symbol::Folder }, {"Font", Symbol::Font }, {"FontColor", Symbol::FontColor }, {"FontDecrease", Symbol::FontDecrease }, {"FontIncrease", Symbol::FontIncrease }, {"FontSize", Symbol::FontSize }, {"Forward", Symbol::Forward }, {"FourBars", Symbol::FourBars }, {"FullScreen", Symbol::FullScreen }, {"GlobalNavigationButton", Symbol::GlobalNavigationButton }, {"Globe", Symbol::Globe }, {"Go", Symbol::Go }, {"GoToStart", Symbol::GoToStart }, {"GoToToday", Symbol::GoToToday }, {"HangUp", Symbol::HangUp }, {"Help", Symbol::Help }, {"HideBcc", Symbol::HideBcc }, {"Highlight", Symbol::Highlight }, {"Home", Symbol::Home }, {"Import", Symbol::Import }, {"ImportAll", Symbol::ImportAll }, {"Important", Symbol::Important }, {"Italic", Symbol::Italic }, {"Keyboard", Symbol::Keyboard }, {"LeaveChat", Symbol::LeaveChat }, {"Library", Symbol::Library }, {"Like", Symbol::Like }, {"LikeDislike", Symbol::LikeDislike }, {"Link", Symbol::Link }, {"List", Symbol::List }, {"Mail", Symbol::Mail }, {"MailFilled", Symbol::MailFilled }, {"MailForward", Symbol::MailForward }, {"MailReply", Symbol::MailReply }, {"MailReplyAll", Symbol::MailReplyAll }, {"Manage", Symbol::Manage }, {"Map", Symbol::Map }, {"MapDrive", Symbol::MapDrive }, {"MapPin", Symbol::MapPin }, {"Memo", Symbol::Memo }, {"Message", Symbol::Message }, {"Microphone", Symbol::Microphone }, {"More", Symbol::More }, {"MoveToFolder", Symbol::MoveToFolder }, {"MusicInfo", Symbol::MusicInfo }, {"Mute", Symbol::Mute }, {"NewFolder", Symbol::NewFolder }, {"NewWindow", Symbol::NewWindow }, {"Next", Symbol::Next }, {"OneBar", Symbol::OneBar }, {"OpenFile", Symbol::OpenFile }, {"OpenLocal", Symbol::OpenLocal }, {"OpenPane", Symbol::OpenPane }, {"OpenWith", Symbol::OpenWith }, {"Orientation", Symbol::Orientation }, {"OtherUser", Symbol::OtherUser }, {"OutlineStar", Symbol::OutlineStar }, {"Page", Symbol::Page }, {"Page2", Symbol::Page2 }, {"Paste", Symbol::Paste }, {"Pause", Symbol::Pause }, {"People", Symbol::People }, {"Permissions", Symbol::Permissions }, {"Phone", Symbol::Phone }, {"PhoneBook", Symbol::PhoneBook }, {"Pictures", Symbol::Pictures }, {"Pin", Symbol::Pin }, {"Placeholder", Symbol::Placeholder }, {"Play", Symbol::Play }, {"PostUpdate", Symbol::PostUpdate }, {"Preview", Symbol::Preview }, {"PreviewLink", Symbol::PreviewLink }, {"Previous", Symbol::Previous }, {"Print", Symbol::Print }, {"Priority", Symbol::Priority }, {"ProtectedDocument", Symbol::ProtectedDocument }, {"Read", Symbol::Read }, {"Redo", Symbol::Redo }, {"Refresh", Symbol::Refresh }, {"Remote", Symbol::Remote }, {"Remove", Symbol::Remove }, {"Rename", Symbol::Rename }, {"Repair", Symbol::Repair }, {"RepeatAll", Symbol::RepeatAll }, {"RepeatOne", Symbol::RepeatOne }, {"ReportHacked", Symbol::ReportHacked }, {"ReShare", Symbol::ReShare }, {"Rotate", Symbol::Rotate }, {"RotateCamera", Symbol::RotateCamera }, {"Save", Symbol::Save }, {"SaveLocal", Symbol::SaveLocal }, {"Scan", Symbol::Scan }, {"SelectAll", Symbol::SelectAll }, {"Send", Symbol::Send }, {"SetLockScreen", Symbol::SetLockScreen }, {"SetTile", Symbol::SetTile }, {"Setting", Symbol::Setting }, {"Share", Symbol::Share }, {"Shop", Symbol::Shop }, {"ShowBcc", Symbol::ShowBcc }, {"ShowResults", Symbol::ShowResults }, {"Shuffle", Symbol::Shuffle }, {"SlideShow", Symbol::SlideShow }, {"SolidStar", Symbol::SolidStar }, {"Sort", Symbol::Sort }, {"Stop", Symbol::Stop }, {"StopSlideShow", Symbol::StopSlideShow }, {"Street", Symbol::Street }, {"Switch", Symbol::Switch }, {"SwitchApps", Symbol::SwitchApps }, {"Sync", Symbol::Sync }, {"SyncFolder", Symbol::SyncFolder }, {"Tag", Symbol::Tag }, {"Target", Symbol::Target }, {"ThreeBars", Symbol::ThreeBars }, {"TouchPointer", Symbol::TouchPointer }, {"Trim", Symbol::Trim }, {"TwoBars", Symbol::TwoBars }, {"TwoPage", Symbol::TwoPage }, {"Underline", Symbol::Underline }, {"Undo", Symbol::Undo }, {"UnFavorite", Symbol::UnFavorite }, {"UnPin", Symbol::UnPin }, {"UnSyncFolder", Symbol::UnSyncFolder }, {"Up", Symbol::Up }, {"Upload", Symbol::Upload }, {"Video", Symbol::Video }, {"VideoChat", Symbol::VideoChat }, {"View", Symbol::View }, {"ViewAll", Symbol::ViewAll }, {"Volume", Symbol::Volume }, {"WebCam", Symbol::WebCam }, {"World", Symbol::World }, {"XboxOneConsole", Symbol::XboxOneConsole }, {"ZeroBars", Symbol::ZeroBars }, {"Zoom", Symbol::Zoom }, {"ZoomIn", Symbol::ZoomIn }, {"ZoomOut", Symbol::ZoomOut } }; winrt::Microsoft::UI::Xaml::Controls::IconElement ui_get_icon(const char* name) { if (ui_symbol_icons.find(name) == ui_symbol_icons.end()) { SymbolIcon no_icon = { nullptr }; return no_icon; } Symbol symbol = ui_symbol_icons[name]; SymbolIcon icon = SymbolIcon(symbol); return icon; } // symbol icon implementation UiSymbolIcon::UiSymbolIcon(winrt::Microsoft::UI::Xaml::Controls::Symbol sym) { symbol = sym; } UiSymbolIcon::~UiSymbolIcon() { } winrt::Microsoft::UI::Xaml::Controls::IconElement UiSymbolIcon::getIcon() { return SymbolIcon(symbol); } // image icon implementation UiImageIcon::UiImageIcon(const char* uristr) { wchar_t* wuri = str2wstr(uristr, nullptr); Windows::Foundation::Uri uri{ wuri }; this->uri = uri; free(wuri); } UiImageIcon::~UiImageIcon() { } winrt::Microsoft::UI::Xaml::Controls::IconElement UiImageIcon::getIcon() { BitmapIcon icon = BitmapIcon(); icon.UriSource(uri); ImageIcon img = ImageIcon(); img.Source(); return icon; } // bitmap icon implementation UiBitmapIcon::UiBitmapIcon(winrt::Microsoft::UI::Xaml::Media::Imaging::BitmapSource bitmap) { this->bitmap = bitmap; } UiBitmapIcon::~UiBitmapIcon() { } winrt::Microsoft::UI::Xaml::Controls::IconElement UiBitmapIcon::getIcon() { ImageIcon icon = ImageIcon(); icon.Source(bitmap); return icon; } UIEXPORT UiIcon* ui_icon(const char* name, size_t size) { Symbol symbol = ui_symbol_icons[name]; UiSymbolIcon* icon = new UiSymbolIcon(symbol); return icon; } UIEXPORT UiIcon* ui_imageicon(const char* file) { return new UiImageIcon(file); } UIEXPORT void ui_icon_free(UiIcon* icon) { delete icon; } struct __declspec(uuid("905a0fef-bc53-11df-8c49-001e4fc686da")) IBufferByteAccess : ::IUnknown { virtual HRESULT __stdcall Buffer(uint8_t** value) = 0; }; winrt::Microsoft::UI::Xaml::Media::Imaging::WriteableBitmap ui_dllicon2bitmap(const char* dll, int iconindex, bool large) { WriteableBitmap wbitmap = { nullptr }; // get the icon from the dll HICON hicon_small; HICON hicon_large; if (ExtractIconExA(dll, iconindex, &hicon_large, &hicon_small, 1) > 0) { HICON hicon = large ? hicon_large : hicon_small; // convert icon to (gdi) bitmap ICONINFO info; info.hbmColor = nullptr; info.hbmMask = nullptr; if (GetIconInfo(hicon, &info)) { BITMAP bitmap; if (GetObjectW(info.hbmColor, sizeof(BITMAP), &bitmap) != 0) { size_t bitmap_size = bitmap.bmWidthBytes * bitmap.bmHeight; char *bitmap_data = (char*)malloc(bitmap_size); // get the pixel data if (GetBitmapBits(info.hbmColor, bitmap_size, bitmap_data) != 0) { WriteableBitmap wb = WriteableBitmap(bitmap.bmWidth, bitmap.bmHeight); void *wb_data = wb.PixelBuffer().data(); memcpy(wb_data, bitmap_data, bitmap_size); wbitmap = wb; } free(bitmap_data); } if (info.hbmMask) { DeleteObject(info.hbmMask); } if (info.hbmColor) { DeleteObject(info.hbmColor); } } DestroyIcon(hicon_small); DestroyIcon(hicon_large); } return wbitmap; } UiIcon* ui_dllicon(const char* dll, int iconindex, bool large) { WriteableBitmap wbitmap = ui_dllicon2bitmap(dll, iconindex, large); return new UiBitmapIcon(wbitmap); } UIEXPORT UiIcon* ui_foldericon(size_t size) { bool large = true; UiIcon** sys_folder_icon = &sys_folder_icon32; if (size <= 24) { large = false; sys_folder_icon = &sys_folder_icon16; } if (*sys_folder_icon) { return *sys_folder_icon; } UiIcon* icon = ui_dllicon("shell32.dll", 3, large); *sys_folder_icon = icon; return icon; } UIEXPORT UiIcon* ui_fileicon(size_t size) { bool large = true; UiIcon** sys_folder_icon = &sys_file_icon32; if (size <= 24) { large = false; sys_folder_icon = &sys_file_icon16; } if (*sys_folder_icon) { return *sys_folder_icon; } UiIcon* icon = ui_dllicon("shell32.dll", 0, large); *sys_folder_icon = icon; return icon; }