_
I've noticed there does not seem to be Observers for classes:
- Importer* Exporter* TextureWriter
Anyone think there's any need here?
_
_
I've noticed there does not seem to be Observers for classes:
_
Model.title
@unknownuser said:
The tile method retrieves the name of the model. If the model is saved on disk, returns the file name without extension. Otherwise returns an empty string.
http://code.google.com/apis/sketchup/docs/ourdoc/model.html#title
Change 'tile' to 'title' in method description.
We could use Model.is_saved? and Model.is_unsaved? methods, as the Model.title method is the only way (that I can find) to determine if the model has yet been saved or not. We cannot rely upon the word 'Untitled' (in the caption bar) because that may actually be a valid filename.
Workaround:
class Sketchup;;Model
def is_saved?
return not title.empty?
end
def is_unsaved?
return title.empty?
end
end # class
_
need AppObserver.onCloseModel
@unknownuser said:
It is often used to attach other observers to each model as it is opened or started. This ensures that your observers are watching all open models.
http://code.google.com/apis/sketchup/docs/ourdoc/appobserver.html
In an MDI application (as the Mac is now, and hopefully the PC will be in upcoming versions,) there needs to be a way to detect that an MDI child window has been closed, so scripts can do cleanup, such as unattaching observers that may have been attached using onNewModel or onOpenModel.
Of course on the PC, at the current time, Sketchup is not yet an MDI application; and to close the active model, a user would either open a new model (firing the onNewModel event,) open another model from a file (firing the onOpenModel event,) OR shut down Sketchup (firing the onQuit event.)
_
@martinrinehart said:
@dan rathbun said:
What's wrong with the standard included classes
File
andDir
??
You can do all that would be desired with their methods.That's all I've done:
def cd( path ) Dir::chdir( path ) end
Shell Commands are already allowed within Ruby. [Examples for PC win32 platform, but also applies to Mac OSX.]
use the %x delimiter, as in: %x{dir *.skp}
or backquoted strings, as in: dir *.skp
(from: Programming Ruby -
The Pragmatic Programmer's Guide)
The Ruby Language > Expressions > Single Terms
Shell Command. A shell command is a string enclosed in backquotes, or in a general delimited string (page 200) starting with %x. The value of the string is the standard output of running the command represented by the string under the host operating system's standard shell. The execution also sets the $? variable with the command's exit status.
[Example - '.c' changed to '.skp';'ls' changed to 'dir'.]
%(#BF0000)[filter = "*.skp"
files = dir #{filter}
files = %x{dir #{filter}}]
! Backquoted strings allow replacement like doublequoted strings !
Expressions > Miscellaneous Expressions**http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html**
Command Expansion
If you enclose a string in backquotes, or use the delimited form prefixed by %x, it will (by default) be executed as a command by your underlying operating system. The value of the expression is the standard output of that command.
! The output is a String, so any String method can be applied to the expression: Ex:
dir
.include?('.jpg')
returns true if there are any jpeg files in the dir
_
FYI: MSDOS Shell Default Font
It's a pain in the butt to get the Font set in the DOS shell.
Try changing the 'DefaultFont' registry setting in:
'HKEY_CURRENT_USER\Software\Microsoft\Command Processor'
You may need to Log off and back on, before the setting takes effect.
There is also a list of fonts at:
'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont' where the list numbers should begin at 0.
But I haven't had any luck getting the list to appear in the Console Properties dialog.
(EDIT)By the way, the settings for the Console Properties dialog are saved at:
'HKEY_CURRENT_USER\Console'
@tig said:
UI.openURL will open/execute any filepath passed to it - if that's a folder it opens it in Windows-Explorer, if it's a file it opens with its default application, if it's an application/batch-file it runs, if it's a URL it opens in a web-browser [default app].
I just tested safe levels with UI.openURL and the setting of $SAFE has no effect on the function of executables started by UI.openURL.
Could this be a security issue?
_
The following code does the same thing BUT must be run from within Sketchup Ruby.
( Jim's code can run in standard Ruby, and does not need Sketchup running.)
folder = Dir.getwd
# browse for another folder here (opt.)
# see TIG's "import_from_folder" script
Dir.foreach( folder ) do |fn|
skp = File.join(folder,fn)
img = ''
# first 2 entries are dirs '.' and '..'
if File.ftype( skp )=='file'
if fn.downcase.include?('.skp')
# it's a Sketchup model
img = fn.split('.')[0]+'.png'
img = File.join( folder, img )
Sketchup.save_thumbnail(skp,img)
end # if it's a SKP
end # if 'file' type
end # Dir loop
EDIT-06JAN2010: added downcase to filename .skp test
FYI: There are three (3) save_thumbnail methods
Sketchup.save_thumbnail which can work on files, other than the one that's loaded.
Model.save_thumbnail which only works for the current model, but has a bug, in that if the model has never been saved, it writes a blank thumbnail image to the %UserProfile% folder instead of the Model folder specified in Preferences>Files>Model folderpath.
[BUG - as of SU ver 7.1.6087]
ComponentDefinition.save_thumbnail
There is also View.write_image which can write a thumbnail of the current view that CAN be different than the thumbnail that was saved within the file.
_
Stumbled on this. Didn't know it would happen, but it of course makes sense, because of the way MS Windows works.
If you wish to open a File Explorer window, to some given folder, use UI.openURL method.
# use empty quote quirk to get SU folderpath
supath = Sketchup.find_support_file("")
# open a File Explorer
UI.openURL(supath)
_
@chrisglasier said:
@unknownuser said:
Doug Crockford is the inventor of JSON.
Yes yes ... I was just making sure two nonsenses don't make a sense.
2(-1) = -2
so
2(nonsense) = non-twosenses
but:
(-1)^2 = 1
so
nonsense^2 = a sense
it follows then that:
the squareroot of nonsense must be imaginary
@martinrinehart said:
I've hacked up a little bit of DOS that let's you change, make, remove and list contents of directories and delete files in the Ruby Console.
What's wrong with the standard included classesFile
andDir
??
You can do all that would be desired with their methods.
@martinrinehart said:
It's useful as is, but I'm not happy that you have to put all the params in quotes: ...
Any way to lose the quotes, short of writing a shell?
In many cases, since we migrated to 32bit Windows, we've had to put quotes around most pathnames or filenames that have spaces in DOS command scripts anyway... so it's not a big deal.
_
@martinrinehart said:
Any way to lose the quotes, short of writing a shell?
**** Warning! ****
Kernel.exec('cmd.exe')
will cause Sketchup to 'hang' on Win32.
When the shell is exited, BugSplat! closes Sketchup.
(This is because Kernel.exec
replaces the current Process
, which is the interpreter process started by Sketchup.)
So to use a DOS shell, instead use 1 of two choices:
DOS shell in a Sub Process
Kernel.system('cmd.exe')
which runs in a subprocess, and also returns a boolean value of success( TrueClass
) or failure( FalseClass
).
As a bonus, it can set a detailed error code in the Ruby global $?
.
And ugly side-effect however, is that Sketchup stops and waits while the shell is open. The Windows TaskManager reports that sketchup.exe is 'not responding', which is true; but will return to normal operation once the DOS shell is closed.
If the user types 'exit' in the shell, Kernel.system
returns true
with exitcode 0; if the user clicks the shell window close button then Kernel.system
returns false
with exitcode 58.
DOS shell in a Separate Process
UI.openURL('cmd.exe')
Simple and works because of the $SAFE
level is set to 0 by default.
@dan rathbun said:
@thomthom said:
@whaat said:
... For example, OnEntityChanged, what constitutes a 'change'?
Yea - I spent some time on this because I was setting attributes - which seems to be a change. Not sure if I want that to trigger. At least not most of the times. attributes are like meta data.
maybe onChange for geometric changes, andonAttribChange(dict, key, oldVal, newVal)
for the attribute meta data?Do changes to an Attribute currently fire onEntityChanged events?
What about adding or deleting an attribute from a Dictionary?
What about adding or deleting a Dictionary from an Entity?
EDIT
I asked this because, it would lead to whether we need EntityObserver methods:
%(#BF0000)[onBeforeAttributeAdd(entity, dict, key, value)
onAfterAttributeAdd(entity, dict, key, value,]result%(#BF0000)[)
onBeforeAttributeDelete(entity, dict, key, value)
onAfterAttributeDelete(entity, dict, oldKey, oldVal,]result)
Also, ThomThom's example needs the entity handle passed.
onAttribChange(entity, dict, key, oldVal, newVal)%(#004000)[*
Also would a DictionaryObserver be necessary?
(I'd think not as most Attribute and Dictionary functions are available thru the Entity object.)
@jim said:
Just messing around with the Toolbar entries in the registry to see if there might be a way to reset their positions.
Conclusion: Changing values in registry while SU is running has no effect. SU only reads from the registry on startup, and writes to it only on shutdown.
(1) This means the registry probably does not contain the current position of a toolbar if it's moved during a session.
(2) This means (on the up side,) that you can set up your toolbars the way you like (and they work,) then shutdown SU, and backup those registry keys for the toolbars to a .reg file. [You will likely have to export each key and then append all the files into one. Also possibly, you'd need to add a command at the top of the file to delete all 'ToolbarsUser-*' keys.] Once you have the .reg file, you can use it to restore the toolbars settings back to the optimum layout if they get messed up, etc. EDIT['con' changed to 'up']
@jim said:
... I have been opening and closing toolbars and sketchup all day, and can see no patterns. I was hoping to see some way to detect and set a toolbar's (x, y) position. The toolbar registry entries do have XPos and YPos values, but I can't find a clear connection between them and the toolbar's actual position.
XPos and MRUDockLeftPos are basically the Xorigin of the toolbar, with respect to the origin of it's Container when Docked. But.. XPos may be the 'last' setting, and MRU... the historical or previous setting. (Generally the MRU attributes are there to put a toolbar back where it was after it was turned off, and then turned on again.) I'm guessing a bit here.. however, I noticed that some toolbars update both values, other toolbars do not. So it may be as simple as, there have been several programmers, over the years working on this feature, and it may be the ol' righthand/lefthand scenario. (Bugs may have creeped in.)
YPos and MRUDockTopPos are basically the Yorigin of the toolbar, with respect to the origin of it's Container when Docked. (same notes apply as to the Docked X position values.)
MRUDockRightPos is the Righthand end of the toolbar, with respect to the origin of it's Container when Docked. (Left-Right should give the width of the toolbar.)
MRUDockBottomPos is the bottom edge of the toolbar, with respect to the origin of it's Container when Docked. (Top-Bottom should give the heigth of the toolbar.)
MRUFloatXPos should be the X position with respect to the Display Screen origin.
MRUFloatYPos should be the Y position with respect to the Display Screen origin.
However we see strange values, perhaps positioning codes, two examples:
0x80000000 (2147483648)* 0xF8DB0000 (4175101952)* Add to that the duplicate registry record that gets created when you pull a toolbar off a container, and float it.
Moving Toolbars
In Win32 programming, everything on the screen, is a 'window'. Specifically all items are subclasses of class Window, and inherit base methods, etc. (So even a button is a window, that happens to have an image that makes it look like a button.)
Floating: When toolbars are floated, they are basically re-styled as a non-modal dialog subclass; and re-adopted as a direct child of the application window (Sketchup's window.)
So, Jim, you should be able to move them around in the same way you did the Console window, using Win32 API calls.
Docked: When docked, they are re-adopted as a child window of the Toolbar Container Window, and restyled so as not to have frames, no caption bar, and add grips. If the caption names are not changed, you may be able to use the same methods you use for moving floating bars, just compensate for the different origins. (Screen origin vs the origins of the individual toolbar containers.)
UI.toolbar_names
http://code.google.com/apis/sketchup/docs/ourdoc/ui.html#toolbar_names
@unknownuser said:
The toolbar_names method is used to returns the name of all the available toolbars (this differs between PC and Mac).
(1) In the above sentence "returns" should be singular.
(2) I believe punctuation marks are supposed to go at the end of the words, ie: "Mac.)" not "Mac)." ...Language majors, confirm?
(3) It would nice if we are to do cross-platform scripts, that you list the names for PC and Mac in the API.
(4) UI.toolbar_names.sort on the PC, ver 7.1 returns:
["Camera", "Construction", "DisplayMode", "Drawing", "Edit", "GettingStarted", "Google", "Principle", "Section", "Standard", "StandardViews", "VCB", "Walk"]
.
On the [Win32] Sketchup Menu: View > Toolbars(and toolbar captions):
Principle is Principal* Edit is Modification* VCB is Measurements* StandardViews is Views* Section is Sections* DisplayMode is FaceStyle* Walk is Walkthrough
These are on the [Win32] Menu: View > Toolbars but, missing from the UI toolbar methods:
LargeToolSet* Layers* SceneTabs (on View menu )* Shadows
Missing from View Menu and toolbar methods:
StatusBar
(We can toggle it on/off [with send_action on PC], so might as well add it to the toolbar methods so we can test it's visiblilty, and use set_toolbar_visible for cross platform [if it can be toggled on MAC.])* If a user has the StatusBar off, a tool might want to instead display a messagebox if it must inform the user of some fact, so it needs to test whether it's on/off.
(5) This same Toolbar Name Identifier Set is used with the following methods, and have the same problems, missing Identifiers, etc.
So.. we don't mind variation in the toolbar names/symbols, so long as we know what that variation is.
(An alternative... we might create tb_Name constants under the UI module that would be the same for both platforms.)
@dan rathbun said:
(An alternative... we might create tb_Name constantsunder the UI module that would be the same for both platforms.)
Here's an example, call it 'UI_tb_const.rb'
module UI
#
# Example ONLY
#
case Sketchup;;OS
when ;WIN
#
tb_CAM = 'Camera'.freeze
tb_CONS = 'Construction'.freeze
tb_DISP = 'DisplayMode'.freeze
tb_DRAW = 'Drawing'.freeze
tb_EDIT = 'Edit'.freeze
tb_GETS = 'GettingStarted'.freeze
tb_GOOG = 'Google'.freeze
tb_LTS = 'LargeToolSet'.freeze
tb_LAYR = 'Layers'.freeze
tb_STD = 'Standard'.freeze
tb_TABS = 'SceneTabs'.freeze
tb_PRIN = 'Principle'.freeze # spelling!
tb_SBAR = 'StatusBar'.freeze
tb_SECT = 'Section'.freeze
tb_SHAD = 'Shadows'.freeze
tb_VIEW = 'StandardViews'.freeze
tb_VCB = 'VCB'.freeze
tb_WALK = 'Walk'.freeze
#
when ;OSX
# what are the Mac Strings?
tb_CAM = 'Camera'.freeze
tb_CONS = 'Construction'.freeze
tb_DISP = 'DisplayMode'.freeze
tb_DRAW = 'Drawing'.freeze
tb_EDIT = 'Edit'.freeze
tb_GETS = 'GettingStarted'.freeze
tb_GOOG = 'Google'.freeze
tb_LTS = 'LargeToolSet'.freeze
tb_LAYR = 'Layers'.freeze
tb_STD = 'Standard'.freeze
tb_TABS = 'SceneTabs'.freeze
tb_PRIN = 'Principle'.freeze # spelling!
tb_SBAR = 'StatusBar'.freeze
tb_SECT = 'Section'.freeze
tb_SHAD = 'Shadows'.freeze
tb_VIEW = 'StandardViews'.freeze
tb_VCB = 'VCB'.freeze
tb_WALK = 'Walk'.freeze
#
end # case
end # module UI extension
Sketchup.send_action
http://code.google.com/apis/sketchup/docs/ourdoc/sketchup.html#send_action
You can toggle the StatusBar on/off in Ruby (PC only?) via:
Sketchup.send_action(59393)
The following have no effect on my PC in SU ver 7.1.x:
Sketchup.send_action(21019) hide Status bar and VCB
Sketchup.send_action(21020) show Status bar and VCB
Sketchup.send_action(21022) hide Status bar and VCB?
..whereas the above id 59393 does work for just the StatusBar.
[ NOTE: I've moved my VCB up to the 2nd line of the Top Toolbar Container in 2nd position after the Layers toolbar, so I'd not want the VCB turned off with the StatusBar anyhow. I see them as two different things. ]
@unknownuser said:
I thought that
begin ... rescue ... end
is required, but I am glad to hear that rescue alone is sufficient.
That is because in module definitions, the module
statement is a block statement so the word module
works the same as begin
(after all, the module
does need an end
.)
module My_Module
# method defs
# code goes here
rescue
# error handling code
else
# only do code if no exceptions
ensure
# always do this code on exit
end # the end of the method def
The same is true for method
definitions, where the def
keyword 'begins' the block.
def my_method
# code goes here
rescue
# error handling code
else
# only do code if no exceptions
ensure
# always do this code
end # the end of the module
@jim said:
Visibility:
Toolbar visibility is controlled by a "Visible" key in the Toolbar entry. If the "Visible" key does not exists, the Toolbar is visible. If it does exist and equals 0, the toolbar is not visible.
This Windows .bat file will turn all the toolbars on or off (including the Status bar! )
You can toggle the StatusBar on/off in Ruby (PC only?) via:
%(#BF0000)[Sketchup.send_action 59393]
I don't find a method to test it's visibility, tho. (Perhaps the %(#BF0000)[UI.toolbar_visible?]
method needs to be updated in this respect, along with the other bugs this method needs fixed.)
UPDATE - %(#BF0000)[send_action]
The following have no effect on my PC in ver 7.1.x:
%(#BF0000)[21019 hide Status bar and VCB 21020 show Status bar and VCB 21022 hide Status bar and VCB?]
..whereas the above id 59393 does work. (Also I have moved the VCB up to the 2nd line of the Top Toolbar Container, so it's not docked on the StatusBar.)
_
BarIDs (SU ver 7.1.xxxx)
**` 103 (0x0067) = Shadows
127 (0x007f) = Standard
136 (0x0088) = Walk(Through)
137 (0x0089) = Principal
211 (0x00d3) = LargeToolSet
220 (0x00dc) = Layers
221 (0x00dd) = VCB
355 (0x0163) = Face Style
360 (0x0168) = Camera
362 (0x016a) = Views
475 (0x01db) = Construction
477 (0x01dd) = Sections
499 (0x01f3) = Edit(Modification)
%(#000000)[501 (0x01f5) = Drawing
10617 (0x2979) = Google
21992 (0x55e8) = GettingStarted
59393 (0xe801) = StatusBar
59402 (0xe80a) = SceneTabs
87528 = 0x55e8 + 0x10000 (means that GettingStarted was there, but was pulled off the TBC or turned off; it's kind of like a placeholder. If you see 66013 (it was where the Sections tb was, ie 0x1dd + 0x10000 = 0x101dd which is 66013 decimal.)
Notes:
59402 - SU will not let this have a Visible=0 attribute if SceneTabs is checked in the Menu; it will be deleted from the registry when SU closes.]
__`**
It looks like SU does not update registry values for many things until it closes.
The opposite may also be true, that it doesn't check the registry for updates except on startup.
So changing registry values while SU is open probably won't work (for certain settings,) until the next session, and some of your changes may get overwritten when SU closes (if you change them while SU is running.)
So for each setting, keep track of whether it can or can't be set while SU is loaded.