mirror of
https://github.com/transmission/transmission.git
synced 2025-12-20 02:18:42 +00:00
* chore: savepoint * chore: code style * refactor: add std::string_view constructor for NativeIcon::Spec * chore: add TODO comment * feat: honor per-desktop HIG on when to show menu icons * chore: remove Faenza system-run icon unused sinceb58e95910b* chore: remove Faenza view-refresh icon not needed due tob58e95910b* chore: remove Faenza media-playback-pause icon not needed due tob58e95910b* chore: remove Faenza media-playback-start icon not needed due tob58e95910b* chore: add a safeguard against merging with incomplete TODO items * feat: add more icons refactor: remove some tracer cerr statements * refactor: remove IconCache use from MainWindow * chore: remove Faenza icon set * chore: re-enable remote session network icon * fix: FTBFS on Windows * refactor: use symbolic names for Segoe icons * docs: add links to Segoe MDL2 Assets icon list * chore: savepoint segoe icons work still a WIP; includes test code that should not ship * feat: use segoe::FastForward for action_StartNow feat: use segoe::Move for action_SetLocation refactor: make it easier for devs to force a font at compile time for development work segoe license does not allow bundling but does allow dev work chore: code_style.sh * refactor: remove unused addEmblem() * docs: add code comment on how to force an icon font * fix: Win 10, 11 icons play nicely with dark mode * chore: savepoint add draft of SF Symbol -> QPixmap loader * chore: remove dangling font reference from qrc file * fix: FTBFS * refactor: use bribri code for NSImage -> QPixmap * feat: support dark, light mode when rendering SF Symbol monochrome icons * fixup! feat: support dark, light mode when rendering SF Symbol monochrome icons fix: fail gracefully on macOS 11 * chore: code style * chore: tweak some SF Symbol icon choices * chore: consistent uppercase for hex segoe QChars * chore: undefine DEV_FORCE_FONT_FAMILY and DEV_FORCE_FONT_RESOURCE * chore: savepoint * refactor: clean up NativeIcon impl * refactor: remove unused MenuMode::Other * refactor: DRY in FilterBar::createActivityCombo() * chore: remove obsolete code comment * refactor: rename icons::Facet as icons::Type * fix: oops * refactor: minor cleanup * fix: tyop * chore: remove unused #includes * fix: add modes for some icons * refactor: tweak some icon choices on macOS * fix: ensure icons are visible on File, Help menus fix: remove unused local variable * refactor: tweak some icon choices for XDG * refactor: remove the fallback QStyle::StandardPixmaps These interfere with deciding whether an icon is well-defined and unambiguous as per the macOS and Windows HIG guidelines. If a standard or unambiguous icon exists in the native icon sets, specify it with an SF Symbols name, a Segoe codepoint, or XDG standard icon name. Otherwise, leave those fields blank. * refactor: remove unused #includes * docs: add "choosing icons" section in NativeIcons.cc * refactor: simplify icons::shouldBeShownInMenu() * refactor: reduce unnecessary code shear from main * refactor: make TorrentDelegate::warning_emblem_ const * refactor: extract-method MainWindow::updateActionIcons() * feat: update MainWindow icons when light/dark theme changes * feat: restore the QStyle::StandardPixmaps as fallbacks Can be used on older Windows / macOS if Segoe or SF Symbols are unavailable * refactor: add button text for add/edit/remove tracker buttons QStyle::StandardPixmap doesn't have good icons for these, so let's ensure that these buttons have visible text. * fix: building NativeIconMac.mm on mac even if not clang * chore: iwyu in new code * docs: tweak the "Choosing Icons" comments again * fix: handle changed QStyles in icons::icon() do not cache point_sizes set between calls refactor: const correctness * fixup! refactor: simplify icons::shouldBeShownInMenu() refactor: minor code tweak, declare vars in order that they are used
100 lines
3.5 KiB
Plaintext
100 lines
3.5 KiB
Plaintext
// This file Copyright © Mnemosyne LLC.
|
|
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
|
|
// or any future license endorsed by Mnemosyne LLC.
|
|
// License text can be found in the licenses/ folder.
|
|
|
|
#import <AppKit/AppKit.h>
|
|
|
|
#import <QApplication>
|
|
#import <QColor>
|
|
#import <QImage>
|
|
#import <QPalette>
|
|
#import <QPixmap>
|
|
|
|
// Source: https://stackoverflow.com/a/74756071
|
|
// Posted by Bri Bri
|
|
// Retrieved 2025-11-22, License - CC BY-SA 4.0
|
|
namespace bribri
|
|
{
|
|
|
|
CGBitmapInfo CGBitmapInfoForQImage(QImage const& image)
|
|
{
|
|
CGBitmapInfo bitmapInfo = kCGImageAlphaNone;
|
|
|
|
switch (image.format())
|
|
{
|
|
case QImage::Format_ARGB32:
|
|
bitmapInfo = kCGImageAlphaFirst | kCGBitmapByteOrder32Host;
|
|
break;
|
|
case QImage::Format_RGB32:
|
|
bitmapInfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
|
|
break;
|
|
case QImage::Format_RGBA8888_Premultiplied:
|
|
bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
|
|
break;
|
|
case QImage::Format_RGBA8888:
|
|
bitmapInfo = kCGImageAlphaLast | kCGBitmapByteOrder32Big;
|
|
break;
|
|
case QImage::Format_RGBX8888:
|
|
bitmapInfo = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big;
|
|
break;
|
|
case QImage::Format_ARGB32_Premultiplied:
|
|
bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return bitmapInfo;
|
|
}
|
|
|
|
QImage CGImageToQImage(CGImageRef cgImage)
|
|
{
|
|
size_t const width = CGImageGetWidth(cgImage);
|
|
size_t const height = CGImageGetHeight(cgImage);
|
|
QImage image(width, height, QImage::Format_ARGB32_Premultiplied);
|
|
image.fill(Qt::transparent);
|
|
|
|
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
|
|
CGContextRef context = CGBitmapContextCreate((void*)image.bits(), image.width(), image.height(), 8, image.bytesPerLine(), colorSpace, CGBitmapInfoForQImage(image));
|
|
|
|
// Scale the context so that painting happens in device-independent pixels
|
|
qreal const devicePixelRatio = image.devicePixelRatio();
|
|
CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio);
|
|
|
|
CGRect rect = CGRectMake(0, 0, width, height);
|
|
CGContextDrawImage(context, rect, cgImage);
|
|
|
|
CFRelease(colorSpace);
|
|
CFRelease(context);
|
|
|
|
return image;
|
|
}
|
|
|
|
} // namespace bribri
|
|
|
|
QPixmap loadSFSymbol(QString const symbol_name, int const pixel_size)
|
|
{
|
|
if (NSImage* image = [NSImage imageWithSystemSymbolName:symbol_name.toNSString() accessibilityDescription:nil])
|
|
{
|
|
auto* configuration = [NSImageSymbolConfiguration configurationWithPointSize:pixel_size weight:NSFontWeightRegular];
|
|
if (@available(macOS 12.0, *))
|
|
{
|
|
// use whatever color QPalette::ButtonText is using
|
|
// @available check needed for configurationWithHierarchicalColor
|
|
QColor const qfg = qApp->palette().color(QPalette::ButtonText);
|
|
NSColor* nsfg = [NSColor colorWithCalibratedRed:qfg.redF() green:qfg.greenF() blue:qfg.blueF() alpha:qfg.alphaF()];
|
|
auto* colorConfig = [NSImageSymbolConfiguration configurationWithHierarchicalColor:nsfg];
|
|
configuration = [configuration configurationByApplyingConfiguration:colorConfig];
|
|
}
|
|
image = [image imageWithSymbolConfiguration:configuration];
|
|
|
|
// NSImage -> QPixmap
|
|
NSRect image_rect = NSMakeRect(0, 0, pixel_size, pixel_size);
|
|
CGImageRef cgimg = [image CGImageForProposedRect:&image_rect context:nil hints:nil];
|
|
return QPixmap::fromImage(bribri::CGImageToQImage(cgimg));
|
|
}
|
|
|
|
return {};
|
|
}
|