Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hiro: add cursor auto-hide #1328

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions desktop-ui/presentation/presentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ Presentation::Presentation() {

settingsMenu.setText("Settings");
videoSizeMenu.setText("Size").setIcon(Icon::Emblem::Image);

bool hideCursorImplemented = false;
#if defined(PLATFORM_MACOS)
hideCursorImplemented = true;
#endif

//generate size menu
u32 multipliers = 5;
Expand Down Expand Up @@ -95,6 +100,14 @@ Presentation::Presentation() {
muteAudioSetting.setText("Mute Audio").setChecked(settings.audio.mute).onToggle([&] {
settings.audio.mute = muteAudioSetting.checked();
});
autoHideCursorSetting.setText("Auto-Hide Cursor").setChecked(settings.general.autoHideCursor).onToggle([&] {
settings.general.autoHideCursor = autoHideCursorSetting.checked();
settingsWindow.optionSettings.autoHideCursorOption.setChecked(settings.general.autoHideCursor);
presentation.setHidesCursor(settings.general.autoHideCursor);
});
if(!hideCursorImplemented) {
autoHideCursorSetting.setVisible(false);
}
showStatusBarSetting.setText("Show Status Bar").setChecked(settings.general.showStatusBar).onToggle([&] {
settings.general.showStatusBar = showStatusBarSetting.checked();
if(!showStatusBarSetting.checked()) {
Expand Down Expand Up @@ -227,6 +240,8 @@ Presentation::Presentation() {
}
});

setHidesCursor(settings.general.autoHideCursor);

iconLayout.setCollapsible();

iconSpacer.setCollapsible().setColor({0, 0, 0}).setDroppable().onDrop([&](auto filenames) {
Expand Down
1 change: 1 addition & 0 deletions desktop-ui/presentation/presentation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct Presentation : Window {
Group preferRegionGroup{&preferNTSCU, &preferNTSCJ, &preferPAL};
MenuSeparator groupSettingsSeparatpr{&settingsMenu};
MenuCheckItem muteAudioSetting{&settingsMenu};
MenuCheckItem autoHideCursorSetting{&settingsMenu};
MenuCheckItem showStatusBarSetting{&settingsMenu};
MenuSeparator audioSettingsSeparator{&settingsMenu};
MenuItem videoSettingsAction{&settingsMenu};
Expand Down
14 changes: 14 additions & 0 deletions desktop-ui/settings/options.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
auto OptionSettings::construct() -> void {
setCollapsible();
setVisible(false);
bool hideCursorImplemented = false;
#if defined(PLATFORM_MACOS)
hideCursorImplemented = true;
#endif

commonSettingsLabel.setText("Emulator Options").setFont(Font().setBold());

Expand Down Expand Up @@ -37,5 +41,15 @@ auto OptionSettings::construct() -> void {
});
nintendo64ExpansionPakLayout.setAlignment(1).setPadding(12_sx, 0);
nintendo64ExpansionPakHint.setText("Enable/Disable the 4MB Expansion Pak").setFont(Font().setSize(7.0)).setForegroundColor(SystemColor::Sublabel);

miscellaneousSettingsLabel.setVisible(hideCursorImplemented).setText("Miscellaneous").setFont(Font().setBold());

autoHideCursorOption.setText("Auto-Hide Cursor").setVisible(hideCursorImplemented).setChecked(settings.general.autoHideCursor).onToggle([&] {
settings.general.autoHideCursor = autoHideCursorOption.checked();
presentation.setHidesCursor(settings.general.autoHideCursor);
presentation.autoHideCursorSetting.setChecked(settings.general.autoHideCursor);
});
autoHideCursorLayout.setAlignment(1).setPadding(12_sx, 0);
autoHideCursorHint.setVisible(hideCursorImplemented).setText("Hide the mouse cursor when idle over the game window").setFont(Font().setSize(7.0)).setForegroundColor(SystemColor::Sublabel);

}
1 change: 1 addition & 0 deletions desktop-ui/settings/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ auto Settings::process(bool load) -> void {
bind(boolean, "General/RunAhead", general.runAhead);
bind(boolean, "General/AutoSaveMemory", general.autoSaveMemory);
bind(boolean, "General/HomebrewMode", general.homebrewMode);
bind(boolean, "General/AutoHideCursor", general.autoHideCursor);

bind(natural, "Rewind/Length", rewind.length);
bind(natural, "Rewind/Frequency", rewind.frequency);
Expand Down
7 changes: 6 additions & 1 deletion desktop-ui/settings/settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ struct Settings : Markup::Node {
bool runAhead = false;
bool autoSaveMemory = true;
bool homebrewMode = false;
bool autoHideCursor = true;
} general;

struct Rewind {
Expand Down Expand Up @@ -251,6 +252,10 @@ struct OptionSettings : VerticalLayout {
HorizontalLayout nintendo64ExpansionPakLayout{this, Size{~0, 0}, 5};
CheckLabel nintendo64ExpansionPakOption{&nintendo64ExpansionPakLayout, Size{0, 0}, 5};
Label nintendo64ExpansionPakHint{&nintendo64ExpansionPakLayout, Size{0, 0}};
Label miscellaneousSettingsLabel{this, Size{~0, 0}, 5};
HorizontalLayout autoHideCursorLayout{this, Size{~0, 0}, 5};
CheckLabel autoHideCursorOption{&autoHideCursorLayout, Size{0, 0}, 5};
Label autoHideCursorHint{&autoHideCursorLayout, Size{0,0}};
};

struct FirmwareSettings : VerticalLayout {
Expand Down Expand Up @@ -432,4 +437,4 @@ extern OptionSettings& optionSettings;
extern FirmwareSettings& firmwareSettings;
extern PathSettings& pathSettings;
extern DriverSettings& driverSettings;
extern DebugSettings& debugSettings;
extern DebugSettings& debugSettings;
38 changes: 38 additions & 0 deletions hiro/cocoa/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
window = &windowReference;

NSUInteger style = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;
hidesCursor = false;
cursorIsInWindow = false;
if(window->state.resizable) style |= NSResizableWindowMask;
hideCursorTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(hideCursor:) userInfo:nil repeats:YES];

if(self = [super initWithContentRect:NSMakeRect(0, 0, 640, 480) styleMask:style backing:NSBackingStoreBuffered defer:YES]) {
[self setDelegate:self];
Expand Down Expand Up @@ -137,6 +140,13 @@
return YES;
}

-(void) hideCursor:(NSTimer*)timer {
CFTimeInterval secondsSinceCursorMoved = CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGEventMouseMoved);
if(secondsSinceCursorMoved >= 2.0 && hidesCursor && cursorIsInWindow) {
[NSCursor setHiddenUntilMouseMoves:YES];
}
}

-(NSMenu*) menuBar {
return menuBar;
}
Expand Down Expand Up @@ -205,6 +215,18 @@
window->state.fullScreen = true;
}

-(void)mouseEntered:(NSEvent *)theEvent {
cursorIsInWindow = true;
}

-(void)mouseExited:(NSEvent *)theEvent {
cursorIsInWindow = false;
}

-(void)setHidesCursor:(bool)hides {
hidesCursor = hides;
}

-(void)windowDidExitFullScreen:(NSNotification *)notification {
window->state.fullScreen = false;
}
Expand Down Expand Up @@ -368,6 +390,10 @@ auto pWindow::setResizable(bool resizable) -> void {
[cocoaWindow setStyleMask:style];
}

auto pWindow::setHidesCursor(bool hidesCursor) -> void {
[cocoaWindow setHidesCursor:hidesCursor];
}

auto pWindow::setTitle(const string& text) -> void {
[cocoaWindow setTitle:[NSString stringWithUTF8String:text]];
}
Expand Down Expand Up @@ -405,6 +431,18 @@ auto pWindow::sizeEvent() -> void {
}

statusBarReposition();

NSView* theView = [cocoaWindow contentView];
NSArray* trackingAreas = theView.trackingAreas;
for (NSTrackingArea* oldArea in trackingAreas) {
[theView removeTrackingArea:oldArea];
}
NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect: theView.bounds
options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways)
owner:cocoaWindow
userInfo:nil];
[theView addTrackingArea:area];


if(!locked()) self().doSize();
}
Expand Down
11 changes: 10 additions & 1 deletion hiro/cocoa/window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,24 @@
@interface CocoaWindow : NSWindow <NSWindowDelegate> {
@public
hiro::mWindow* window;
bool hidesCursor;
bool cursorIsInWindow;
NSTimer* hideCursorTimer;
NSMenu* menuBar;
NSMenu* rootMenu;
NSMenuItem* disableGatekeeper;
NSTextField* statusBar;
NSTrackingArea* trackingArea;
}
-(id) initWith:(hiro::mWindow&)window;
-(BOOL) canBecomeKeyWindow;
-(BOOL) canBecomeMainWindow;
-(void) windowDidBecomeMain:(NSNotification*)notification;
-(void) windowDidMove:(NSNotification*)notification;
-(void) windowDidResize:(NSNotification*)notification;
-(void) mouseEntered:(NSEvent*)theEvent;
-(void) mouseExited:(NSEvent*)theEvent;
-(void) setHidesCursor:(bool)hidesCursor;
-(BOOL) windowShouldClose:(id)sender;
-(NSDragOperation) draggingEntered:(id<NSDraggingInfo>)sender;
-(BOOL) performDragOperation:(id<NSDraggingInfo>)sender;
Expand All @@ -23,6 +30,7 @@
-(void) menuDisableGatekeeper;
-(void) menuQuit;
-(NSTextField*) statusBar;
-(void) hideCursor:(NSTimer*)timer;
@end

namespace hiro {
Expand Down Expand Up @@ -55,7 +63,8 @@ struct pWindow : pObject {
auto setTitle(const string& text) -> void;
auto setAssociatedFile(const string& filename) -> void;
auto setVisible(bool visible) -> void;

auto setHidesCursor(bool hidesCursor) -> void;

auto moveEvent() -> void;
auto sizeEvent() -> void;
auto statusBarHeight() -> u32;
Expand Down
2 changes: 2 additions & 0 deletions hiro/core/shared.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,7 @@ struct Window : sWindow {
auto remove(sStatusBar statusBar) { return self().remove(statusBar), *this; }
auto reset() { return self().reset(), *this; }
auto resizable() const { return self().resizable(); }
auto hidesCursor() const { return self().hidesCursor(); }
auto setAlignment(Alignment alignment = Alignment::Center) { return self().setAlignment(alignment), *this; }
auto setAlignment(sWindow relativeTo, Alignment alignment = Alignment::Center) { return self().setAlignment(relativeTo, alignment), *this; }
auto setBackgroundColor(Color color = {}) { return self().setBackgroundColor(color), *this; }
Expand All @@ -953,6 +954,7 @@ struct Window : sWindow {
auto setPosition(Position position) { return self().setPosition(position), *this; }
auto setPosition(sWindow relativeTo, Position position) { return self().setPosition(relativeTo, position), *this; }
auto setResizable(bool resizable = true) { return self().setResizable(resizable), *this; }
auto setHidesCursor(bool hidesCursor = true) { return self().setHidesCursor(hidesCursor), *this; }
auto setSize(Size size) { return self().setSize(size), *this; }
auto setTitle(const string& title = "") { return self().setTitle(title), *this; }
auto setAssociatedFile(const string& filename = "") { return self().setAssociatedFile(filename), *this; }
Expand Down
10 changes: 10 additions & 0 deletions hiro/core/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ auto mWindow::resizable() const -> bool {
return state.resizable;
}

auto mWindow::hidesCursor() const -> bool {
return state.hidesCursor;
}

auto mWindow::setAlignment(Alignment alignment) -> type& {
auto workspace = Monitor::workspace();
auto geometry = frameGeometry();
Expand Down Expand Up @@ -349,6 +353,12 @@ auto mWindow::setResizable(bool resizable) -> type& {
return *this;
}

auto mWindow::setHidesCursor(bool hidesCursor) -> type& {
state.hidesCursor = hidesCursor;
signal(setHidesCursor, hidesCursor);
return *this;
}

auto mWindow::setSize(Size size) -> type& {
return setGeometry({
state.geometry.x(), state.geometry.y(),
Expand Down
3 changes: 3 additions & 0 deletions hiro/core/window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct mWindow : mObject {
auto remove(sStatusBar statusBar) -> type&;
auto reset() -> type& override;
auto resizable() const -> bool;
auto hidesCursor() const -> bool;
auto setAlignment(Alignment = Alignment::Center) -> type&;
auto setAlignment(sWindow relativeTo, Alignment = Alignment::Center) -> type&;
auto setBackgroundColor(Color color = {}) -> type&;
Expand All @@ -58,6 +59,7 @@ struct mWindow : mObject {
auto setPosition(Position) -> type&;
auto setPosition(sWindow relativeTo, Position) -> type&;
auto setResizable(bool resizable = true) -> type&;
auto setHidesCursor(bool hidesCursor = true) -> type&;
auto setSize(Size size) -> type&;
auto setTitle(const string& title = "") -> type&;
auto setAssociatedFile(const string& filename = "") -> type&;
Expand Down Expand Up @@ -89,6 +91,7 @@ struct mWindow : mObject {
sSizable sizable;
sStatusBar statusBar;
string title;
bool hidesCursor;
} state;

auto destruct() -> void override;
Expand Down