Hi!
I want to make a plugin with a custom info box (or inspector). I read the Select Tool guide, and try to use vanilla
library to create GUI. I use the following code:
from GlyphsApp.plugins import *
from vanilla import *
from vanilla.vanillaGroup import Group
import objc
# Our own patched Vanilla Group class
class PatchedGroup(Group):
nsViewClass = objc.lookUpClass("GSInspectorView") # GSInspectorView
class CJKMetrics(ReporterPlugin):
def settings(self):
self.menuName = 'CJK Metrics'
self.name = 'CJK Metrics'
# Create Vanilla window and group with controls
viewWidth = 150
viewHeight = 40
self.sliderMenuView = Window((viewWidth, viewHeight))
# Using PatchedGroup() here instead of Group()
self.sliderMenuView.group = PatchedGroup((0, 0, viewWidth, viewHeight))
self.sliderMenuView.group.text = TextBox((10, 0, -10, -10), self.name)
self.sliderMenuView.group.slider = Slider((10, 18, -10, 23), callback=self.sliderCallback)
# Define the menu
self.generalContextMenus = [
{"view": self.sliderMenuView.group.getNSView()}
]
# Prints the slider’s value
def sliderCallback(self, sender):
print('Slider value:', sender.get())
But I can only find the group added into the context menu, rather than the info box:
Could you please explain what happens here and how I can add the custom info box?
By the way, in the original guide, the statement nsViewClass = GSInspectorView
leaves an error NameError: name 'GSInspectorView' is not defined
, so I use objc.lookUpClass("GSInspectorView")
instead. Is this correct? And if so, please update the document, thank you!
You are adding your view to the content menu (# Define the menu
).
What does the slider change? It might be better off in the context menu after all.
You need to add a callback “GSInspectorViewControllersCallback” and implement
def inspectorViewControllersForLayer_(self, layer):
return [self]
def view(self):
return self.sliderMenuView.group.getNSView()
inspectorViewControllersForLayer_
is supposed to return NSViewControllers, but any object that can return a view will do.
This his the full code:
import objc
from GlyphsApp import *
from GlyphsApp.plugins import *
from vanilla import *
from vanilla.vanillaGroup import Group
# Our own patched Vanilla Group class
class PatchedGroup(Group):
nsViewClass = objc.lookUpClass("GSInspectorView") # GSInspectorView
class CJKMetrics(ReporterPlugin):
@objc.python_method
def settings(self):
self.menuName = 'CJK Metrics'
self.name = 'CJK Metrics'
# Create Vanilla window and group with controls
viewWidth = 150
viewHeight = 40
self.sliderWindow = Window((viewWidth, viewHeight))
self.sliderWindow.group = PatchedGroup((0, 0, viewWidth, viewHeight)) # Using PatchedGroup() here instead of Group()
self.sliderWindow.group.text = TextBox("auto", self.name)
self.sliderWindow.group.slider = Slider("auto", callback=self.sliderCallback_)
rules = [
"H:|-[text]-|",
"H:|-[slider]-|",
"V:|-3-[text]-2-[slider]-3-|",
]
metrics = {}
self.sliderWindow.group.addAutoPosSizeRules(rules, metrics)
GSCallbackHandler.addCallback_forOperation_(self, "GSInspectorViewControllersCallback")
def inspectorViewControllersForLayer_(self, layer):
return [self]
def view(self):
return self.sliderWindow.group.getNSView()
The auto layout stuff is needed as Glyphs internally uses it and the way vanilla sets up the views is not playing well together with it.
I think your solution can work now. Thank you!
In G3 this method does not work. Could you please provide an updated version for this patch?