automap.config

Settings that survive closing the window.

Small and hand-editable on purpose: a JSON file you can look at and fix. An unreadable or half-written file is treated as “no settings yet” rather than as an error – losing a preference is not worth refusing to start over.

Module Attributes

DEFAULT_FAST_TRAVEL_TARGETS

New Phlan, The Slums, Sokol Keep -- goldbox/areas.py ids 0, 20 and 21.

POOL_OF_RADIANCE

goldbox.games.Game.key for the one title with an area table.

DEFAULT_FAST_TRAVEL_BY_GAME

What a title gets before anybody has ticked anything.

RENAMED

Keys an older build wrote, and the field each is now called.

WIDTH_CEILING

The largest number a widget width may be -- Qt's own QWIDGETSIZE_MAX, spelled out rather than imported because this module is the settings file and builds no widgets.

UNSHOWN_CHROME

What to assume a title bar and a resize border cost while the window has never been shown.

Functions

clamp_to_screen(window[, space])

Never bigger than the display, never off the edge of it.

fold_shared_folder(folder, table)

Every title folder turns out to hold, folded into table.

game_key([game])

The key to file a fast-travel choice under.

hold_geometry(window[, space])

Stand by the size we just asked for, if the platform overrides it.

remember_geometry(window, settings)

Note where and how big this window is, for the next run.

restore_geometry(window, settings[, floor, ...])

Put a window back where it was.

whole_sizes(raw, count)

A remembered row of widget sizes, or None for "nobody chose these".

Classes

Settings

Everything the map remembers between runs.

automap.config.DEFAULT_FAST_TRAVEL_BY_GAME: dict[str, tuple[int, ...]] = {'pool-of-radiance': (0, 20, 21)}

What a title gets before anybody has ticked anything. Every title but Pool of Radiance gets nothing, because goldbox.areas.areas_for_title has nothing to offer it – an id ticked for a title with no area table would be an id from another game’s list.

automap.config.DEFAULT_FAST_TRAVEL_TARGETS: tuple[int, ...] = (0, 20, 21)

New Phlan, The Slums, Sokol Keep – goldbox/areas.py ids 0, 20 and 21. The three a party has almost certainly walked in by the time it wants to travel anywhere, so the list starts safe rather than long. A Pool of Radiance fact, which is why it is keyed like one below.

Type:

Ticked on a fresh config

automap.config.POOL_OF_RADIANCE = 'pool-of-radiance'

goldbox.games.Game.key for the one title with an area table. Spelled out rather than imported: this module is the settings file and has no other business with the game descriptors.

automap.config.RENAMED = {'fasttravel_areas': 'fast_travel_targets'}

Keys an older build wrote, and the field each is now called. Read, never written: a file saved by this build carries the new name only, so the rename finishes rather than being carried forever. The cost of that is one-way – an older build reading a new file sees no choice and offers its own three – which beats a settings file with two names for one setting in it.

class automap.config.Settings[source]

Bases: object

Everything the map remembers between runs.

__init__(reveal=True, interval_ms=0, backend='', window_width=940, window_height=820, sight=4, disks='', last_save_folder='', saves_folder='', game_folders=None, ultimate_host='', backup_folder='', backup_folder_chosen=False, geometry='', diagnostics=False, clear_quickfight=False, automap_columns=None, editor_rows=None, fast_travel_targets=None)
Parameters:
Return type:

None

automap_columns: list[int] | None = None
backend: str = ''
backup_folder: str = ''
backup_folder_chosen: bool = False
chosen_areas(game=None)[source]

The area ids the Fast Travel dropdown may offer for this title.

Return type:

tuple[int, …]

clear_quickfight: bool = False
column_widths(count)[source]

The remembered automapper column widths, or None for “use the defaults”.

None is what a hand-edited file gets: a width that is negative, is not a number, is above WIDTH_CEILING, or a row of the wrong length after the layout changed. The whole row is refused rather than mended, because a mended row is three widths of which one is somebody’s and two are ours, and a window laid out from that is harder to explain than one that opened at its defaults.

Zero passes, because zero is what a column dragged shut is worth.

Parameters:

count (int)

Return type:

list[int] | None

diagnostics: bool = False
disks: str = ''
editor_rows: list[int] | None = None
fast_travel_targets: dict[str, list[int]] | None = None
game_folders: dict[str, str] | None = None
geometry: str = ''
interval_ms: int = 0
last_save_folder: str = ''
classmethod load()[source]
Return type:

automap.config.Settings

reveal: bool = True
row_heights(count)[source]

The remembered character-editor row heights, or None for “use the defaults”.

The same rule as column_widths above and for the same reasons: a hand-edited number that is not a whole size between zero and WIDTH_CEILING, or a row of the wrong length after the layout changed, refuses the whole row rather than mending part of it. Zero passes, because zero is what a row dragged shut is worth.

Parameters:

count (int)

Return type:

list[int] | None

save()[source]
Return type:

None

saves_folder: str = ''
set_chosen_areas(ids, game=None)[source]

Record the choice for one title, empty included.

Only that title’s entry is touched: ticking in a Curse session must not disturb the Pool of Radiance list somebody spent a while building.

Return type:

None

sight: int = 4
ultimate_host: str = ''
window_height: int = 820
window_width: int = 940
automap.config.UNSHOWN_CHROME = (16, 48)

What to assume a title bar and a resize border cost while the window has never been shown. Before show() there is no frame, so frameGeometry() equals geometry() and the chrome measures as nothing – which is how a 1030 px window passed a clamp against a 1032 px work area on Windows and then opened 39 px taller than the screen, with the status bar off the bottom. Windows 11 draws a 32 px caption, GNOME about 37; 48 is above both and is only ever a first-run estimate, because clamp_to_screen runs again after show() with the real numbers.

automap.config.WIDTH_CEILING = 16777215

The largest number a widget width may be – Qt’s own QWIDGETSIZE_MAX, spelled out rather than imported because this module is the settings file and builds no widgets. It is here as a guard rather than as a layout opinion: a hand-edited width above it does not clamp when it reaches QSplitter.setSizes, it raises, and a settings file must not be able to stop the window opening.

automap.config.clamp_to_screen(window, space=None)[source]

Never bigger than the display, never off the edge of it.

space overrides the screen’s work area, which is how a test fakes a display smaller than the one it is running on.

Return type:

None

automap.config.fold_shared_folder(folder, table)[source]

Every title folder turns out to hold, folded into table.

#357 (The automapper reads the shared Game disks folder, so setting a title's own folder does not make it map that title): the shared disks folder is gone from paths.resolve_disks’s precedence, so what used to be a one-shot migration into game_folders (#22 (A disk folder setting per game, not one shared by all six)) now runs on every load instead, and for every title the folder holds rather than only the first.

table is mutated in place with dict.setdefault, so a row the player has already set is never overwritten by a fresh guess – this can run every time disks is non-empty without disturbing a deliberate choice. The return value is what was actually found in folder: empty for a folder that no longer exists, is empty, or holds nothing this project recognises, which is how Settings.load knows not to blank disks – a folder on a drive that is not plugged in today is retried on the next load that can read it, rather than dropped.

Parameters:
Return type:

dict[str, str]

automap.config.game_key(game=None)[source]

The key to file a fast-travel choice under.

Takes a goldbox.games.Game, a key string, or None – and None is Pool of Radiance, because every choice made before this setting was keyed at all was Pool of Radiance’s. A Game.title is not accepted: the file is keyed by the stable identifier, never by display text.

Return type:

str

automap.config.hold_geometry(window, space=None)[source]

Stand by the size we just asked for, if the platform overrides it.

A Wayland compositor answers the first show() with a size of its own and Qt takes it: on cosmic-comp, Donald’s desktop, a bare QMainWindow that asks for 1875x1030 is 1280x662 one frame later – measured with a plain window and no code of ours in it, so it is the platform. Everything set before show() is thrown away that way, which is what “the window doesn’t remember its size on Linux” was: the compositor’s size was then what closing remembered, so the next run opened at it and the size before it was gone for good.

The same size asked for again after that first configure is honoured, so that is what this does. The first resize the program did not ask for is undone once, and then the watcher stands down – every later one is the user dragging an edge, and fighting that would be far worse than the bug. The re-assertion is clamped like any other, so a platform shrinking a window because it genuinely does not fit still wins.

Nothing happens on X11 or Windows, where no such configure arrives. The watcher is parented to the window; the return is for a test to hold.

automap.config.remember_geometry(window, settings)[source]

Note where and how big this window is, for the next run.

Parameters:

settings (automap.config.Settings)

Return type:

None

automap.config.restore_geometry(window, settings, floor=None, space=None)[source]

Put a window back where it was. True if a saved geometry was used.

With nothing saved – a first run, or a settings file from before this – the remembered width and height are used instead, raised to floor if the caller has one. Either way the result is clamped to the screen: the floor never wins over the display, or a laptop gets a window it cannot see the bottom of.

space is the available work area, for a test that has to fake a screen the offscreen platform will not give it.

Parameters:
Return type:

bool

automap.config.whole_sizes(raw, count)[source]

A remembered row of widget sizes, or None for “nobody chose these”.

None is what a hand-edited file gets: a size that is negative, is not a number, is above WIDTH_CEILING, or a row of the wrong length after the layout changed. The whole row is refused rather than mended, because a mended row is part somebody’s and part ours, and a window laid out from that is harder to explain than one that opened at its defaults.

Zero passes, because zero is what a pane dragged shut is worth.

Parameters:

count (int)

Return type:

list[int] | None