Skip to content

Commit 0920042

Browse files
committed
Added preference for prefering, and buttons for toggling, relative paths.
Fixed an issue with figuring out the difference between paths containing different drives. Anti-aliased some icons.
1 parent 83bb03c commit 0920042

File tree

4 files changed

+287
-170
lines changed

4 files changed

+287
-170
lines changed

src/guiSetup.gloa

Lines changed: 145 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@ export setupGuiFrames :: () {
6262
guiState.hbox!({
6363
guiState.inputText!({ name="bgPath", labelLeft="path", tooltip="Absolute path, or relative to the .hotparticles file (Right-click for recent)", weight=1 }),
6464
guiState.buttons!({ buttons={
65-
{name="bgChoose", image="iconFolder", tooltip="Browse files"},
66-
{name="bgReload", image="iconReload", tooltip="Reload background"},
65+
{name="bgChoose", image="iconFolder", tooltip="Browse files"},
66+
{name="bgRelative", image="iconRelativeDirectory", tooltip="Toggle relative path"},
67+
{name="bgReload", image="iconReload", tooltip="Reload background"},
6768
}}),
6869
}),
6970
guiState.hbox!({
@@ -119,8 +120,9 @@ export setupGuiFrames :: () {
119120
guiState.hbox!({
120121
guiState.inputText!({ name="texturePath", labelLeft="path", tooltip="Absolute path, or relative to the .hotparticles file (Right-click for recent)", weight=1 }),
121122
guiState.buttons!({ buttons={
122-
{name="chooseTexture", image="iconFolder", tooltip="Browse files"},
123-
{name="reloadTexture", image="iconReload", tooltip="Reload texture"},
123+
{name="textureChoose", image="iconFolder", tooltip="Browse files"},
124+
{name="textureRelative", image="iconRelativeDirectory", tooltip="Toggle relative path"},
125+
{name="textureReload", image="iconReload", tooltip="Reload texture"},
124126
}}),
125127
}),
126128
guiState.hbox!({
@@ -349,8 +351,9 @@ export setupGuiFrames :: () {
349351
guiState.hbox!({
350352
guiState.inputText!({ name="shaderPath", labelLeft="path", tooltip="Absolute path, or relative to the .hotparticles file", weight=1 }),
351353
guiState.buttons!({ buttons={
352-
{name="chooseShader", image="iconFolder", tooltip="Browse files"},
353-
{name="reloadShader", image="iconReload", tooltip="Reload shader"},
354+
{name="shaderChoose", image="iconFolder", tooltip="Browse files"},
355+
{name="shaderRelative", image="iconRelativeDirectory", tooltip="Toggle relative path"},
356+
{name="shaderReload", image="iconReload", tooltip="Reload shader"},
354357
}}),
355358
}),
356359
}),
@@ -453,11 +456,16 @@ export setupGuiFrames :: () {
453456
guiState.frame!({ name="preferences", width=DIALOG_WIDTH, modal=true, layout=.FLOATING, active=false,
454457
guiState.text!({ text="Preferences", size=3 }),
455458

456-
guiState.separator!({ thick=false }),
459+
guiState.separator!({ thick=true }),
457460
guiState.section!({ label="Max buffer size",
458461
guiState.inputText!({ name="preferences_maxBufferSize", tooltip="Default: 16000" }),
459462
}),
460463

464+
guiState.separator!({ thick=true }),
465+
guiState.section!({ label="File browser",
466+
guiState.checkbox!({ name="preferences_preferRelativePaths", label="Prefer relative paths", tooltip="Returned paths will be relative whenever possible" }),
467+
}),
468+
461469
guiState.separator!({ thick=false }),
462470
guiState.section!({ label="Max recent",
463471
guiState.hbox!({
@@ -466,7 +474,7 @@ export setupGuiFrames :: () {
466474
}),
467475
}),
468476

469-
guiState.separator!({ thick=false }),
477+
guiState.separator!({ thick=true }),
470478
guiState.section!({ label="Undo history",
471479
guiState.inputText!({ name="preferences_maxChanges", tooltip="Default: 200" }),
472480
}),
@@ -605,11 +613,16 @@ local fileDialog_isSave = false
605613
local fileDialog_dir = ""
606614
local fileDialog_filename = ""
607615
local fileDialog_filenamePattern = ""
608-
local fileDialog_onHighlight: = cast((path:Path)) NULL
609-
local fileDialog_onChoose: = cast((path:Path)) NULL
616+
local fileDialog_onHighlight: = cast((pathObj:Path, pathAbsoluteObj:Path)) NULL
617+
local fileDialog_onChoose: = cast((pathObj:Path, pathAbsoluteObj:Path)) NULL
610618
local fileDialog_onClose: = cast(()) NULL
611619

612-
export showFileDialog :: (title:string, dir,filename:string, onHighlight:(path:Path), onChoose:(path:Path), onClose:(), filenamePattern="", isSave=false, floating=false) {
620+
export showFileDialog :: (title:string, dir,filename:string,
621+
onHighlight: (pathObj:Path, pathAbsoluteObj:Path),
622+
onChoose: (pathObj:Path, pathAbsoluteObj:Path),
623+
onClose: (),
624+
filenamePattern="", isSave=false, floating=false
625+
) {
613626
fileDialog_isSave = isSave
614627
fileDialog_dir = dir
615628
fileDialog_filename = filename
@@ -1019,10 +1032,10 @@ export setupGuiCallbacks :: () {
10191032
if not ok filename = ""
10201033

10211034
showFileDialog("Choose texture", dir, filename,
1022-
onHighlight = (pathObj:Path) {
1035+
onHighlight = (pathObj:Path, pathAbsoluteObj:Path) {
10231036
textureBrowserPreviewImage = NULL
10241037

1025-
local _, dir, filename = pathObj.getDirectoryAndFilename!()
1038+
local _, dir, filename = pathAbsoluteObj.getDirectoryAndFilename!()
10261039
if not connectToRemoteDirectory(dir) return
10271040
defer disconnectFromRemoteDirectory()
10281041

@@ -1036,9 +1049,9 @@ export setupGuiCallbacks :: () {
10361049
local filter = project.pixelateTextures ? LG.FilterMode.NEAREST : LG.FilterMode.LINEAR
10371050
textureBrowserPreviewImage.setFilter!(filter, filter)
10381051
},
1039-
onChoose = (pathObj:Path) {
1040-
local ok, dir, filename = pathObj.getDirectoryAndFilename!()
1041-
assert(ok)
1052+
onChoose = (pathObj:Path, pathAbsoluteObj:Path) {
1053+
local ok, dir, filename = pathAbsoluteObj.getDirectoryAndFilename!()
1054+
if not ok return -- @UX: Show error message.
10421055

10431056
if not connectToRemoteDirectory(dir) {
10441057
setErrorText("Could not access folder '%s'", dir)
@@ -1064,6 +1077,15 @@ export setupGuiCallbacks :: () {
10641077
)
10651078
}
10661079

1080+
guiState.onAction.bgRelative = (buttons:gui.Buttons, buttonIndex:int) {
1081+
local project = app.projects[app.currentProjectIndex]
1082+
local ok, path = toggleRelativePath(project, project.bgPath, [*] () -> (success:bool, path:string) {
1083+
local ok, path = getBackgroundFullPath(project)
1084+
return ok, path
1085+
})
1086+
if ok setBackgroundPath(project, path)
1087+
}
1088+
10671089
guiState.onAction.bgReload = (buttons:gui.Buttons, buttonIndex:int) {
10681090
local project = app.projects[app.currentProjectIndex]
10691091
if project.bgPath updateBackgroundTexture(project)
@@ -1361,7 +1383,7 @@ export setupGuiCallbacks :: () {
13611383
})
13621384
}
13631385

1364-
guiState.onAction.chooseTexture = (buttons:gui.Buttons, buttonIndex:int) {
1386+
guiState.onAction.textureChoose = (buttons:gui.Buttons, buttonIndex:int) {
13651387
local project, system = getCurrentProjectAndSystem()
13661388
local pathObj = Path(system.texturePath)
13671389
local ok, dir = pathObj.getDirectory!()
@@ -1383,10 +1405,10 @@ export setupGuiCallbacks :: () {
13831405
if not ok filename = ""
13841406

13851407
showFileDialog("Choose texture", dir, filename,
1386-
onHighlight = (pathObj:Path) {
1408+
onHighlight = (pathObj:Path, pathAbsoluteObj:Path) {
13871409
textureBrowserPreviewImage = NULL
13881410

1389-
local _, dir, filename = pathObj.getDirectoryAndFilename!()
1411+
local _, dir, filename = pathAbsoluteObj.getDirectoryAndFilename!()
13901412
if not connectToRemoteDirectory(dir) return
13911413
defer disconnectFromRemoteDirectory()
13921414

@@ -1400,9 +1422,9 @@ export setupGuiCallbacks :: () {
14001422
local filter = project.pixelateTextures ? LG.FilterMode.NEAREST : LG.FilterMode.LINEAR
14011423
textureBrowserPreviewImage.setFilter!(filter, filter)
14021424
},
1403-
onChoose = (pathObj:Path) {
1404-
local ok, dir, filename = pathObj.getDirectoryAndFilename!()
1405-
assert(ok)
1425+
onChoose = (pathObj:Path, pathAbsoluteObj:Path) {
1426+
local ok, dir, filename = pathAbsoluteObj.getDirectoryAndFilename!()
1427+
if not ok return -- @UX: Show error message.
14061428

14071429
if not connectToRemoteDirectory(dir) {
14081430
setErrorText("Could not access folder '%s'", dir)
@@ -1428,7 +1450,16 @@ export setupGuiCallbacks :: () {
14281450
)
14291451
}
14301452

1431-
guiState.onAction.reloadTexture = (buttons:gui.Buttons, buttonIndex:int) {
1453+
guiState.onAction.textureRelative = (buttons:gui.Buttons, buttonIndex:int) {
1454+
local project, system = getCurrentProjectAndSystem()
1455+
local ok, path = toggleRelativePath(project, system.texturePath, [*] () -> (success:bool, path:string) {
1456+
local ok, path = getTextureFullPath(project, system)
1457+
return ok, path
1458+
})
1459+
if ok setTexturePath(project, system, path)
1460+
}
1461+
1462+
guiState.onAction.textureReload = (buttons:gui.Buttons, buttonIndex:int) {
14321463
local project, system = getCurrentProjectAndSystem()
14331464
if system.texturePath updateParticleTexture(project, system)
14341465
}
@@ -2184,75 +2215,87 @@ export setupGuiCallbacks :: () {
21842215
)
21852216

21862217
-- Shader.
2187-
guiState.onRefresh.shaderPath = (input:gui.InputText) {
2188-
local project, system = getCurrentProjectAndSystem()
2189-
input.value = system.shaderPath
2190-
}
2191-
guiState.onAction.shaderPath = (input:gui.InputText) {
2192-
local project, system = getCurrentProjectAndSystem()
2193-
setShaderPath(project, system, Path(trim(input.value)).toString!())
2194-
}
2195-
guiState.onOption.shaderPath = (input:gui.InputText, _:int) {
2196-
showRecentFilesContextMenu("Recent shaders", app.recentShaders, (path:string) {
2218+
do {
2219+
guiState.onRefresh.shaderPath = (input:gui.InputText) {
21972220
local project, system = getCurrentProjectAndSystem()
2198-
setShaderPath(project, system, path)
2199-
})
2200-
}
2221+
input.value = system.shaderPath
2222+
}
2223+
guiState.onAction.shaderPath = (input:gui.InputText) {
2224+
local project, system = getCurrentProjectAndSystem()
2225+
setShaderPath(project, system, Path(trim(input.value)).toString!())
2226+
}
2227+
guiState.onOption.shaderPath = (input:gui.InputText, _:int) {
2228+
showRecentFilesContextMenu("Recent shaders", app.recentShaders, (path:string) {
2229+
local project, system = getCurrentProjectAndSystem()
2230+
setShaderPath(project, system, path)
2231+
})
2232+
}
22012233

2202-
guiState.onAction.chooseShader = (buttons:gui.Buttons, buttonIndex:int) {
2203-
local project, system = getCurrentProjectAndSystem()
2204-
local pathObj = Path(system.shaderPath)
2205-
local ok, dir = pathObj.getDirectory!()
2234+
guiState.onAction.shaderChoose = (buttons:gui.Buttons, buttonIndex:int) {
2235+
local project, system = getCurrentProjectAndSystem()
2236+
local pathObj = Path(system.shaderPath)
2237+
local ok, dir = pathObj.getDirectory!()
22062238

2207-
if not ok {
2208-
dir = getSaveDirectory().."/projects"
2239+
if not ok {
2240+
dir = getSaveDirectory().."/projects"
22092241

2210-
} else {
2211-
local dirObj = Path(dir)
2242+
} else {
2243+
local dirObj = Path(dir)
22122244

2213-
if not dirObj.isAbsolute {
2214-
ok, dir = Path(project.path).getDirectory!()
2215-
dirObj.prepend!(ok ? dir : getSaveDirectory().."/projects")
2216-
dir = dirObj.toString!()
2245+
if not dirObj.isAbsolute {
2246+
ok, dir = Path(project.path).getDirectory!()
2247+
dirObj.prepend!(ok ? dir : getSaveDirectory().."/projects")
2248+
dir = dirObj.toString!()
2249+
}
22172250
}
2218-
}
22192251

2220-
local ^ok, filename = Path(system.shaderPath).getFilename!()
2221-
if not ok filename = ""
2252+
local ^ok, filename = Path(system.shaderPath).getFilename!()
2253+
if not ok filename = ""
22222254

2223-
showFileDialog("Choose shader", dir, filename,
2224-
onHighlight = (pathObj:Path) {},
2225-
onChoose = (pathObj:Path) {
2226-
local ok, dir, filename = pathObj.getDirectoryAndFilename!()
2227-
assert(ok)
2255+
showFileDialog("Choose shader", dir, filename,
2256+
onHighlight = (pathObj:Path, pathAbsoluteObj:Path) {
2257+
-- @UX: Preview shader.
2258+
},
2259+
onChoose = (pathObj:Path, pathAbsoluteObj:Path) {
2260+
local ok, dir, filename = pathAbsoluteObj.getDirectoryAndFilename!()
2261+
if not ok return -- @UX: Show error message.
22282262

2229-
if not connectToRemoteDirectory(dir) {
2230-
setErrorText("Could not access folder '%s'", dir)
2231-
return
2232-
}
2233-
defer disconnectFromRemoteDirectory()
2263+
if not connectToRemoteDirectory(dir) {
2264+
setErrorText("Could not access folder '%s'", dir)
2265+
return
2266+
}
2267+
defer disconnectFromRemoteDirectory()
22342268

2235-
addRecent(app.recentFolders, dir, app.maxRecentFolders)
2269+
addRecent(app.recentFolders, dir, app.maxRecentFolders)
22362270

2237-
local shader = pcall_newShader(filename)
2238-
if shader == NULL {
2239-
setErrorText("'%s' is not a valid shader file", filename)
2240-
return
2241-
}
2271+
local shader = pcall_newShader(filename)
2272+
if shader == NULL {
2273+
setErrorText("'%s' is not a valid shader file", filename)
2274+
return
2275+
}
22422276

2243-
local project, system = getCurrentProjectAndSystem()
2244-
setShaderPath(project, system, pathObj.toString!())
2245-
popPanel()
2246-
},
2247-
onClose = () {}
2248-
)
2249-
}
2277+
local project, system = getCurrentProjectAndSystem()
2278+
setShaderPath(project, system, pathObj.toString!())
2279+
popPanel()
2280+
},
2281+
onClose = () {}
2282+
)
2283+
}
22502284

2251-
guiState.onAction.reloadShader = (buttons:gui.Buttons, buttonIndex:int) {
2252-
local project, system = getCurrentProjectAndSystem()
2253-
if system.shaderPath updateParticleShader(project, system)
2285+
guiState.onAction.shaderRelative = (buttons:gui.Buttons, buttonIndex:int) {
2286+
local project, system = getCurrentProjectAndSystem()
2287+
local ok, path = toggleRelativePath(project, system.shaderPath, [*] () -> (success:bool, path:string) {
2288+
local ok, path = getShaderFullPath(project, system)
2289+
return ok, path
2290+
})
2291+
if ok setShaderPath(project, system, path)
2292+
}
2293+
2294+
guiState.onAction.shaderReload = (buttons:gui.Buttons, buttonIndex:int) {
2295+
local project, system = getCurrentProjectAndSystem()
2296+
if system.shaderPath updateParticleShader(project, system)
2297+
}
22542298
}
2255-
--
22562299

22572300
guiState.onRefresh.customDataSystem = (input:gui.InputText) {
22582301
local project, system = getCurrentProjectAndSystem()
@@ -2271,7 +2314,7 @@ export setupGuiCallbacks :: () {
22712314
}
22722315

22732316
--==============================================================
2274-
--= Save/open project
2317+
--= File dialog
22752318
--==============================================================
22762319
do {
22772320
local Item :: struct { isDir=false, name="" }
@@ -2426,6 +2469,19 @@ export setupGuiCallbacks :: () {
24262469
guiState.refreshRecursively!("fileDialog_directory")
24272470
}
24282471

2472+
local makeRelativeOrClone :: (pathObj:Path) -> Path {
2473+
if not app.preferRelativePaths or fileDialog_isSave return pathObj.clone!()
2474+
2475+
local project = app.projects[app.currentProjectIndex]
2476+
if not project.path return pathObj.clone!()
2477+
2478+
local _, dir = Path(project.path).getDirectory!()
2479+
local ok, pathRelativeObj = pathObj.getRelativeTo!(dir)
2480+
if ok return pathRelativeObj
2481+
2482+
return pathObj.clone!()
2483+
}
2484+
24292485
guiState.onAction.fileDialog_items = (buttons:gui.Buttons, buttonIndex:int) {
24302486
local item = cast(Item) buttons.buttons[buttonIndex].value
24312487

@@ -2435,7 +2491,7 @@ export setupGuiCallbacks :: () {
24352491

24362492
local pathObj = Path(dirCurrent)
24372493
insert(pathObj.path, item.name)
2438-
fileDialog_onHighlight(pathObj)
2494+
fileDialog_onHighlight(makeRelativeOrClone(pathObj), pathObj)
24392495

24402496
} elseif item.name == ".." {
24412497
local dirObj = Path(dirCurrent)
@@ -2476,7 +2532,7 @@ export setupGuiCallbacks :: () {
24762532
}
24772533
}
24782534

2479-
fileDialog_onChoose(pathObj)
2535+
fileDialog_onChoose(makeRelativeOrClone(pathObj), pathObj)
24802536
}
24812537
}
24822538

@@ -3675,6 +3731,14 @@ export setupGuiCallbacks :: () {
36753731
guiState.refreshRecursively!(frame)
36763732
}
36773733

3734+
guiState.onRefresh.preferences_preferRelativePaths = (checkbox:gui.Checkbox) {
3735+
checkbox.checked = app.preferRelativePaths
3736+
}
3737+
guiState.onAction.preferences_preferRelativePaths = (checkbox:gui.Checkbox, _:int) {
3738+
app.preferRelativePaths = checkbox.checked
3739+
scheduleSaveWorkspace()
3740+
}
3741+
36783742
guiState.onRefresh.preferences_maxBufferSize = (input:gui.InputText) {
36793743
input.value = format("%.0f", app.maxBufferSize)
36803744
}

0 commit comments

Comments
 (0)