├── .gitignore ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── Gemfile ├── LICENSE ├── README.md ├── SketchUp Attribute Helper.sublime-project └── src ├── su_attributes.rb └── su_attributes └── core.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.sublime-workspace 2 | 3 | Gemfile.lock 4 | 5 | *.rbz 6 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. 3 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp 4 | // List of extensions which should be recommended for users of this workspace. 5 | "recommendations": [ 6 | // Spell checking code and comments are important. 7 | "streetsidesoftware.code-spell-checker", 8 | 9 | // Will make VSCode pick up .editorconfig. 10 | "editorconfig.editorconfig", 11 | 12 | // Essential for Ruby syntax highlighting and debugging. 13 | "rebornix.ruby", 14 | 15 | // For code insight and auto-complete. 16 | "castwide.solargraph" 17 | ], 18 | // List of extensions recommended by VS Code that should not be recommended for users of this workspace. 19 | "unwantedRecommendations": [] 20 | } 21 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | 8 | { 9 | "name": "Listen for rdebug-ide", 10 | "type": "Ruby", 11 | "request": "attach", 12 | "cwd": "${workspaceRoot}", 13 | "remoteHost": "127.0.0.1", 14 | "remotePort": "7000", 15 | "remoteWorkspaceRoot": "${workspaceRoot}" 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "solargraph.diagnostics": true, 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "Launch SketchUp in Ruby Debug mode", 8 | "type": "shell", 9 | "command": "skippy", 10 | "args": [ 11 | "sketchup:debug", 12 | "${input:sketchupVersion}" 13 | ], 14 | "runOptions": { 15 | "reevaluateOnRerun": false 16 | }, 17 | "problemMatcher": [] 18 | } 19 | ], 20 | "inputs": [ 21 | { 22 | "id": "sketchupVersion", 23 | "type": "pickString", 24 | "description": "SketchUp Version", 25 | "options": [ 26 | "2021", 27 | "2020", 28 | "2019", 29 | "2018", 30 | "2017" 31 | ], 32 | "default": "2021" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | group :development do 4 | gem 'minitest' # Helps solargraph with code insight when you write unit tests. 5 | gem 'rubocop', '~> 0.63.1' # Static analysis of Ruby Code. 6 | gem 'rubocop-sketchup', '~> 0.8.0' # Static analysis of SketchUp extensions. 7 | gem 'sketchup-api-stubs' # Auto-complete for the SketchUp Rub API. 8 | gem 'skippy', '~> 0.4.1.a' # Aid with common SketchUp extension tasks. 9 | gem 'solargraph' # For code-insight and RuboCop integration with VSCode. 10 | end 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 SketchUp 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sketchup-attribute-helper 2 | 3 | Inspect and visualize nested attributes in SketchUp models 4 | 5 | ## Operation 6 | 7 | After installing the SketchUp Attribute Helper you can access the tool under the `Extensions/Developer Menu -> Attribute Helper -> Visualize Selected`. To use the extension select a component who's attributes you wish to inspect then choose Visualize Selected. A dialog will appear which displays all the attributes for that component. There will be several sections for various groups of attributes. 8 | -------------------------------------------------------------------------------- /SketchUp Attribute Helper.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "folders": 3 | [ 4 | { 5 | "follow_symlinks": true, 6 | "path": "." 7 | } 8 | ], 9 | "settings": 10 | { 11 | "default_encoding": "UTF-8", 12 | "ensure_newline_at_eof_on_save": true, 13 | "rulers": 14 | [ 15 | 80 16 | ], 17 | "show_encoding": true, 18 | "show_line_endings": true, 19 | "tab_size": 2, 20 | "translate_tabs_to_spaces": true, 21 | "trim_trailing_white_space_on_save": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/su_attributes.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2021, Trimble Inc. 2 | # 3 | # License: The MIT License (MIT) 4 | # 5 | # A SketchUp Ruby Extension that surfaces attributes attached to components. 6 | # More info at https://github.com/SketchUp/sketchup-attribute-helper 7 | 8 | 9 | require 'sketchup.rb' 10 | require 'extensions.rb' 11 | 12 | #------------------------------------------------------------------------------- 13 | 14 | module Trimble 15 | module AttributeHelper 16 | 17 | ### CONSTANTS ### ------------------------------------------------------------ 18 | 19 | # Plugin information 20 | PLUGIN_ID = 'AttributeHelper'.freeze 21 | PLUGIN_NAME = 'SketchUp Attribute Helper'.freeze 22 | PLUGIN_VERSION = '1.0.3'.freeze 23 | 24 | # Resource paths 25 | FILENAMESPACE = File.basename(__FILE__, '.*') 26 | PATH_ROOT = File.dirname(__FILE__).freeze 27 | PATH = File.join(PATH_ROOT, FILENAMESPACE).freeze 28 | 29 | 30 | ### EXTENSION ### ------------------------------------------------------------ 31 | 32 | unless file_loaded?(__FILE__) 33 | loader = File.join( PATH, 'core.rb' ) 34 | ex = SketchupExtension.new(PLUGIN_NAME, loader) 35 | ex.description = 'Visually inspect nested attributes in SketchUp.' 36 | ex.version = PLUGIN_VERSION 37 | ex.copyright = 'Trimble Inc © 2015-2021' 38 | ex.creator = 'SketchUp' 39 | Sketchup.register_extension(ex, true) 40 | end 41 | 42 | end # module AttributeHelper 43 | end # module Trimble 44 | 45 | #------------------------------------------------------------------------------- 46 | 47 | file_loaded(__FILE__) 48 | 49 | #------------------------------------------------------------------------------- 50 | -------------------------------------------------------------------------------- /src/su_attributes/core.rb: -------------------------------------------------------------------------------- 1 | # Copyright 2014-2021, Trimble Inc. 2 | # 3 | # License: The MIT License (MIT) 4 | 5 | require "sketchup.rb" 6 | require "stringio" 7 | 8 | module Trimble 9 | module AttributeHelper 10 | 11 | PLUGIN = self 12 | 13 | class << self 14 | attr_reader :app_observer 15 | attr_reader :model_observer 16 | attr_reader :selection_observer 17 | end 18 | 19 | 20 | def self.visualize_selected 21 | content = self.traverse_selected 22 | html = self.wrap_content(content) 23 | 24 | options = { 25 | :dialog_title => "Attribute Visualizer", 26 | :preferences_key => 'AttributeVisualizer', 27 | :scrollable => true, 28 | :resizable => true, 29 | :height => 300, 30 | :width => 400, 31 | :left => 200, 32 | :top => 200 33 | } 34 | @window ||= UI::WebDialog.new(options) 35 | @window.set_html(html) 36 | @window.set_on_close { 37 | @window = nil 38 | self.detach_observers 39 | } 40 | unless @window.visible? 41 | @window.show 42 | self.attach_observers 43 | end 44 | end 45 | 46 | 47 | def self.attach_observers 48 | @app_observer ||= AppObserver.new 49 | @model_observer ||= ModelObserver.new 50 | @selection_observer ||= SelectionObserver.new 51 | model = Sketchup.active_model 52 | Sketchup.remove_observer(@app_observer) 53 | model.remove_observer(@model_observer) 54 | model.selection.remove_observer(@selection_observer) 55 | Sketchup.add_observer(@app_observer) 56 | model.add_observer(@model_observer) 57 | model.selection.add_observer(@selection_observer) 58 | end 59 | 60 | 61 | def self.detach_observers 62 | Sketchup.remove_observer(@app_observer) 63 | Sketchup.active_model.remove_observer(@model_observer) 64 | Sketchup.active_model.selection.remove_observer(@selection_observer) 65 | end 66 | 67 | 68 | def self.traverse_selected 69 | html = StringIO.new 70 | 71 | model = Sketchup.active_model 72 | selection = model.selection 73 | 74 | if selection.empty? 75 | if model.active_path.nil? 76 | entity = model 77 | else 78 | entity = model.active_path.last 79 | end 80 | else 81 | return "Invalid selection size" unless selection.size == 1 82 | entity = selection[0] 83 | end 84 | 85 | html.puts "
#{html_key} | #{html_value} | #{value.class} |
" 133 | html.puts self.format_dictionary(sub_dic, path) 134 | html.puts " |