RIG Settings Window Controller Overview | Generated by AI
Overview
This Objective-C code implements the RIGSettingWindowController class, which manages a settings window for the “Reveal-In-GitHub” (RIG) macOS app (likely an Xcode plugin for quickly revealing selected code in GitHub repositories). The window allows users to configure custom menu items, keyboard shortcuts, and regex patterns for different GitHub repos. It uses a table-like view (RIGConfigCellsView) to display and edit up to 10 config slots (padded with empties for UI consistency).
The class conforms to NSTableViewDataSource and NSTableViewDelegate protocols, suggesting it handles data and events for a table view inside the custom cells view. It integrates with app-wide singletons like RIGSetting for persistence and RIGUtils for UI feedback.
Key responsibilities:
- Load and display configurable items (e.g., menu titles, shortcut keys, regex patterns).
- Validate and save changes.
- Provide buttons for saving, clearing default repo settings, and resetting to defaults.
Imports and Defines
#import "RIGSettingWindowController.h"
#import "RIGConfigCellsView.h"
#import "RIGConfig.h"
#import "RIGPlugin.h"
#import "RIGUtils.h"
#import "RIGSetting.h"
#define kOutterXMargin 0
#define kOutterYMargin 0
- Imports pull in the header for this class, a custom view for rendering config rows (
RIGConfigCellsView), model objects (RIGConfigfor individual settings,RIGSettingfor app-wide storage), and utilities (RIGUtilsfor alerts,RIGPluginpossibly for plugin lifecycle). - Defines set zero margins for full-width layout of the config view inside the window.
Private Interface
@interface RIGSettingWindowController ()<NSTableViewDataSource, NSTableViewDelegate>
@property (nonatomic, strong) NSArray *configs;
@property (nonatomic, strong) RIGConfigCellsView *configCellsView;
@property (weak) IBOutlet NSView *mainView;
@property (weak) IBOutlet NSView *configsView;
@end
- Declares a private extension for internal properties and protocol conformance.
configs: Array ofRIGConfigobjects holding the user’s settings (e.g., menu title, last key pressed, regex pattern).configCellsView: Custom view that renders the configs as editable rows (likely a scrollable table or stack of cells).mainViewandconfigsView: IBOutlets to container views in the storyboard/nib file;configsViewhosts the dynamic cells.
Implementation
Initialization Methods
- (void)awakeFromNib {
[super awakeFromNib];
}
- (void)windowDidLoad {
[super windowDidLoad];
self.configs = [self displayConfigs];
self.configCellsView = [[RIGConfigCellsView alloc] initWithFrame:CGRectMake(kOutterXMargin, kOutterYMargin, CGRectGetWidth(self.configsView.frame) - 2 * kOutterXMargin, [RIGConfigCellsView heightForConfigs:self.configs])];
self.configCellsView.configs = self.configs;
[self.configsView addSubview:self.configCellsView];
[self.configCellsView reloadData];
}
awakeFromNib: Empty override; called when the window loads from the nib (storyboard). Just chains to superclass.windowDidLoad: Core setup after the window is fully loaded.- Loads
configsviadisplayConfigs(explained below). - Creates
configCellsViewwith a frame that fillsconfigsViewhorizontally (using margins) and vertically based on the total height needed for all configs (computed byRIGConfigCellsViewclass method). - Assigns configs to the view, adds it as a subview, and triggers a data reload (likely refreshes the table cells).
- Loads
There’s a commented-out call to updateConfigsViewHeight, which suggests dynamic resizing was considered but disabled—possibly because the cells view auto-sizes or the window is fixed.
- (void)updateConfigsViewHeight {
CGRect frame = self.configsView.frame;
frame.size.height = CGRectGetHeight(self.configCellsView.frame);
self.configsView.frame = frame;
}
- Utility to resize
configsViewto match the cells view’s height. Not currently used, but could be for auto-growing the window if more configs are added.
Config Management
- (NSMutableArray *)displayConfigs {
NSMutableArray *configs = [NSMutableArray arrayWithArray:[RIGSetting setting].configs];
while (configs.count < 10) {
RIGConfig *config = [[RIGConfig alloc] init];
config.menuTitle = @"";
config.lastKey = @"";
config.pattern = @"";
[configs addObject:config];
}
return configs;
}
- Loads existing configs from the app’s singleton
RIGSetting. - Pads the array to exactly 10 items with blank
RIGConfiginstances. This ensures a consistent UI (e.g., 10 editable rows), even if the user has fewer saved configs. Empty ones are filtered out on save.
- (void)reloadConfigs {
self.configs = [self displayConfigs];
self.configCellsView.configs = self.configs;
[self.configCellsView reloadData];
}
- Refreshes the displayed configs from storage and updates the view. Used after resets.
- (BOOL)isValidConfigs:(NSArray *)configs {
for (RIGConfig *config in configs) {
if (![config isValid]) {
return NO;
}
}
return YES;
}
- Iterates over configs and calls
isValidon each (likely checks for non-emptymenuTitleandpattern). ReturnsYESonly if all are valid or empty (but see filtering below).
- (NSArray *)filteredConfigs {
NSMutableArray *filtered = [NSMutableArray array];
NSArray *configs = self.configCellsView.configs;
for (RIGConfig *config in configs) {
if (config.menuTitle.length > 0 || config.lastKey.length > 0 || config.pattern.length > 0) {
[filtered addObject:config];
}
}
return filtered;
}
- Filters the 10-slot array to include only non-empty configs (based on any field having content). This strips blanks before validation/saving, so
isValidConfigsonly checks real entries.
Action Handlers (IBActions)
These are connected to buttons in the UI via Interface Builder.
- (IBAction)saveButtonClcked:(id)sender {
NSArray *configs = [self filteredConfigs];
if (![self isValidConfigs:configs]) {
[RIGUtils showMessage:@"Please complete the config, should at least have menuTitle and pattern."];
return;
}
[RIGSetting setting].configs = self.configCellsView.configs;
[RIGUtils showMessage:@"Save succeed. Will Take effect when reopen Xcode."];
}
- Save Button: Filters configs, validates them (error alert if invalid), then saves the full (padded) array back to
RIGSetting. Note: It saves the full 10 slots, but blanks are ignored on load/filter. Shows success message noting a Xcode restart is needed (plugin reload).
Typo in method name: “Clcked” should be “Clicked”.
- (IBAction)clearButtonClicked:(id)sender {
RIGSetting *setting = [RIGSetting settingForGitPath:self.gitRepo.localPath];
NSString *defaultRepo = setting.defaultRepo;
if (defaultRepo == nil) {
[RIGUtils showMessage:@"There's no default repo setting."];
} else {
setting.defaultRepo = nil;
[RIGUtils showMessage:[NSString stringWithFormat:@"Succeed to clear current default repo(%@) setting. In the next time to open github, will ask you to select new default repo.", defaultRepo]];
}
}
- Clear Button: Targets a project-specific setting via
settingForGitPath(assumesself.gitRepois available, possibly set elsewhere). Clears thedefaultRepo(e.g., a fallback GitHub URL). Alerts if none set, or confirms clearance with details.
Note: self.gitRepo isn’t declared here—likely a property from a superclass or category.
- (IBAction)resetMenusButtonClicked:(id)sender {
[[RIGSetting setting] setConfigs:[RIGSetting defaultConfigs]];
[self reloadConfigs];
}
- Reset Button: Overwrites configs with app defaults (from
RIGSetting), then reloads the UI. No confirmation dialog—direct action.
Potential Improvements/Notes
- UI Flow: The window is non-modal (no explicit show calls here), so it’s probably presented via
[controller showWindow:sender]. Changes require Xcode restart due to plugin nature. - Validation: Relies on
RIGConfig.isValid, which isn’t shown—likely ensures required fields like title and pattern are non-empty. - Edge Cases: Padding to 10 assumes a fixed UI; dynamic sizing could use the commented
updateConfigsViewHeight. No undo/confirm for reset/clear. - Dependencies: Heavily tied to app models (
RIGConfig,RIGSetting)—full understanding needs those headers.
This code is from 2015, so it uses older Cocoa patterns (e.g., manual frame setup over Auto Layout). For modern SwiftUI, it’d be a View with @State for configs.