Dialog to Return a Folder
-
Currently
UI.openpanel()
only returns a file-path and you have to get its directory to select a folder.
I have a cross-platform tool where at one point you need to select a folder - if it's new or empty you can't select it without first making a temporary file in it and picking that... My client is unimpressed with the this aspect [as am I]. I had hoped that entering '.' at the file prompt would allow you to select the folder by its hidden '.' - it doesn't work... Does anyone have any ideas about selecting a folder/directory directly - e.g. is there a java-script - web-dialog solution I haven't come across ? It must work on PC and Mac -
I consider this a proof-of-concept, so needs some work to make it usable. But so far, it is cross-platform. If you (or anyone) wants to turn it into something useful for everyone, please do.
-
Godd idea Jim. Too bad it's not possible to make modal webdialogs on OSX. (hopes for something nice in SU8)
-
Thanks Jim, I'll investigate it...........
-
Amazing.. was thinking of doing this exact thing, night before last.
This is a good start.
Needs some cosmetics, and a few bugs fixed.- The pwd output to the console, seems to be 1 dir behind.* should have an image entry in the css to set image background transparent (so the pick hilte shows thru.)* needs the meta-tag in the html <HEAD> to turn on XP style controls
-
After playing around with Jim's browser for a few mins...
my initial reactions are:(1) It's (at least on my XP machine,) much faster at displaying folder lists than the native Windows FileExplorer. (Probably because it does not worry about file type associations, or right-click context menus for everything displayed.)
(2) It's much more fun (ie, more intuitive, easier to use, faster, etc.) than that 'darned' postage stamp sized Windows (pre-Vista,) native folder picker. Add the fact it's customizable... and it can be a candidate to also use outside of Sketchup on a PC with a full Ruby install. (It would likely run as an HTA in that case.)
Thumbs up
and three cheers so far Jim!
-
Thanks
I clobbered together a folder_browser as part of a larger code set using your ideas... as it's subject to a NDA I can't post it here, BUT here are some tips about what I changed/added - in no particular order...
I set a @ variable to represent the returned folderpath.
The starter is
def startfb(dir=nil, input=nil)
this is to separate it from another 'start', by running it with arguments I can determine which directory to start the list in [dir] and then what action to take [def to run] with the resulting @folderpath [using input].
So we don't mess with the current working directory we remember it, reset it to dir then process and set it back on closing [inside the calling code NOT the fb itself]I made it a sub-def of a wider class and ensured that @dlg etc were renamed so as not to clash with another @dlg I already had open.
I changed the dialog to be a fixed size [also added 'instructions' into the top-bar] - in the js etc I made the list 80% so it never squeezes the buttons off screen. I also swapped the location to the top of the dialog and removed the 'Location:' text as it sees clear what the string is anyway.
I changed the 'OK' button size to be bigger
value=OK style='width:146px'
and added new functions to 'Cancel' and 'New Folder'onclick="cancel()"
andonclick="mkdir()"
... These in turn 'call' back and close the dialog or open another dialog into which you can type the new folder name...If you add a new folder it is added to the list immediately after the folder-up item, the rest are listed in order - this makes finding that new folder much easier - if you navigate away and back it will now get added to the list in the correct order...
The call back is a new sub-def called 'newfolder()' and that opens another simple dialog to get the the new name - it's trapped in my case to ensure it only has _ and alphanumerics in it -
newDir.gsub!(/[^_A-Za-z0-9]/,'')
. It also checks for validity and preexistence and warns appropriately.
Dir.mkdir(newDir) @dlgfb.execute_script('clear_list()') self.populatefb(Dir.pwd, newDir)
Note how thepopulate
def [renamed to avoid a clash] takes arguments - this is to set the starting directory and IF there's a new-directory to pass it over so that the list can be manipulated to have its name second on the updated list.list << file if File.basename(file) != newDir
and
scr='appendDiv("../");' @dlgfb.execute_script(scr) scr='appendDiv("'+newDir+'");' if newDir
Then the list is appended...@dlgfb.show_modal{} ensures that the dialog stays foremost until you Cancel or OK,
I added
img{ opacity:0.66; /*Firefox & Chrome*/ filter:alpha(opacity=66); /* IE */ }
to the css so that the images are slightly transparent and show the selected item through themselves.
I also edited the folder.png and erased the white edge areas so that it was 'transparent'. I also duplicated it as folderup.png and added an 'up' arrow onto it - this img is then added to the listed item IF its text is ../ - i.e. it's the navigate folder-up at the top of the list...
if ( txt == '../') d.innerHTML = '<img src="./folderup.png"/> '+txt; else d.innerHTML = '<img src="./folder.png"/> '+txt;
Also added tests for js's OK
if ( selected_elem == null ) my_alert(); else if ( selected_elem.innerText.trim() == "../" ) my_alert(); else use_this( selected_elem.innerText.trim() );
Wheremy_alert()
opens an error message telling you to select a folder before clicking OK - - the first trap is you haven't selected a folder yet and the second is you've selected the first item 'folder-up' which can't be taken as a folder-path.
Also note how this
d.ondblclick = function(id) { selected_elem = null folder_select(d.id);return(false); }
ensures that if you have double-clicked the folder-up item or another folder, to move the list into there, then there is nothing remembered as theselected_elem
- otherwise hitting OK when you were in the next folder level would take the last selected folder [double-clicked >> current-folder] as the desired one which is not what's wanted - but this waymy_alert()
will tell you to select something in the current list before pressing OK...I also changed the selection color to be less dark [ruby:3dez4ubj]this.style.background = 'gray';[/ruby:3dez4ubj]
Hope these bits help...
Advertisement