Skip to content
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
5 changes: 5 additions & 0 deletions packages/uhk-common/src/models/application-settings.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { MacroGroupingSettings } from './macro-grouping-settings.js';
import { RgbColorInterface } from './rgb-color-interface.js';

export enum AppTheme {
Expand Down Expand Up @@ -34,4 +35,8 @@ export interface ApplicationSettings {
* If true, the Advanced settings menu is shown on Agent startup.
*/
alwaysEnableAdvancedMode?: boolean;
/**
* Sidebar macro grouping preferences.
*/
macroGrouping?: Partial<MacroGroupingSettings>;
}
1 change: 1 addition & 0 deletions packages/uhk-common/src/models/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './application-settings.js';
export * from './macro-grouping-settings.js';
export * from './backup-user-configuration.js';
export * from './backup-user-configuration-info.js';
export * from './ble-address-pair.js';
Expand Down
15 changes: 15 additions & 0 deletions packages/uhk-common/src/models/macro-grouping-settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export interface MacroGroupingSettings {
camelCaseSeparation: boolean;
enabled: boolean;
maxDepth: number;
minChildren: number;
}

export const MACRO_GROUPING_MIN_DEPTH = 1;

export const DEFAULT_MACRO_GROUPING_SETTINGS: MacroGroupingSettings = {
camelCaseSeparation: false,
enabled: false,
maxDepth: 1,
minChildren: 2,
};
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,8 @@ <h1>
</div>
</div>


<div class="col-12 col-md-6 mb-0 mt-0">
<div class="d-flex align-items-center mt-2">
<div class="col-12 col-md-6 mb-0 mt-2">
<div class="d-flex align-items-center">
<label class="mb-0 me-2">Theme</label>
<ng-select
class="theme-selector"
Expand All @@ -69,6 +68,64 @@ <h1>
<button type="button" class="btn btn-link px-0" (click)="openConfigFolder()">Open configuration folder</button>
</div>

<div class="col-12 mt-3" *ngIf="macroGroupingSettings$ | async as macroGroupingSettings">
<h2 class="h5">Macro sidebar grouping</h2>
<div class="macro-grouping-checkbox mt-0">
<div class="checkbox mb-0">
<label>
<input type="checkbox"
[checked]="macroGroupingSettings.enabled"
(change)="updateMacroGroupingSettings({ enabled: $event.target.checked })"
> Group macros in the sidebar
</label>
</div>
<circle-tooltip
tooltip="Turns sidebar grouping on or off. When enabled, macros are sorted into collapsible folders by splitting names at non-alphanumeric characters, such as colons, underscores, hyphens, and spaces. For example, Doom: Chainsaw and Doom_Plasma gun appear under a Doom folder. When disabled, macros are shown as a flat alphabetical list. Only the sidebar layout changes; macro names in your configuration stay the same."
[width]="420"
/>
</div>
<div class="macro-grouping-dependent-options"
[class.macro-grouping-dependent-options--disabled]="!macroGroupingSettings.enabled">
<div class="macro-grouping-checkbox mt-1">
<div class="checkbox mb-0">
<label>
<input type="checkbox"
[checked]="macroGroupingSettings.camelCaseSeparation"
[disabled]="!macroGroupingSettings.enabled"
(change)="updateMacroGroupingSettings({ camelCaseSeparation: $event.target.checked })"
> Split camel case macro names
</label>
</div>
<circle-tooltip
tooltip="Requires Group macros in the sidebar. Adds a second splitting rule on top of non-alphanumeric separators: camelCase boundaries within each name segment. For example, bindMouseLeft and bindMouseRight are grouped under bind. Use this if you name macros in camelCase without non-alphanumeric separators. Leave off if camelCase names should stay whole, such as when the full name is a single identifier used by macro commands."
[width]="420"
/>
</div>
<div class="macro-grouping-inline-option mt-1">
<label class="mb-0" for="macro-grouping-max-depth">Maximum nesting depth:</label>
<input id="macro-grouping-max-depth"
type="number"
class="form-control macro-grouping-number-input"
min="1"
[max]="macroGroupingMaxDepth"
[disabled]="!macroGroupingSettings.enabled"
[ngModel]="macroGroupingSettings.maxDepth"
(ngModelChange)="updateMacroGroupingSettings({ maxDepth: +$event })">
</div>
<div class="macro-grouping-inline-option mt-1">
<label class="mb-0" for="macro-grouping-min-children">Minimum macros per group:</label>
<input id="macro-grouping-min-children"
type="number"
class="form-control macro-grouping-number-input"
min="2"
max="10"
[disabled]="!macroGroupingSettings.enabled"
[ngModel]="macroGroupingSettings.minChildren"
(ngModelChange)="updateMacroGroupingSettings({ minChildren: +$event })">
</div>
</div>
</div>

<ng-template #systemThemeTooltip>
<p class="text-start mb-0">The <strong>Follow operating system theme</strong> option may not be supported on all Linux distributions.</p>
</ng-template>
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
h1 {
margin-bottom: 1rem;
}

.theme-selector {
min-width: 230px;
}

.macro-grouping-number-input {
width: 4rem;
}

.macro-grouping-checkbox {
align-items: center;
display: flex;
gap: 0.375rem;
}

.macro-grouping-inline-option {
align-items: center;
display: flex;
gap: 0.5rem;
}

.macro-grouping-dependent-options--disabled {
opacity: 0.55;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,26 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { faCog } from '@fortawesome/free-solid-svg-icons';

import { AppTheme, AppThemeSelect } from 'uhk-common';
import { AppTheme, AppThemeSelect, MacroGroupingSettings } from 'uhk-common';
import {
AppState,
appUpdateSettingsState,
getAlwaysEnableAdvancedMode,
getAnimationEnabled,
getAppTheme,
getIsAdvancedSettingsMenuVisible,
getMacroGroupingSettings,
getOperatingSystem,
getSupportedThemes,
keyboardHalvesAlwaysJoined
} from '../../../store';
import { MACRO_GROUPING_MAX_DEPTH } from '../../../util/group-macros-by-name';
import { State as UpdateSettingsState } from '../../../store/reducers/auto-update-settings';
import {
CheckForUpdateNowAction,
ToggleCheckForUpdateOnStartupAction
} from '../../../store/actions/auto-update-settings';
import { OpenConfigFolderAction, SetAppThemeAction, ToggleAnimationEnabledAction, ToggleKeyboardHalvesAlwaysJoinedAction } from '../../../store/actions/app';
import { OpenConfigFolderAction, SetAppThemeAction, SetMacroGroupingSettingsAction, ToggleAnimationEnabledAction, ToggleKeyboardHalvesAlwaysJoinedAction } from '../../../store/actions/app';
import { ToggleAlwaysEnableAdvancedModeAction } from '../../../store/actions/advance-settings.action';
import { OperatingSystem } from '../../../models/operating-system';

Expand All @@ -44,6 +46,8 @@ export class SettingsComponent {
keyboardHalvesAlwaysJoined$: Observable<boolean>;
alwaysEnableAdvancedMode$: Observable<boolean>;
alwaysEnableAdvancedModeSettingVisible$: Observable<boolean>;
macroGroupingSettings$: Observable<MacroGroupingSettings>;
macroGroupingMaxDepth = MACRO_GROUPING_MAX_DEPTH;

constructor(private store: Store<AppState>) {
this.updateSettingsState$ = store.select(appUpdateSettingsState);
Expand All @@ -54,6 +58,7 @@ export class SettingsComponent {
this.keyboardHalvesAlwaysJoined$ = store.select(keyboardHalvesAlwaysJoined);
this.alwaysEnableAdvancedMode$ = store.select(getAlwaysEnableAdvancedMode);
this.alwaysEnableAdvancedModeSettingVisible$ = store.select(getIsAdvancedSettingsMenuVisible);
this.macroGroupingSettings$ = store.select(getMacroGroupingSettings);
}

openConfigFolder(): void {
Expand Down Expand Up @@ -84,4 +89,8 @@ export class SettingsComponent {
this.store.dispatch(new ToggleAlwaysEnableAdvancedModeAction(enabled));
}

updateMacroGroupingSettings(settings: Partial<MacroGroupingSettings>): void {
this.store.dispatch(new SetMacroGroupingSettingsAction(settings));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
.col-controls {
min-width: 145px;
text-align: right;
white-space: nowrap;

&.arguments {
fa-icon {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,23 +221,40 @@
class="chevron float-end me-1"
(click)="toggleMenuItem('macro')"></fa-icon>
</div>
<ul [@toggler]="this.sideMenuState.macro.animation">
<li *ngFor="let macro of state.macros" class="sidebar__level-2--item">
<div class="sidebar__level-2" [routerLinkActive]="['active']">
<a [routerLink]="['/macro', macro.id]"
[class.disabled]="state.updatingFirmware">{{macro.name}}</a>
<span class="sidebar__macro_count badge rounded-pill"
ngbTooltip="This is the number of times the macro is used across all keymaps."
placement="bottom"
container="body">{{ macro.usageCount }}</span>
</div>
</li>
<ul class="sidebar__macro-tree" [@toggler]="this.sideMenuState.macro.animation">
<ng-container *ngTemplateOutlet="macroTree; context: { $implicit: state.macroTree }"></ng-container>
</ul>
</li>
</ul>
</li>
</ul>

<ng-template #macroTree let-nodes>
<ng-container *ngFor="let node of nodes">
<li *ngIf="node.type === 'macro'" class="sidebar__macro-tree-item">
<div class="sidebar__macro-tree-entry" [routerLinkActive]="['active']">
<a [routerLink]="['/macro', node.macro.id]"
[class.disabled]="state.updatingFirmware">{{ node.macro.name }}</a>
<span class="sidebar__macro_count badge rounded-pill"
ngbTooltip="This is the number of times the macro is used across all keymaps."
placement="bottom"
container="body">{{ node.macro.usageCount }}</span>
</div>
</li>
<li *ngIf="node.type === 'group'" class="sidebar__macro-tree-item">
<div class="sidebar__macro-tree-entry sidebar__macro-group"
(click)="toggleMacroGroup(node.path)">
{{ node.label }}…
<fa-icon [icon]="getMacroGroupArrowIcon(node.path)"
class="sidebar__macro-group-arrow"></fa-icon>
</div>
<ul class="sidebar__macro-group-children" [@toggler]="getMacroGroupState(node.path).animation">
<ng-container *ngTemplateOutlet="macroTree; context: { $implicit: node.children }"></ng-container>
</ul>
</li>
</ng-container>
</ng-template>

<ul class="menu--bottom">
<li class="menu--bottom__item">
<a [routerLink]="['/settings']"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
$level-0-item-spacing: 0.5rem 0.5rem;
$level-1-item-spacing: 0.25rem 1rem 0.25rem 1.5rem;
$level-2-item-spacing: 0.125rem 0 0.125rem 2rem;
$macro-tree-base-indent: 2rem;
$macro-tree-indent-step: 0.75rem;
// Keep MACRO_GROUPING_MAX_DEPTH in util/group-macros-by-name.ts in sync with these layout values.

:host {
background-color: var(--color-sidemenu-bg);
Expand Down Expand Up @@ -139,10 +142,73 @@ ul {
}
}

// Indentation is purely structural: it comes from the nested <ul> lists, not
// from any per-leaf padding. The root list supplies the base indent and each
// nested group list adds one step, so depth accumulates through the DOM.
&__macro-tree-entry {
padding: 0.125rem 0;
}

&__macro-tree {
width: auto;
margin-left: $macro-tree-base-indent;
}

&__macro-group-children {
width: auto;
padding-left: $macro-tree-indent-step;
border-left: 1px solid silver;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I havent checked out the PR just looked into it. Is this silver looks goon in light and dark mode? Should not we use a predefined "silver" color?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the silver color does look good in light and dark modes alike.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not we use a predefined "silver" color?

We definitely should.

}

&__macro-tree-item {
position: relative;

&.active,
.active {
background-color: var(--color-sidemenu-active-bg);
color: var(--color-sidemenu-active-text);

a {
color: var(--color-sidemenu-active-text);
}

&:hover {
background-color: var(--color-sidemenu-active-bg);
}
}

&:hover {
cursor: pointer;
}

a {
display: block;
width: 100%;

&.disabled {
opacity: 0.65;
}
}
}

&__macro-group {
cursor: pointer;
font-weight: 500;

&-arrow {
float: right;
font-size: 0.65rem;
line-height: inherit;
margin-right: 0.25rem;
opacity: 0.45;
}
}

// General hover over menu items.
&__level-0,
&__level-1,
&__level-2 {
&__level-2,
&__macro-tree-entry {
&:hover {
background-color: var(--color-hover-link-color);

Expand Down
Loading