Files
OrcaSlicer/src/slic3r/Utils/MacDarkMode.mm
T
Kris Austin 7888452666 build: clear 7 warning categories across 26 sites (#15615)
* build: clear 2 warnings - cast the NSTextField the class check already proved

mainframe_text_field is NSTextField* and was assigned a bare NSView*, which
Clang reports as -Wincompatible-pointer-types. Both assignments sit inside
if ([viewObject class] == [NSTextField self]), so the runtime type is already
guaranteed, and the line above the second one casts the same variable the same
way to call setTextColor. macOS only, since nothing else compiles this file.

* build: clear 6 warning categories from the clang-cl inventory

-Wmissing-braces (9). Aggregates whose first member is itself an aggregate.
GUID's fourth member is BYTE[8], so the trailing eight bytes take their own
braces. The others were reaching for zero-initialization with {0} and say {}
now. bbs_3mf's backup Task ends in an anonymous union, which needs braces of
its own; those braces initialize the union's first member rather than the one
named at the call site, so the RemoveBackup site says so in a comment.

-Wmacro-redefined (11). SendMultiMachinePage.hpp defines five names that
Preferences.hpp, PresetBundleDialog.hpp, ExportPresetBundleDialog.hpp and
TroubleshootDialog.hpp also define with different values, so the value in
force depended on include order. All nine of this file's DESIGN_ macros take
the SEND_ prefix it already uses for its own macros, values unchanged, so a
DESIGN_ name added elsewhere later cannot collide with it again. They read as
one page-local palette, a 900 to 400 gray ramp plus sizes, so the four with
no current readers stay: dropping them would leave gaps in a named scale. test_marchingsquares.cpp defines NOMINMAX,
which libslic3r already passes as a PUBLIC compile definition, so it takes
the #ifndef guard the other suites use.

-Wbraced-scalar-init (3). Two PushStyleVar calls resolve to the float
overload, so the braces were initializing a scalar. ConfigOptionFloatsNullable
already takes an initializer_list, so the inner braces did the same thing.

-Wmicrosoft-goto (2). Both gotos in copy_file_gui jump forward over the
initialization of size, dwRead and dwWrite, which only MSVC accepts. Those
declarations move up to join the others at the top of the function.

-Wunused-private-field (3). Every use of ColourPicker's m_clrData and
m_picker_widget is behind !defined(__linux__), so on Linux they are written
and never read; the members now carry the same guard. ParamsPanel's
m_size_move is read nowhere. Tab has its own, which is the one Tab.cpp uses.

-Wnonportable-include-path (2). BaseException.h asked for "stackwalker.h"
and the file on disk is StackWalker.h.
2026-09-10 07:39:14 -03:00

429 lines
13 KiB
Plaintext

#import "MacDarkMode.hpp"
#include "../GUI/Widgets/Label.hpp"
#include "wx/osx/core/cfstring.h"
#import <algorithm>
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
#import <AppKit/NSScreen.h>
#import <WebKit/WebKit.h>
#include <objc/runtime.h>
@interface MacDarkMode : NSObject {}
@end
@implementation MacDarkMode
namespace Slic3r {
namespace GUI {
NSTextField* mainframe_text_field = nil;
bool is_in_full_screen_mode = false;
bool mac_dark_mode()
{
NSString *style = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
return style && [style isEqualToString:@"Dark"];
}
double mac_max_scaling_factor()
{
double scaling = 1.;
if ([NSScreen screens] == nil) {
scaling = [[NSScreen mainScreen] backingScaleFactor];
} else {
for (int i = 0; i < [[NSScreen screens] count]; ++ i)
scaling = std::max<double>(scaling, [[[NSScreen screens] objectAtIndex:0] backingScaleFactor]);
}
return scaling;
}
void set_miniaturizable(void * window)
{
CGFloat rFloat = 34/255.0;
CGFloat gFloat = 34/255.0;
CGFloat bFloat = 36/255.0;
[(NSView*) window window].titlebarAppearsTransparent = true;
[(NSView*) window window].backgroundColor = [NSColor colorWithCalibratedRed:rFloat green:gFloat blue:bFloat alpha:1.0];
[(NSView*) window window].styleMask |= NSMiniaturizableWindowMask;
NSEnumerator *viewEnum = [[[[[[[(NSView*) window window] contentView] superview] titlebarViewController] view] subviews] objectEnumerator];
NSView *viewObject;
while(viewObject = (NSView *)[viewEnum nextObject]) {
if([viewObject class] == [NSTextField self]) {
//[(NSTextField*)viewObject setTextColor : NSColor.whiteColor];
mainframe_text_field = (NSTextField*)viewObject;
}
}
}
void set_tag_when_enter_full_screen(bool isfullscreen)
{
is_in_full_screen_mode = isfullscreen;
}
void set_title_colour_after_set_title(void * window)
{
NSEnumerator *viewEnum = [[[[[[[(NSView*) window window] contentView] superview] titlebarViewController] view] subviews] objectEnumerator];
NSView *viewObject;
while(viewObject = (NSView *)[viewEnum nextObject]) {
if([viewObject class] == [NSTextField self]) {
[(NSTextField*)viewObject setTextColor : NSColor.whiteColor];
mainframe_text_field = (NSTextField*)viewObject;
}
}
if (mainframe_text_field) {
[(NSTextField*)mainframe_text_field setTextColor : NSColor.whiteColor];
}
}
void WKWebView_evaluateJavaScript(void * web, wxString const & script, void (*callback)(wxString const &))
{
[(WKWebView*)web evaluateJavaScript:wxCFStringRef(script).AsNSString() completionHandler: ^(id result, NSError *error) {
if (callback && error != nil) {
wxString err = wxCFStringRef(error.localizedFailureReason).AsString();
callback(err);
}
}];
}
void WKWebView_setTransparentBackground(void * web)
{
WKWebView * webView = (WKWebView*)web;
[webView layer].backgroundColor = [NSColor clearColor].CGColor;
[webView registerForDraggedTypes: @[NSFilenamesPboardType]];
}
void openFolderForFile(wxString const & file)
{
NSArray *fileURLs = [NSArray arrayWithObjects:wxCFStringRef(file).AsNSString(), /* ... */ nil];
[[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:fileURLs];
}
}
}
@end
/* WKWebView */
@implementation WKWebView (DragDrop)
+ (void) load
{
Method draggingEntered = class_getInstanceMethod([WKWebView class], @selector(draggingEntered:));
Method draggingEntered2 = class_getInstanceMethod([WKWebView class], @selector(draggingEntered2:));
method_exchangeImplementations(draggingEntered, draggingEntered2);
Method draggingUpdated = class_getInstanceMethod([WKWebView class], @selector(draggingUpdated:));
Method draggingUpdated2 = class_getInstanceMethod([WKWebView class], @selector(draggingUpdated2:));
method_exchangeImplementations(draggingUpdated, draggingUpdated2);
Method prepareForDragOperation = class_getInstanceMethod([WKWebView class], @selector(prepareForDragOperation:));
Method prepareForDragOperation2 = class_getInstanceMethod([WKWebView class], @selector(prepareForDragOperation2:));
method_exchangeImplementations(prepareForDragOperation, prepareForDragOperation2);
Method performDragOperation = class_getInstanceMethod([WKWebView class], @selector(performDragOperation:));
Method performDragOperation2 = class_getInstanceMethod([WKWebView class], @selector(performDragOperation2:));
method_exchangeImplementations(performDragOperation, performDragOperation2);
}
- (NSDragOperation)draggingEntered2:(id<NSDraggingInfo>)sender
{
return NSDragOperationCopy;
}
- (NSDragOperation)draggingUpdated2:(id<NSDraggingInfo>)sender
{
return NSDragOperationCopy;
}
- (BOOL)prepareForDragOperation2:(id<NSDraggingInfo>)info
{
return TRUE;
}
- (BOOL)performDragOperation2:(id<NSDraggingInfo>)info
{
NSURL* url = [NSURL URLFromPasteboard:[info draggingPasteboard]];
if (!url) {
return FALSE;
}
NSString * path = [url path];
url = [NSURL fileURLWithPath: path];
[self loadFileURL:url allowingReadAccessToURL:url];
return TRUE;
}
@end
/* textColor for NSTextField */
@implementation NSTextField (textColor)
- (void)setTextColor2:(NSColor *)textColor
{
if (Slic3r::GUI::mainframe_text_field != self){
[self setTextColor2: textColor];
}else{
if(Slic3r::GUI::is_in_full_screen_mode){
[self setTextColor2 : NSColor.darkGrayColor];
}else{
[self setTextColor2 : NSColor.whiteColor];
}
}
}
+ (void) load
{
Method setTextColor = class_getInstanceMethod([NSTextField class], @selector(setTextColor:));
Method setTextColor2 = class_getInstanceMethod([NSTextField class], @selector(setTextColor2:));
method_exchangeImplementations(setTextColor, setTextColor2);
}
@end
/* drawsBackground for NSTextField */
@implementation NSTextField (drawsBackground)
- (instancetype)initWithFrame2:(NSRect)frameRect
{
[self initWithFrame2:frameRect];
self.drawsBackground = false;
return self;
}
+ (void) load
{
Method initWithFrame = class_getInstanceMethod([NSTextField class], @selector(initWithFrame:));
Method initWithFrame2 = class_getInstanceMethod([NSTextField class], @selector(initWithFrame2:));
method_exchangeImplementations(initWithFrame, initWithFrame2);
}
@end
/* textColor for NSButton */
@implementation NSButton (NSButton_Extended)
- (NSColor *)textColor
{
NSAttributedString *attrTitle = [self attributedTitle];
int len = [attrTitle length];
NSRange range = NSMakeRange(0, MIN(len, 1)); // get the font attributes from the first character
NSDictionary *attrs = [attrTitle fontAttributesInRange:range];
NSColor *textColor = [NSColor controlTextColor];
if (attrs)
{
textColor = [attrs objectForKey:NSForegroundColorAttributeName];
}
return textColor;
}
- (void)setTextColor:(NSColor *)textColor
{
NSMutableAttributedString *attrTitle =
[[NSMutableAttributedString alloc] initWithAttributedString:[self attributedTitle]];
int len = [attrTitle length];
NSRange range = NSMakeRange(0, len);
[attrTitle addAttribute:NSForegroundColorAttributeName value:textColor range:range];
[attrTitle fixAttributesInRange:range];
[self setAttributedTitle:attrTitle];
[attrTitle release];
}
- (void)setBezelStyle2:(NSBezelStyle)bezelStyle
{
if (bezelStyle != NSBezelStyleShadowlessSquare)
[self setBordered: YES];
[self setBezelStyle2: bezelStyle];
}
+ (void) load
{
Method setBezelStyle = class_getInstanceMethod([NSButton class], @selector(setBezelStyle:));
Method setBezelStyle2 = class_getInstanceMethod([NSButton class], @selector(setBezelStyle2:));
method_exchangeImplementations(setBezelStyle, setBezelStyle2);
}
- (NSFocusRingType) focusRingType
{
return NSFocusRingTypeNone;
}
@end
/* edit column for wxCocoaOutlineView */
#include <wx/dataview.h>
#include <wx/osx/cocoa/dataview.h>
#include <wx/osx/dataview.h>
@implementation wxCocoaOutlineView (Edit)
bool addObserver = false;
- (BOOL)outlineView: (NSOutlineView*) view shouldEditTableColumn:(nullable NSTableColumn *)tableColumn item:(nonnull id)item
{
NSClipView * clipView = [[self enclosingScrollView] contentView];
if (!addObserver) {
addObserver = true;
clipView.postsBoundsChangedNotifications = YES;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(synchronizedViewContentBoundsDidChange:)
name:NSViewBoundsDidChangeNotification
object:clipView];
}
wxDataViewColumn* const col((wxDataViewColumn *)[tableColumn getColumnPointer]);
wxDataViewItem item2([static_cast<wxPointerObject *>(item) pointer]);
wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
// Before doing anything we send an event asking if editing of this item is really wanted.
wxDataViewEvent event(wxEVT_DATAVIEW_ITEM_EDITING_STARTED, dvc, col, item2);
dvc->GetEventHandler()->ProcessEvent( event );
if( !event.IsAllowed() )
return NO;
return YES;
}
- (void)synchronizedViewContentBoundsDidChange:(NSNotification *)notification
{
wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
wxDataViewCustomRenderer * r = dvc->GetCustomRendererPtr();
if (r)
r->FinishEditing();
}
@end
/* Font for wxTextCtrl */
@implementation NSTableHeaderCell (Font)
- (NSFont*) font
{
return Label::sysFont(13).OSXGetNSFont();
}
@end
/* remove focused border for wxTextCtrl */
@implementation NSTextField (FocusRing)
- (NSFocusRingType) focusRingType
{
return NSFocusRingTypeNone;
}
@end
/* gesture handle for Canvas3D */
@interface wxNSCustomOpenGLView : NSOpenGLView
{
}
@end
@implementation wxNSCustomOpenGLView (Gesture)
wxEvtHandler * _gestureHandler = nullptr;
- (void) onGestureMove: (NSPanGestureRecognizer*) gesture
{
wxPanGestureEvent evt;
NSPoint tr = [gesture translationInView: self];
evt.SetDelta({(int) tr.x, (int) tr.y});
[self postEvent:evt withGesture:gesture];
}
- (void) onGestureScale: (NSMagnificationGestureRecognizer*) gesture
{
wxZoomGestureEvent evt;
evt.SetZoomFactor(gesture.magnification + 1.0);
[self postEvent:evt withGesture:gesture];
}
- (void) onGestureRotate: (NSRotationGestureRecognizer*) gesture
{
wxRotateGestureEvent evt;
evt.SetRotationAngle(-gesture.rotation);
[self postEvent:evt withGesture:gesture];
}
- (void) postEvent: (wxGestureEvent &) evt withGesture: (NSGestureRecognizer* ) gesture
{
NSPoint pos = [gesture locationInView: self];
evt.SetPosition({(int) pos.x, (int) pos.y});
if (gesture.state == NSGestureRecognizerStateBegan)
evt.SetGestureStart();
else if (gesture.state == NSGestureRecognizerStateEnded)
evt.SetGestureEnd();
_gestureHandler->ProcessEvent(evt);
}
- (void) scrollWheel2:(NSEvent *)event
{
bool shiftDown = [event modifierFlags] & NSShiftKeyMask;
if (_gestureHandler && shiftDown && event.hasPreciseScrollingDeltas) {
wxPanGestureEvent evt;
evt.SetDelta({-(int)[event scrollingDeltaX], - (int)[event scrollingDeltaY]});
_gestureHandler->ProcessEvent(evt);
} else {
[self scrollWheel2: event];
}
}
+ (void) load
{
Method scrollWheel = class_getInstanceMethod([wxNSCustomOpenGLView class], @selector(scrollWheel:));
Method scrollWheel2 = class_getInstanceMethod([wxNSCustomOpenGLView class], @selector(scrollWheel2:));
method_exchangeImplementations(scrollWheel, scrollWheel2);
}
- (void) initGesturesWithHandler: (wxEvtHandler*) handler
{
// NSPanGestureRecognizer * pan = [[NSPanGestureRecognizer alloc] initWithTarget: self action: @selector(onGestureMove:)];
// pan.numberOfTouchesRequired = 2;
// pan.allowedTouchTypes = 0;
// NSMagnificationGestureRecognizer * magnification = [[NSMagnificationGestureRecognizer alloc] initWithTarget: self action: @selector(onGestureScale:)];
// NSRotationGestureRecognizer * rotation = [[NSRotationGestureRecognizer alloc] initWithTarget: self action: @selector(onGestureRotate:)];
// [self addGestureRecognizer:pan];
// [self addGestureRecognizer:magnification];
// [self addGestureRecognizer:rotation];
_gestureHandler = handler;
}
@end
namespace Slic3r {
namespace GUI {
void initGestures(void * view, wxEvtHandler * handler)
{
wxNSCustomOpenGLView * glView = (wxNSCustomOpenGLView *) view;
[glView initGesturesWithHandler: handler];
}
}
}
void StaticGroup_layoutBadge(void * group, void * badge)
{
NSView * vg = (NSView *)group;
NSView * vb = (NSView *)badge;
vb.translatesAutoresizingMaskIntoConstraints = NO;
[vg addConstraint: [NSLayoutConstraint constraintWithItem:vb attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:vg attribute:NSLayoutAttributeTop multiplier:1.0 constant:15]];
[vg addConstraint: [NSLayoutConstraint constraintWithItem:vb attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:vg attribute:NSLayoutAttributeRight multiplier:1.0 constant:-1]];
}