Hi. I wanted to make a button with two actions: when it was pressed with the “SHIFT” pressed, and without it.
Here is the code that works on Windows. Please help with the OSX code.
require 'fiddle/import'
module User32
extend Fiddle::Importer
dlload 'user32'
extern 'int GetAsyncKeyState(int)'
end
toolbar = UI::Toolbar.new 'Test'
cmd = UI::Command.new('Shift_test') {
if (User32::GetAsyncKeyState VK_SHIFT)>0
puts 'SHIFT pressed'
else
puts 'SHIFT Not pressed'
end
}
toolbar = toolbar.add_item cmd
toolbar.show
The general approach to detect key presses (or mouse events for that matter) requires creating a Sketchup::Tool instance (irrespective of the operating system you are on).
You will need to define a class that implements the methods onKeyUp and/or onKeyDown of the Sketchup::Tool interface. (The documentation is here: https://ruby.sketchup.com/Sketchup/Tool.html.)
class MyCustomTool
def initialize
# Custom initialization (if needed).
end
def activate
puts "MyCustomTool is now active!"
end
def onKeyDown(key, repeat, flags, view)
puts "Pressed SHIFT" if key == VK_SHIFT
end
def onKeyUp(key, repeat, flags, view)
puts "Released SHIFT" if key == VK_SHIFT
end
def deactivate(view)
view.invalidate
end
end
Then you need to create an instance of this class and add it to the Sketchup::Tools stack like so:
Finally, just add these two lines inside your UI::Command block (while removing your current logic) and test the code by invoking your tool from the menu bar. The two messages should show up in the Ruby Console.
True, but this will not work for this special case. The reason is that the instancing and activation of the tool will begin intercepting key presses after the user has clicked on the toolbar button.
It also has the disadvantage that what the user has activated for a tool will be changed. Yes, the new tool can be popped off the toolstack, but it is likely the previous tool would be reset.
The answer is not that simple with regard to the Mac edition of SketchUp. There are various explanations on StackOverflow with regard to reading the keyboard modifiers without implementing an asynchronous responder (event handler). But this would require knowing what frameworks that SketchUp’s Mac edition uses. Carbon? Cocoa Quartz? AppKit? Foundation?, etc.
Oh, right. Now I understand the question… It feels very strange that one would want such behavior. Why not create two separate toolbar buttons then? This reminds me of how one can trigger different actions in macOS when pressing Alt (also called Option key) and then clicking on a button, which is incredibly unintuitive. I don’t even use such “features” as a result.
I wanted to create an additional function, not overload the user interface. For example, rotating a component by 90 degrees or 270. It seems Mac is losing out to Microsoft in this feature. I will be forced to define the platform and assign different functions.
Well, this is not the first time a coder has wanted more than one action per button. For example, in the past, it was desired to have a settings dialog popup when a tool’s toolbar button was double clicked. I think it was even formally requested.
But I think the main argument against was as you say … intuition, discoverability.
I do know (because I participated in the discussion) that a double-click option is easily doable by using a state variable to check if the button has been clicked twice. The trick is to delay action for a fraction of a second, giving enough time for a second click and so a second firing of the command’s proc.
Jim Foltz’ old Ruby toolbar plugin did this to allow setting the path to a ruby file I think, if memory serves. (He has long since left the SketchUp realm, so I don’t know if the plugin is available anymore. Likely not.)
I would rather we get a context click (right click) proc option for buttons.
But this also likely violates the K.I.S.S. principle (or the Principal of Least Surprise.)
So do I, with tweaks by me and @driven (who has seemingly also left the forum). I never noticed the double-click though. I’ll have to try it once I am again able to work at the computer.
I agree not overloading the UI is nice.
I am thinking about a command to move windows around taking care of the openings. So I was hoping I could use the arrow keys to indicate one of the 4 directions. I would not like to add 4 other buttons to my toolbar.
Of course there would be instructions in the status bar.
Some native commands do that when usibg keys; ctrl, opt, cmd …
but… maybe those cmds are not pure ruby coded.