I’m developing my first extension, but I’ve run into an issue where I need to use a global variable. Arghhh!
The issue is with the LanguageHandler class, it seems it must be instantiated in the top level ruby file (in the Plugins folder), not in the sub-folder.
I’ve applied to be a developer, but I don’t yet have access to relevant documentation.
e.g. Homepage | SketchUp Developer
Folder structure is, I hope, in accordance with requirements:
I’d like to get rid of the $centaur_gltf_export_translate global, but creating the LanguageHandler in the gltfExport.rb file fails, or rather, doesn’t find anything, due to it residing in the sub-folder.
You could use a constant in your top level namespace to point at the LangHandler object instead of using a global variable.
I first saw this in ThomThom’s code and until that point I had never really thought of that constants can point to any object, not just primitive data types.
Regarding the Permission denied I also get the same error. The docs work in mysterious ways.
I didn’t quite follow, a constant is just a variable written in all caps, right?
Replacing $centaur_gltf_export_translate with TRANSLATOR merely gave me an error about an uninitialized constant in the lower level module.
module Centaur
module GltfExporter
# add item if menu is not already loaded
unless file_loaded?(__FILE__)
main_menu = UI.menu("Plugins").add_submenu($centaur_gltf_export_translate['menuMain'])
main_menu.add_item($centaur_gltf_export_translate['menuGltf']) { GltfExport.new.Export(false) }
main_menu.add_item($centaur_gltf_export_translate['menuGlb']) { GltfExport.new.Export(true) }
file_loaded(__FILE__)
end
class GltfExport
Maybe the global is acceptable for publishing the script?
# =begin
#
# Copyright 2016, john@drivenupthewall.co.uk
#
# All Rights Reserved - for now...
#
# =end
module JcB
# plugin namespace for all methods...
module SineCircle
NAME = 'sine_circle'
TITLE = 'Sine Circle'
VERSION = '1.0.3'
PATH = __dir__ rescue File.dirname(__FILE__)
# pactched languagehandler.rb for earlier versions
require (File.join(PATH, "jcb_#{NAME}/bin/lang_patch")) if Sketchup.version.to_i < 14
TRANSL8 = LanguageHandler.new( "jcb_#{NAME}.strings")
extension_name = TRANSL8["#{TITLE}"]
PLUGIN = SketchupExtension.new(extension_name, "jcb_#{NAME}/#{NAME}_menu")
# translatable text on separate lines for easy extraction [aviod quotation marks]
PLUGIN.description =
TRANSL8['This plugin allows the creation of cylindercal sinusoldal curves'] + ".\n" +
TRANSL8['It preserves settings per Session'] + ".\n" +
TRANSL8['It is advised to work at a large scale [use meters as if millimetres]'] + ".\n" +
TRANSL8['The string file can be translated'] + "..."
PLUGIN.version = VERSION
PLUGIN.copyright = '2016 john@drivenupthewall.co.uk'
PLUGIN.creator = 'john@drivenupthewall.co.uk'
Sketchup.register_extension( PLUGIN, true )
load File.join(PATH, File.basename(__FILE__, '.rb'), "version_#{VERSION}.rb")
end
end
then
# an attempt at a generic menu loader that needs only the lang file ...
module JcB
# the menu ruby loads the logic ruby on demand...
module SineCircle
extend self
# add rescue for pre Ruby 2
path = __dir__ rescue File.dirname(__FILE__)
# to handle the new file formats for toolbar images...
ext = '.png'
ver = Sketchup.version.to_i
if ver >= 16
osx = Sketchup.platform == :platform_osx
ext = osx ? '.pdf' : '.svg'
end
title = TRANSL8["#{TITLE}"]
# create toolbar
tb = UI::Toolbar.new(title)
# menu item
menu = UI.menu('Plugins', title)
# add a cmd for menu, toolbar or shortcut item...
cmd = UI::Command.new(title) do
# use load for testing locally and require for production without...
load File.join(path, "#{NAME}_logic.rb") if ENV["LOGNAME"] == "johns_iMac"
require File.join(path, "#{NAME}_logic")
# this method becomes available on load as it's defined under the same namespace...
user_input
end
cmd.tooltip = cmd.status_bar_text = TRANSL8['Create sine waves on cylinders'] + '...'
cmd.large_icon = cmd.small_icon = File.join(path, 'Resources', 'images', "#{NAME}#{ext}")
unless file_loaded? "#{NAME}_menu.rb"
menu.add_item(cmd)
tb.add_item(cmd)
# showing the toolbar
tb.get_last_state == -1 ? tb.show : tb.restore
file_loaded("#{NAME}_menu.rb")
end # unless
end # module SineCircle
end # module JcB
@DanRathbun,
Oh, that is the link that I did use!
I found the old link on this forum related to the LanguageHandler class, and thought there must be extra information hidden away from prying eyes.
Thanks for clarifying! And thanks for all the help you have given to others on this forum!
Incidentally, is the folder for English supposed to be ‘en’ on this YARD API doc, or is it supposed to read ‘en-US’?
Because if I use ‘en’, it doesn’t find the file.
It’s supposed to be “en-US” the same as returned by the Sketchup::get_locale() method.
Not. There is no good use of globals for data or objects only to be used by a single extension or module.
Ruby has 2 things. Objects and references that point at objects.
A module is an instance of class Module, and in your examples, you’ve created a module instance object referenced as the identifier Centaur, which is a “constant” because it begins with a capital letter.
Class and module references are CamelCase in Ruby by convention. Constants that point at other objects (data, strings, etc.) are all UPPERCASE by convention.
But in Ruby references can be reassigned at any time to point at any other object (of any class.) This is still true for constants with the Ruby versions that SketchUp still uses. Warnings are generated when doing constant reassignments because it is poor programming practice and perhaps in the future it may not be allowed at all. (This cannot be done in many other coding languages.)
In Ruby “variables” are just references that are expected to be reassigned to point at other objects later on. It could be reassigned to point at the nil object, or one of the other objects in the ordinal set of the Integer class, or a new text string, etc. Whatever.