GSLayer edited callback/notification

I cannot find any callback or notification posted when a layer’s paths/anchors/components/etc are edited.

I can observer GSGlyph.lastChange but that doesn’t tell me which layer has changed.

What exactly are you trying to do?

Monitor changes on any layer’s path/anchors/components/metrics and immediately do stuff with the new data. The layer will not necessarily be active.

I’ve had some luck by simultaneously observing NSUndoManagerCheckpointNotification on the layer’s undoManager, and also implementing -(void)processBezierPath:(NSBezierPath*)bezierPath openBezierPath:(NSBezierPath*)openBezierPath secondaryPath:(NSBezierPath*)secondaryPath forLayer:(GSLayer*)layer but I prefer if there’s a less hacky way.

Any news on this? I am working on a GlyphsPalette (in Objective C) that wants to be notified whenever, well, anything changes in the font.

What details do you need?

You can add yourself as an observer to the undoManager:

NSNotificationCenter* dnc = [NSNotificationCenter defaultCenter];
[dnc addObserver:self selector:@selector(undoManagerDidChange:) name:NSUndoManagerDidCloseUndoGroupNotification object:nil];
[dnc addObserver:self selector:@selector(undoManagerDidChange:) name:NSUndoManagerDidUndoChangeNotification object:nil];
[dnc addObserver:self selector:@selector(undoManagerDidChange:) name:NSUndoManagerDidRedoChangeNotification object:nil];
[dnc addObserver:self selector:@selector(undoManagerDidChange:) name:@"GSUndoNotification" object:nil];

and add a method:

- (void)undoManagerDidChange:(NSNotification*)notification {
	NSUndoManager* undoManager = [notification object];

	if ([undoManager isKindOfClass:NSClassFromString(@"GSUndoManager")]) {
		// glyph level undo
		GSGlyph* glyph =  [undoManager valueForKey:@"glyph"];
	}
	else {
		// font level undo
	}
}

(most of this written in Safari)

1 Like

Excellent, thanks! That code worked out of the box.

Just to be sure I understand:

If I use

[dnc addObserver:self selector:@selector(updateInterface:) name:@"GSUpdateInterface" object:nil];

instead of the above, it seems this practically gives me a callback for the same events but without being able to extract the glyph information. Is it different in other ways? Maybe more robust?

The GSUpdateInterface notification gives you more callbacks. Selection, master changes, zoom…

1 Like

Oh, yes, of course. After playing around a bit more it is becoming clearer.

Is there any way to capture when the user selects a different tool (e.g. Select Tool, Text Tool etc.)?

I need a layer update notification / observer, too. In order to increase speed of a plugin, I just want to redraw when something in the layer changed. I can use my observer mechanisms like in my Sync Tabs plugin, but then I need to check the width, the paths, the nodes, the components, the anchors, … all individually. Maybe there’s some implementation already? basically: pythonic way to notify that a layer just changed.

If you have some heavy computation, check the lastOperation property of the glyph. If that changes, you need to recompute.

1 Like

Awesome! Thanks so much @GeorgSeifert

Hey @GeorgSeifert, I’m looking for similar thing,although in python.
I wan’t to compute some stuff while user is changing position of nodes.

Right now I’m doing it with MOUSEDRAGGED callback, but it doesn’t work in every case. For example: whenever I run some filter operations, like RMX harmoniser, my computation is not being applied right after filter does its job.

Usually when I’m working with defcon, I’m adding an observer with “Glyph.Changed” notification to currently edited glyph.

Is there a similar feature in Glyphs’ python api?

Best

if you are only interested in the currently active layer, every time something changed you get a drawing callback. There might be a few more callbacks from changes you are not interested in. To filter those out, store the layer.parent.lastChange and check if in each drawing callback and check if is has changed.

1 Like

thx. will check it out