This is the code I use for it.
I kinda implemented it in an amalgamated fashion, so you find the class definition and then the implementation of the methods and functions, too… if you are going to use this in your code, probably you will need to spread the different part of it among header and source files
/********* Start of inlined file: oj_BestTextEditor.h *********/
#ifndef __OJ_BESTTEXTEDITOR_H__
#define __OJ_BESTTEXTEDITOR_H__
class HackedTextEditor1 :
public TextEditor
{
// ---------- members
bool spippoling; // Didn't know how to call this flag... if you come up with a meaningful name, let me know. This has no meaning
Component* storedParentComponent;
Rectangle <int> storedBoundsInParentComponent;
public:
// ---------- constructors
HackedTextEditor1 (const String& componentName = String::empty, const tchar passwordCharacter = 0);
virtual ~HackedTextEditor1 ();
// ---------- callbacks
virtual void focusGained (FocusChangeType cause);
virtual void focusLost (FocusChangeType cause);
private:
// ---------- not implemented
/** @internal */
HackedTextEditor1 (const HackedTextEditor1&);
/** @internal */
const HackedTextEditor1& operator= (const HackedTextEditor1&);
};
TextEditor* oj_createBestTextEditorForPlugin (const String& componentName = String::empty, const tchar passwordCharacter = 0) throw ();
TextEditor* oj_createBestTextEditor (const String& componentName = String::empty, const tchar passwordCharacter = 0) throw ();
#endif // __OJ_BESTTEXTEDITOR_H__
/********* End of inlined file: oj_BestTextEditor.h *********/
/**
Same parameters of TextEditor(...)
*/
HackedTextEditor1::HackedTextEditor1 (const String& componentName, const tchar passwordCharacter) :
TextEditor (componentName, passwordCharacter),
spippoling (false)
{
}
HackedTextEditor1::~HackedTextEditor1()
{
}
void HackedTextEditor1::focusGained (FocusChangeType cause)
{
if(spippoling)
return;
TextEditor::focusGained(cause);
if(!isOnDesktop())
{
storedParentComponent = getParentComponent();
jassert(storedParentComponent != 0);
storedBoundsInParentComponent = getBounds();
spippoling = true;
addToDesktop(0);
grabKeyboardFocus();
spippoling = false;
}
}
void HackedTextEditor1::focusLost (FocusChangeType cause)
{
if(spippoling)
return;
if(isOnDesktop())
{
jassert (storedParentComponent != 0);
spippoling = true;
storedParentComponent->addChildComponent(this);
setBounds(storedBoundsInParentComponent);
spippoling = false;
}
TextEditor::focusLost(cause);
}
TextEditor* oj_createBestTextEditorForPlugin (const String& componentName, const tchar passwordCharacter) throw ()
{
static PluginHostType hostType;
#if JUCE_MAC
return new TextEditor (componentName, passwordCharacter);
#elif JUCE_WINDOWS
if (hostType.isTracktion() || hostType.isSonar())
return new TextEditor (componentName, passwordCharacter);
return new HackedTextEditor1 (componentName, passwordCharacter);
#else
#error Unsupported OS
#endif
}
TextEditor* oj_createBestTextEditor (const String& componentName, const tchar passwordCharacter) throw ()
{
#if JucePlugin_Build_Standalone
return new TextEditor (componentName, passwordCharacter);
#else
return oj_createBestTextEditorForPlugin (componentName, passwordCharacter);
#endif
}
Basically, calling oj_createBestTextEditor with the same parameters as the TextEditor constructor, will result in an appropriate TextEditor being created for you, provided that you correctly set the JucePlugin_Build_Standalone.
If you are using this in a plug-in only project, you can use oj_createBestTextEditorForPlugin directly.