Skip to content

Commit

Permalink
feat(ui): separate map mode controls from other map settings
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelMakesGames committed Sep 9, 2024
1 parent 1ab0ba0 commit 53aebc0
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 50 deletions.
7 changes: 7 additions & 0 deletions src/renderer/src/lib/SettingControl/index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import StrokeSettingControl from './StrokeSettingControl.svelte';
export let settings: Writable<Record<string, any>>;
export let writeToSettings: Writable<Record<string, any>>[] = [];
export let config: UnknownSettingConfig;
let value: any = get(settings)[config.id];
Expand All @@ -31,6 +32,12 @@
...prev,
[config.id]: value,
}));
for (const otherSettings of writeToSettings) {
otherSettings.update((prev) => ({
...prev,
[config.id]: value,
}));
}
}
}
Expand Down
28 changes: 24 additions & 4 deletions src/renderer/src/lib/Sidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import {
applyMapSettings,
asUnknownSettingConfig,
copyGroupSettings,
countryOptions,
editedMapSettings,
lastProcessedMapSettings,
Expand Down Expand Up @@ -160,7 +161,12 @@
? presetMapSettings.find((preset) => preset.name === loadedSettingsName)
: $customSavedSettings.find((saved) => saved.name === loadedSettingsName);
let confirmed = true;
if (!loadedSettings || settingsAreDifferent(loadedSettings.settings, $editedMapSettings)) {
if (
!loadedSettings ||
settingsAreDifferent(loadedSettings.settings, $editedMapSettings, {
excludeGroups: ['mapMode'],
})
) {
confirmed = await new Promise<boolean>((resolve) => {
modalStore.trigger({
type: 'confirm',
Expand All @@ -172,8 +178,12 @@
}
if (confirmed) {
loadedSettingsKey.set(`${type}|${savedSettings.name}`);
if (settingsAreDifferent(savedSettings.settings, $mapSettings)) {
const validated = validateAndResetMapSettings(savedSettings.settings);
if (
settingsAreDifferent(savedSettings.settings, $mapSettings, { excludeGroups: ['mapMode'] })
) {
const validated = validateAndResetMapSettings(
copyGroupSettings('mapMode', $editedMapSettings, savedSettings.settings),
);
editedMapSettings.set(validated);
mapSettings.set(validated);
lastProcessedMapSettings.set(validated);
Expand Down Expand Up @@ -271,6 +281,16 @@
</button>
</form>

<div class="flex-column my-3 flex-col space-y-2 px-4">
{#each mapSettingsConfig[0]?.settings ?? [] as config (config.id)}
<SettingControl
config={asUnknownSettingConfig(config)}
settings={editedMapSettings}
writeToSettings={[mapSettings, lastProcessedMapSettings]}
/>
{/each}
</div>

<div class="flex items-baseline p-4 pb-1" style="transition-duration: 50ms;">
<h2 class="h3 flex-1">{$t('side_bar.map_settings')}</h2>
<button type="button" class="mx-2 text-primary-500" on:click={saveSettings}>
Expand Down Expand Up @@ -354,7 +374,7 @@

<div class="flex-shrink flex-grow overflow-y-auto">
<Accordion spacing="space-y-2">
{#each mapSettingsConfig as settingGroup (settingGroup.id)}
{#each mapSettingsConfig.slice(1) as settingGroup (settingGroup.id)}
<AccordionItem regionPanel="space-y-6">
<svelte:fragment slot="summary">
<h3 class="h4 font-bold">
Expand Down
25 changes: 12 additions & 13 deletions src/renderer/src/lib/map/MapContainer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import Legend from './Legend.svelte';
import Map from './Map.svelte';
import MapTooltip from './MapTooltip.svelte';
import { mapModes } from './data/mapModes';
import processMapData from './data/processMapData';
import { getBackgroundColor } from './mapUtils';
import SolarSystemMap from './solarSystemMap/SolarSystemMap.svelte';
Expand Down Expand Up @@ -397,6 +398,7 @@
function onMapClick(e: MouseEvent) {
if (e.shiftKey) {
if (!mapModes[$mapSettings.mapMode]?.hasPov) return;
const countryId = tooltip?.countryId;
if (countryId != null) {
editedMapSettings.update((value) => ({
Expand All @@ -410,18 +412,19 @@
}));
}
} else {
if (tooltip?.hidden) return;
openedSystem = tooltip?.system;
}
}
</script>

<div class="relative h-full w-full" style:background={bg} bind:this={container}>
{#if dataOrNull && colorsOrNull && openedSystem == null}
<div class="absolute left-0 top-16">
<div class="absolute left-3 top-3">
<Legend data={dataOrNull} colors={colorsOrNull}></Legend>
</div>
{/if}
<div class="absolute left-3 top-3 flex gap-3">
<div class="absolute right-3 top-3 flex gap-3">
{#if openedSystem}
<button type="button" class="variant-filled btn" on:click={closeSystemMap}>
{$t('generic.back_button')}
Expand All @@ -432,17 +435,12 @@
<HeroiconArrowsPointingOut />
</button>
{/if}
{#if dataOrNull}
<button type="button" class="variant-filled btn" transition:fade on:click={openExportModal}>
{$t('export.button')}
</button>
{/if}
</div>
{#if dataOrNull}
<button
type="button"
class="variant-filled btn absolute right-3 top-3"
transition:fade
on:click={openExportModal}
>
{$t('export.button')}
</button>
{/if}
{#if tooltip != null && openedSystem == null && !tooltip.hidden && !zooming && !resizing}
<div class="pointer-events-none absolute left-0 top-0 h-full w-full overflow-hidden">
<MapTooltip
Expand Down Expand Up @@ -511,7 +509,8 @@
}}
on:click={onMapClick}
class:hidden={openedSystem != null}
class:cursor-pointer={tooltip?.countryId != null}
class:cursor-pointer={(mapModes[$mapSettings.mapMode]?.hasPov && tooltip?.countryId) ||
(tooltip != null && !tooltip.hidden)}
class="h-full w-full"
>
<g transform={transform?.toString()}>
Expand Down
79 changes: 49 additions & 30 deletions src/renderer/src/lib/map/SystemIcons.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,41 @@
}
</script>

{#each getMapModeIcons(data.systems) as system}
{#each data.systems
.filter((s) => s.systemIsKnown || !$mapSettings.terraIncognita)
.map((s) => getSystemIcons(s, $mapSettings)) as systemIcons}
{#each [...(systemIcons.center ? [systemIcons.center] : []), ...systemIcons.left, ...systemIcons.right, ...systemIcons.top, ...systemIcons.bottom] as systemIcon}
<use
href="#{systemIcon.icon}"
x={systemIcon.x - systemIcon.size / 2}
y={systemIcon.y - systemIcon.size / 2}
width={systemIcon.size}
height={systemIcon.size}
{...getFillColorAttributes({
mapSettings: $mapSettings,
colors,
countryColors: systemIcons.system,
colorStack: [systemIcon.color, $mapSettings.borderFillColor],
})}
/>
{/each}
{#if shouldShowLabel(systemIcons.system)}
<text
x={systemIcons.system.x}
y={getIconsBottom(systemIcons) + $mapSettings.systemNamesFontSize / 4}
text-anchor="middle"
dominant-baseline="hanging"
font-size={$mapSettings.systemNamesFontSize}
fill="white"
font-family={$mapSettings.systemNamesFont}
style:text-shadow="0px 0px 3px black"
>
{systemIcons.system.name}
</text>
{/if}
{/each}

{#each getMapModeIcons(data.systems.filter((s) => s.systemIsKnown || !$mapSettings.terraIncognita)) as system}
{#if system.arcs.length <= 1}
<circle
cx={system.x}
Expand Down Expand Up @@ -199,36 +233,21 @@
stroke={colors.black}
/>
{/each}

{#each data.systems
.filter((s) => s.systemIsKnown || !$mapSettings.terraIncognita)
.filter(shouldShowLabel)
.map((s) => getSystemIcons(s, $mapSettings)) as systemIcons}
{#each [...(systemIcons.center ? [systemIcons.center] : []), ...systemIcons.left, ...systemIcons.right, ...systemIcons.top, ...systemIcons.bottom] as systemIcon}
<use
href="#{systemIcon.icon}"
x={systemIcon.x - systemIcon.size / 2}
y={systemIcon.y - systemIcon.size / 2}
width={systemIcon.size}
height={systemIcon.size}
{...getFillColorAttributes({
mapSettings: $mapSettings,
colors,
countryColors: systemIcons.system,
colorStack: [systemIcon.color, $mapSettings.borderFillColor],
})}
/>
{/each}
{#if shouldShowLabel(systemIcons.system)}
<text
x={systemIcons.system.x}
y={getIconsBottom(systemIcons) + $mapSettings.systemNamesFontSize / 4}
text-anchor="middle"
dominant-baseline="hanging"
font-size={$mapSettings.systemNamesFontSize}
fill="white"
font-family={$mapSettings.systemNamesFont}
style:text-shadow="0px 0px 3px black"
>
{systemIcons.system.name}
</text>
{/if}
<text
x={systemIcons.system.x}
y={getIconsBottom(systemIcons) + $mapSettings.systemNamesFontSize / 4}
text-anchor="middle"
dominant-baseline="hanging"
font-size={$mapSettings.systemNamesFontSize}
fill="white"
font-family={$mapSettings.systemNamesFont}
style:text-shadow="0px 0px 3px black"
>
{systemIcons.system.name}
</text>
{/each}
5 changes: 5 additions & 0 deletions src/renderer/src/lib/map/data/mapModes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ interface MapMode {
tooltipLabel?: MessageID;
country?: MapModeBorder[];
system?: MapModeSystem;
hasPov?: boolean;
hasSpecies?: boolean;
}

interface MapModeBorder {
Expand Down Expand Up @@ -47,6 +49,7 @@ export const mapModes: Record<string, MapMode> = {
id: 'wars',
name: 'map_mode.wars.name',
tooltipLabel: 'map_mode.wars.tooltip_label',
hasPov: true,
country: [
{
label: 'map_mode.common.selected_country',
Expand Down Expand Up @@ -175,6 +178,7 @@ export const mapModes: Record<string, MapMode> = {
id: 'populationSpecies',
name: 'map_mode.population.name_species',
tooltipLabel: 'map_mode.population.tooltip_label',
hasSpecies: true,
country: [
{
label: null,
Expand Down Expand Up @@ -244,6 +248,7 @@ export const mapModes: Record<string, MapMode> = {
id: 'fleetPowerAlliedAndHostile',
name: 'map_mode.fleet_power.name_allied_and_hostile',
tooltipLabel: 'map_mode.fleet_power.tooltip_label',
hasPov: true,
country: [
{
label: null,
Expand Down
2 changes: 2 additions & 0 deletions src/renderer/src/lib/settings/mapSettingsConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ export const mapSettingsConfig: MapSettingConfigGroup[] = [
options: [{ id: 'player', name: 'option.country.player' }],
dynamicOptions: countryOptions,
requiresReprocessing: true,
hideIf: (settings) => !mapModes[settings.mapMode]?.hasPov,
},
{
id: 'mapModeSpecies',
type: 'select',
options: [{ id: 'player', name: 'option.country.player' }],
dynamicOptions: speciesOptions,
requiresReprocessing: true,
hideIf: (settings) => !mapModes[settings.mapMode]?.hasSpecies,
},
],
},
Expand Down
27 changes: 24 additions & 3 deletions src/renderer/src/lib/settings/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import { colorSettingSchema } from './ColorSetting';
import { iconSettingSchema } from './IconSetting';
import { defaultMapSettings, type MapSettings } from './mapSettings';
import { mapSettingsConfig } from './mapSettingsConfig';
import type { UnknownSettingConfig } from './SettingConfig';
import type { AppSettingConfig, MapSettingConfig } from './SettingConfig';
import type { AppSettingConfig, MapSettingConfig, UnknownSettingConfig } from './SettingConfig';
import { strokeSettingSchema } from './StrokeSetting';

export function isColorDynamic(color: string, settings: MapSettings): boolean {
Expand Down Expand Up @@ -46,6 +45,22 @@ export function validateAndResetMapSettings(unvalidatedSettings: MapSettings): M
return settings;
}

export function copyGroupSettings(
groupId: string,
fromSettings: MapSettings,
toSettings: MapSettings,
) {
const newSettings = {
...toSettings,
};
const group = mapSettingsConfig.find((group) => group.id === groupId);
group?.settings.forEach((setting) => {
// @ts-expect-error -- ts doesn't recognize that since the same expression is used for the key, the value will be the right type
newSettings[setting.id] = fromSettings[setting.id];
});
return newSettings;
}

export function validateSetting<T extends UnknownSettingConfig>(
value: unknown,
config: T,
Expand Down Expand Up @@ -139,12 +154,18 @@ export function asUnknownSettingConfig(config: AppSettingConfig | MapSettingConf
export function asKnownSettingId(id: string) {
return id as keyof MapSettings | keyof AppSettings;
}

interface SettingsAreDifferentOptions {
requiresReprocessingOnly?: boolean;
excludeGroups?: string[];
}
export function settingsAreDifferent(
a: MapSettings,
b: MapSettings,
{ requiresReprocessingOnly = false } = {},
{ requiresReprocessingOnly = false, excludeGroups }: SettingsAreDifferentOptions = {},
) {
return mapSettingsConfig
.filter((group) => !excludeGroups?.includes(group.id))
.flatMap((group) => group.settings)
.filter((setting) => !requiresReprocessingOnly || setting.requiresReprocessing)
.some((setting) => {
Expand Down

0 comments on commit 53aebc0

Please sign in to comment.