Vanilla: make EditText arrow-savvy

Do a forum search on “GSSteppingTextField” and thou shalst find.

You are making a textfeld with the arguments for a table.
And I think that vanilla is still using cells instead of views to build the table. So you need to make a text field cell (that implements the stepping) and tell vanilla to use it.

It might be easier to build the UI in Xcode where you have much more control.

I tried using this with list instead:

self.w.list = List2((10, 40, -10, -70), [], columnDescriptions=[
            {"title": "Glyph Name", "identifier": "name", "width": 150},
            {"title": "Anchor Name", "identifier": "anchor", "width": 100},
            {"title": "X", "identifier": "x", "width": 50, "editable": True},
            {"title": "Y", "identifier": "y", "width": 50, "editable": True},
        ], editCallback=self.editCallback)
self.w.list = GSSteppingTextField.alloc().init()

Is list the object to initialize? and is the order like the above? (learning as I am going here)

With this, I get the error: AttributeError: 'GSSteppingTextField' object has no attribute 'set' there is this in the code self.w.list.set(self.data)

Also, tried searching for GSSteppingTextField in the Method Reported for more clues but there were no results.

As somebody who also loves vanilla but who has also made a slow transition to coding with XCode, I really recommend making the jump. Coding UIs in XCode is much more powerful and flexible than in vanilla. Sure, it’s an extra learning curve, but that’s always good :wink:

I tried this:

  1. modifying your example of subclass of EditBox to be a subclass of List (with L capitalized)
  2. instead of nsTextFieldClass applying the GSSteppingTextField to nsTextFieldCell (is this implementing the stepping to the TextFieldCell?)
  3. using List2 as the class name
from vanilla import *
from GlyphsApp import *

GSSteppingTextField = objc.lookUpClass("GSSteppingTextField")
class List2 (List):
	nsTextFieldCell = GSSteppingTextField
	def _setCallback(self, callback):
		super(List2, self)._setCallback(callback)
		if callback is not None and self._continuous:
			self._nsObject.setContinuous_(True)
			self._nsObject.setAction_(self._target.action_)
			self._nsObject.setTarget_(self._target)

class ListDemo():
	def __init__(self):
		self.w = Window((200, 100))
		self.w.myList = List2((0, 0, -0, -0),
			[{"X": "100", "Y": "0"}, {"X": "200", "Y": "300"}],
			columnDescriptions=[
				{"title": "X", "identifier": "x", "width": 50, "editable": True},
				{"title": "Y", "identifier": "y", "width": 50, "editable": True},
		], editCallback=self.editTextCallback, continuous=True)
		self.w.open()
		
	def editTextCallback(self, sender):
		print ("text entry!", sender.get())

ListDemo()

Continuous isn’t an argument for list so it is throwing an error for that.
I’m not sure how to tell vanilla to use it. How do I specific to the list or specific cells to use stepping.
Sorry if I am not fully understanding.

Just let me know where I can sign-up for that workshop;-)

You need to understand the difference between the different classes that are in play here.

The List represents an NSTableView. It deals with all kind of things (row, column, selection …). Each cell in the table can have different types. Those cells are represented by NSCell (more specifically NSTextFieldCell, NSButtonCell) objects or by full NSViews.

As far as I can see, the The List2 class in vanilla will use views to display. See the doc string of the List2 class if you can figure out how to set it up. You need to put the info into columnDescriptions. Confusingly, they called it "cellClass" where you need to put in a view class (or the vanilla wrapper of a view).

1 Like

Appreciate the explanation Georg. I’ll give it another go but feels like this might beyond me (for now).

I’m by no means very knowledgeable on plugin coding in XCode. This tutorial is very good, though (further down): Writing plug-ins | Glyphs

Tried some more. Found this demo that uses List2 and cellClass= EditTextList2Cell (the doc says An object that displays text in a List2 column), I managed to isolate nsTextFieldClass that prints out <objective-c class NSTextField at 0x7fff937d0828>.

So it feels like it’s getting close but it’s still not working. Tried with textField = GSSteppingTextField or textField = GSSteppingTextField.alloc().init() Not sure why but compared to your subclass example, GSSteppingTextField is applied to the NSTextField inside the def.

from vanilla import *
from GlyphsApp import *

GSSteppingTextField = objc.lookUpClass("GSSteppingTextField")
class RightAlignEditTextList2Cell(vanilla.EditTextList2Cell):
	def __init__(self, *args, **kwargs):
		super().__init__(*args, **kwargs)
		editText = self.editText
		print (editText.nsTextFieldClass)
		textField = editText.nsTextFieldClass
#		textField = GSSteppingTextField
		textField = GSSteppingTextField.alloc().init()

class Test:

    def __init__(self):
        items = [
            dict(left="A", right="1"),
            dict(left="BB", right="10"),
            dict(left="CCC", right="100"),
        ]
        columnDescriptions = [
            dict(
                identifier="left",
                width=75
            ),
            dict(
                identifier="right",
                width=75,
                cellClass=RightAlignEditTextList2Cell,
                editable=True
            )
        ]

        self.w = vanilla.Window((200, 200))
        self.w.l = vanilla.List2(
            (10, 10, -10, -10),
            items,
            columnDescriptions=columnDescriptions
        )
        self.w.open()

Test()