Protected Label editor please


#1

I’d like the “editor” member of the Label class to be protected, since I need to addToDesktop() it in a subclass of Label.

This is because I found no other way to overcome the bug of some hosts not passing pressed keys to plug-ins. The only solution that works on some hosts (i.e. Ableton Live on Windows) is to have the TextEditor added to the desktop for proper input by the user.

I thought of adding my custom code in createEditorComponent, which is virtual, but unfortunately moving the TextEditor to the desktop at that time is too early for two reasons:

  1. Label calls enterModalState() on itself inside showEditor(), thus disabling any possibility of acting on the TextEditor if it is on the desktop rather than a child of the Label itself

  2. I can’t addToDesktop the TextEditor when it is created, because its size and position are not correct at that time. Indeed they are set up later in showEditor(), when the resized() call is made, much later than createEditorComponent has been called.

Because of these reasons, I thought of re-writing myself the two methods showEditor and hideEditor, but I can’t do that as the editor member is protected.

Even better, adding two empty protected virtual functions editorShown and editorBeingHidden would greatly help in customizing the behaviour of the TextEditor, in the same direction of what createEditorComponent is supposed to lead.


#2

Surely this stuff works in the tip code, because in carbon hosts like Ableton, the plugin UI is basically a window on the desktop that sits above the host’s window - so in that case I’d expect it to make no difference if you put it in a different window…


#3

Yes but… on Windows it still does not work, so I need the workaround anyway…


#4

Fair enough. Maybe if it just called enterModalState on the editor rather than the label, that might do the trick? There’s no particular reason why it needs to make the whole label modal.


#5

Mmm… I fear you’re putting the Label into modal state instead of the editor itself because it’s only the modal component that gets notified via inputAttemptedWhenModal() of an action that would “break” the modal state (according to the documentation of inputAttemptedWhenModal()).

That way, you shut down the editor when something would put the Label out of modal state.

If you were putting the editor in modal state, the editor’s inputAttemptedWhenModal() would be called, not the Label’s one.

IMHO, the current one is a very clever and clean design, it just needs a few more handles for those (like me) struggle with complicated compatibility problem.


#6

Ah yes, that’s a good point. But then, if the label is modal and you’re putting the editor in a new window, that’ll also mess up the inputAttemptedWhenModal() callback, won’t it?


#7

No… the Label seem to get the inputAttemptWhenModal even if the editor is on the desktop… but it does not appear on the screen probably because it is under the window itself.

What if I take the whole Label (with its child TextEditor) to the desktop right after the editor is shown, and I bring it back to its parent window immediately before dismissing it?

I could do that if I had those editorShown and aboutToHideEditor callbacks… do you think is a suitable solution?


#8

That’s a pretty good idea, actually. It sounds more dependable than relying on the inputAttemptWhenModal callback to happen as you want it to when the two items are in separate windows.


#9

I don’t remember where, but I read that adding to the desktop components that are not declared Opaque may result in potential performance problems… since the label 99% of the times will be a string with no background color, is it safe to add it to the desktop?


#10

That’s only a problem for large windows in XP, because repainting any part of them involves repainting the whole thing. Not a problem for small stuff like labels.


#11

Hi, I’ve seen some updates to the tip lately, but none of them included the changes proposed here to the Label component.

To summarize:

  • protected TextEditor member instead of private

  • two public virtual callbacks (empty in Label, to be implemented in subclasses), one called at the moment the TextEditor for editing the label is ready on screen (but before any editing operation on it), and the other called when the editing has ended and the editor is about to be closed and dismissed.

Is it possible to fulfill these requests?


#12

Sorry, just didn’t have time to do that. How about not making the editor object protected, but having these callbacks?

virtual void editorShown (TextEditor* editorComponent);
virtual void editorHidden();

#13

the “hidden” callback should be called before the editor to actually disappear, something like editorAboutToDisappear, and thus the TextEditor* editor parameter would be useful in both of the callbacks.

Ok for letting the editor private


#14

Ok, that sounds sensible.


#15

Perfect!
Just implemented the new virtual callbacks and it’s the first time I get proper text input with every host I tested. I’ve been waiting for this a long time.
Thanks a lot.

btw: is it normal that I have to set the bounds of the label to the original coordinates after adding it back to its original parent? It’s no problem, just a question if it’s ok that the coordinates are lost somewhere between adding to desktop and moving it back.


#16

It seems sensible to me: you could virtually detach the Label from one parent component and, after bringing it to the desktop, add it again as a child of a different parent… in that situation it seems clear to me that you’d need to re-set the bounds for the Label within the new parent.

The case of detaching the Label and then adding it back to the same parent is the same case, it only differs for the fact that “accidentally” the source and destination parents are the same


#17

Well, yes, if you stick it on the desktop its coords are relative to the top of the screen, so are completely different to having it inside a parent.