metaforce/Runtime/CGameOptionsTouchBarMac.mm

308 lines
12 KiB
Plaintext

#include <AppKit/AppKit.h>
#include "CGameOptionsTouchBar.hpp"
#include "CGameOptions.hpp"
#include "GameGlobalObjects.hpp"
#include "MP1/MP1.hpp"
#include "GuiSys/CStringTable.hpp"
#if !__has_feature(objc_arc)
#error ARC Required
#endif
static NSColor* BlueConfirm()
{
return [NSColor colorWithSRGBRed:0/255.f green:130/255.f blue:215/255.f alpha:1.f];
}
@interface GameOptionsTouchBar : NSObject <NSTouchBarDelegate>
{
@public
metaforce::CStringTable* _pauseScreenStrg;
metaforce::CGameOptionsTouchBar::EAction _action;
std::pair<int, int> _selection;
int _value, _pendingValue;
}
-(IBAction)onBack:(id)sender;
-(IBAction)onSlide:(id)sender;
-(IBAction)onSet0:(id)sender;
-(IBAction)onSet1:(id)sender;
-(IBAction)onSet2:(id)sender;
-(IBAction)onLeft:(id)sender;
-(IBAction)onRight:(id)sender;
@end
@implementation GameOptionsTouchBar
- (NSTouchBar*)makeTouchBar
{
NSTouchBar* touchBar = [NSTouchBar new];
touchBar.delegate = self;
id items = @[@"optionsGroup"];
touchBar.customizationRequiredItemIdentifiers = items;
touchBar.defaultItemIdentifiers = items;
touchBar.principalItemIdentifier = @"optionsGroup";
return touchBar;
}
-(NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar
makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier
{
if ([identifier isEqualToString:@"optionsGroup"])
{
NSGroupTouchBarItem* item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier];
NSTouchBar* touchBar = [NSTouchBar new];
touchBar.delegate = self;
id items;
if (_selection.first == -1)
{
items = [NSMutableArray arrayWithCapacity:5];
[items addObject:@"back"];
for (int i=0 ; i<4 ; ++i)
[items addObject:[NSString stringWithFormat:@"left/%d", i]];
}
else if (_selection.second == -1)
{
const std::pair<int, const metaforce::SGameOption*>& opt = metaforce::GameOptionsRegistry[_selection.first];
items = [NSMutableArray arrayWithCapacity:opt.first+1];
[items addObject:@"back"];
for (int i=0 ; i<opt.first ; ++i)
[items addObject:[NSString stringWithFormat:@"right/%d", i]];
}
else
{
const std::pair<int, const metaforce::SGameOption*>& opt = metaforce::GameOptionsRegistry[_selection.first];
const metaforce::SGameOption& subopt = opt.second[_selection.second];
if (subopt.type == metaforce::EOptionType::Float)
items = @[@"back", @"value"];
else if (subopt.type == metaforce::EOptionType::DoubleEnum)
items = @[@"back", @"label", @"double0", @"double1"];
else if (subopt.type == metaforce::EOptionType::TripleEnum)
items = @[@"back", @"label", @"triple0", @"triple1", @"triple2"];
}
touchBar.customizationRequiredItemIdentifiers = items;
touchBar.defaultItemIdentifiers = items;
item.groupTouchBar = touchBar;
return item;
}
else if ([identifier isEqualToString:@"back"])
{
NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSButton* button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarGoBackTemplate]
target:self action:@selector(onBack:)];
item.view = button;
return item;
}
else if ([identifier isEqualToString:@"label"])
{
const std::pair<int, const metaforce::SGameOption*>& opt = metaforce::GameOptionsRegistry[_selection.first];
const metaforce::SGameOption& subopt = opt.second[_selection.second];
const char16_t* cStr = _pauseScreenStrg->GetString(subopt.stringId);
NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()];
NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSTextField* label = [NSTextField labelWithString:[str stringByAppendingString:@":"]];
item.view = label;
return item;
}
else if ([identifier isEqualToString:@"value"])
{
const std::pair<int, const metaforce::SGameOption*>& opt = metaforce::GameOptionsRegistry[_selection.first];
const metaforce::SGameOption& subopt = opt.second[_selection.second];
const char16_t* cStr = _pauseScreenStrg->GetString(subopt.stringId);
NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()];
NSSliderTouchBarItem* item = [[NSSliderTouchBarItem alloc] initWithIdentifier:identifier];
NSSlider* slider = [NSSlider sliderWithValue:_value minValue:subopt.minVal maxValue:subopt.maxVal
target:nil action:nil];
item.target = self;
item.action = @selector(onSlide:);
item.slider = slider;
item.label = str;
return item;
}
else if ([identifier isEqualToString:@"double0"])
{
const char16_t* cStr = _pauseScreenStrg->GetString(95); // Off
NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()];
NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSButton* button = [NSButton buttonWithTitle:str target:self action:@selector(onSet0:)];
if (_value == 0)
button.bezelColor = BlueConfirm();
item.view = button;
return item;
}
else if ([identifier isEqualToString:@"double1"])
{
const char16_t* cStr = _pauseScreenStrg->GetString(94); // On
NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()];
NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSButton* button = [NSButton buttonWithTitle:str target:self action:@selector(onSet1:)];
if (_value == 1)
button.bezelColor = BlueConfirm();
item.view = button;
return item;
}
else if ([identifier isEqualToString:@"triple0"])
{
const char16_t* cStr = _pauseScreenStrg->GetString(96); // Mono
NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()];
NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSButton* button = [NSButton buttonWithTitle:str target:self action:@selector(onSet0:)];
if (_value == 0)
button.bezelColor = BlueConfirm();
item.view = button;
return item;
}
else if ([identifier isEqualToString:@"triple1"])
{
const char16_t* cStr = _pauseScreenStrg->GetString(97); // Stereo
NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()];
NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSButton* button = [NSButton buttonWithTitle:str target:self action:@selector(onSet1:)];
if (_value == 1)
button.bezelColor = BlueConfirm();
item.view = button;
return item;
}
else if ([identifier isEqualToString:@"triple2"])
{
const char16_t* cStr = _pauseScreenStrg->GetString(98); // Dolby
NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()];
NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSButton* button = [NSButton buttonWithTitle:str target:self action:@selector(onSet2:)];
if (_value == 2)
button.bezelColor = BlueConfirm();
item.view = button;
return item;
}
else
{
NSArray<NSString*>* pc = [identifier pathComponents];
if ([pc count] == 2)
{
NSString* first = [pc objectAtIndex:0];
if ([first isEqualToString:@"left"])
{
auto idx = strtoul([[pc objectAtIndex:1] UTF8String], nullptr, 10);
const char16_t* cStr = _pauseScreenStrg->GetString(16+idx);
NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()];
NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSButton* button = [NSButton buttonWithTitle:str target:self action:@selector(onLeft:)];
button.tag = idx;
item.view = button;
return item;
}
else if ([first isEqualToString:@"right"])
{
const std::pair<int, const metaforce::SGameOption*>& opt = metaforce::GameOptionsRegistry[_selection.first];
auto idx = strtoul([[pc objectAtIndex:1] UTF8String], nullptr, 10);
const metaforce::SGameOption& subopt = opt.second[idx];
const char16_t* cStr = _pauseScreenStrg->GetString(subopt.stringId);
NSString* str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()];
NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier];
NSButton* button = [NSButton buttonWithTitle:str target:self action:@selector(onRight:)];
button.tag = idx;
item.view = button;
return item;
}
}
}
return nil;
}
-(IBAction)onBack:(id)sender
{
_action = metaforce::CGameOptionsTouchBar::EAction::Back;
}
-(IBAction)onSlide:(id)sender
{
_pendingValue = [((NSSliderTouchBarItem*)sender).slider intValue];
_action = metaforce::CGameOptionsTouchBar::EAction::ValueChange;
}
-(IBAction)onSet0:(id)sender
{
_pendingValue = 0;
_action = metaforce::CGameOptionsTouchBar::EAction::ValueChange;
}
-(IBAction)onSet1:(id)sender
{
_pendingValue = 1;
_action = metaforce::CGameOptionsTouchBar::EAction::ValueChange;
}
-(IBAction)onSet2:(id)sender
{
_pendingValue = 2;
_action = metaforce::CGameOptionsTouchBar::EAction::ValueChange;
}
-(IBAction)onLeft:(id)sender
{
_selection.first = ((NSButton*)sender).tag;
_action = metaforce::CGameOptionsTouchBar::EAction::Advance;
}
-(IBAction)onRight:(id)sender
{
_selection.second = ((NSButton*)sender).tag;
_action = metaforce::CGameOptionsTouchBar::EAction::Advance;
}
@end
namespace metaforce
{
class CGameOptionsTouchBarMac : public CGameOptionsTouchBar
{
TLockedToken<CStringTable> m_pauseScreen;
GameOptionsTouchBar* m_touchBar;
bool m_initialized = false;
public:
CGameOptionsTouchBarMac()
{
m_pauseScreen = g_SimplePool->GetObj("STRG_PauseScreen");
m_touchBar = [GameOptionsTouchBar new];
m_touchBar->_pauseScreenStrg = m_pauseScreen.GetObj();
m_touchBar->_selection = std::make_pair(-1, -1);
m_touchBar->_value = -1;
}
EAction PopAction()
{
if (m_touchBar->_action != EAction::None)
{
EAction action = m_touchBar->_action;
m_touchBar->_action = EAction::None;
return action;
}
return EAction::None;
}
void GetSelection(int& left, int& right, int& value)
{
left = m_touchBar->_selection.first;
right = m_touchBar->_selection.second;
value = m_touchBar->_pendingValue;
}
void SetSelection(int left, int right, int value)
{
if (m_initialized &&
left == m_touchBar->_selection.first &&
right == m_touchBar->_selection.second &&
value == m_touchBar->_value)
return;
m_initialized = true;
m_touchBar->_selection = std::make_pair(left, right);
m_touchBar->_value = value;
g_Main->GetMainWindow()->setTouchBarProvider((__bridge_retained void*)m_touchBar);
}
};
std::unique_ptr<CGameOptionsTouchBar> NewGameOptionsTouchBar()
{
return std::make_unique<CGameOptionsTouchBarMac>();
}
}