// Request keyboard focus here, so that text fields do not get them automatically.
setWantsKeyboardFocus(true);
#if _WIN32
class ModalTextEditor: public juce::TextEditor, public juce::TextEditorListener
{
public:
explicit ModalTextEditor();
virtual ~ModalTextEditor();
public:
void setTextColour
( const juce::Colour& colour );
void setFocusedTextColour
( const juce::Colour& colour );
virtual void focusGained
( juce::Component::FocusChangeType cause );
protected:
void updateTextColour();
virtual void focusLost
( juce::Component::FocusChangeType cause );
//-- TextEditorListener
void textEditorTextChanged
( TextEditor& editor ) { };
void textEditorReturnKeyPressed
( TextEditor& editor );
void textEditorEscapeKeyPressed
( TextEditor& editor );
void textEditorFocusLost
( TextEditor& editor ) { };
private:
juce::Colour m_textColour;
juce::Colour m_focusedTextColour;
juce::Component* m_oldParent;
juce::Rectangle<int> m_oldBounds;
bool m_isSonar;
juce::String m_textBeforeEdit;
};
//-----------------------------------------------------------------------------------------
#else
class ModalTextEditor: public juce::TextEditor, public juce::TextEditorListener
{
public:
ModalTextEditor();
virtual ~ModalTextEditor();
public:
void setTextColour
( const juce::Colour& colour ) { };
void setFocusedTextColour
( const juce::Colour& colour ) { };
protected:
void mouseDown
( const juce::MouseEvent& e );
//-- TextEditorListener-Methoden
void textEditorTextChanged
( juce::TextEditor& editor ) { };
void textEditorReturnKeyPressed
( juce::TextEditor& editor );
void textEditorEscapeKeyPressed
( juce::TextEditor& editor );
void textEditorFocusLost
( juce::TextEditor& editor ) { };
private:
juce::String m_textBeforeEdit;
};
#endif
#if _WIN32
//==============================================================================
// Windows
//==============================================================================
ModalTextEditor::ModalTextEditor()
: juce::TextEditor("ModalTextEditor")
, m_oldParent(0)
, m_isSonar(false)
, m_textBeforeEdit("")
{
setPopupMenuEnabled(false);
setOpaque(true);
addListener(this);
// Set <m_isSonar>.
const juce::String hostPath(juce::File::getSpecialLocation(juce::File::hostApplicationPath).getFullPathName());
const juce::String hostFilename(juce::File(hostPath).getFileName());
m_isSonar = hostFilename.containsIgnoreCase("SONAR");
};
//------------------------------------------------------------------------------
ModalTextEditor::~ModalTextEditor()
{
};
//------------------------------------------------------------------------------
void ModalTextEditor::focusGained
( juce::Component::FocusChangeType cause )
{
if(m_isSonar)
{
juce::TextEditor::focusGained(cause);
}
else
{
if(!isOnDesktop())
{
m_oldBounds = getBounds();
m_oldParent = getParentComponent();
m_textBeforeEdit = getText();
addToDesktop(juce::ComponentPeer::windowIsTemporary);
updateTextColour();
grabKeyboardFocus();
}
repaint();
}
};
//------------------------------------------------------------------------------
void ModalTextEditor::focusLost
( juce::Component::FocusChangeType cause )
{
if(!m_isSonar)
{
if(isOnDesktop() && m_oldParent != 0)
{
m_oldParent->addChildComponent(this);
updateTextColour();
setBounds(m_oldBounds);
setHighlightedRegion(juce::Range<int>(0, 0));
}
repaint();
}
if(isCurrentlyModal())
{
exitModalState(0);
}
juce::TextEditor::focusLost(cause);
};
//------------------------------------------------------------------------------
void ModalTextEditor::textEditorReturnKeyPressed
( juce::TextEditor& editor )
{
focusLost(focusChangedDirectly);
moveKeyboardFocusToSibling(true);
repaint();
};
//------------------------------------------------------------------------------
void ModalTextEditor::textEditorEscapeKeyPressed
( juce::TextEditor& editor )
{
editor.setText(m_textBeforeEdit);
focusLost(focusChangedDirectly);
moveKeyboardFocusToSibling(true);
repaint();
};
#else
//==============================================================================
// MAC
//==============================================================================
ModalTextEditor::ModalTextEditor()
: juce::TextEditor("ModalTextEditor")
, m_textBeforeEdit("")
{
addListener(this);
};
//------------------------------------------------------------------------------
ModalTextEditor::~ModalTextEditor()
{
};
//------------------------------------------------------------------------------
void ModalTextEditor::mouseDown
( const juce::MouseEvent& e )
{
juce::TextEditor::mouseDown(e);
m_textBeforeEdit = getText();
grabKeyboardFocus();
};
//------------------------------------------------------------------------------
void ModalTextEditor::textEditorReturnKeyPressed
( juce::TextEditor& editor )
{
moveKeyboardFocusToSibling(true);
};
//------------------------------------------------------------------------------
void ModalTextEditor::textEditorEscapeKeyPressed
( juce::TextEditor& editor )
{
moveKeyboardFocusToSibling(true);
editor.setText(m_textBeforeEdit);
};
//------------------------------------------------------------------------------
#endif
///////////////////////////////////////////////////////////////////////////
class KeyboardFocusWorkaroundListener : public MouseListener,
public TextEditorListener
{
public:
KeyboardFocusWorkaroundListener(TextEditor* pTextEditor)
: m_pTextEditor(pTextEditor),
m_bRemoveWhenLosingFocus(false),
m_pOriginalParent(0),
m_bIsOnDesktop(false)
{
}
void mouseDown(const MouseEvent& e)
{
addEditorToDesktop();
}
void mouseExit(const MouseEvent e)
{
}
virtual void textEditorTextChanged (TextEditor& editor) { }
virtual void textEditorReturnKeyPressed (TextEditor& editor)
{
removeEditorFromDesktop();
}
virtual void textEditorEscapeKeyPressed (TextEditor& editor)
{
removeEditorFromDesktop();
}
virtual void textEditorFocusLost (TextEditor& editor)
{
if (m_bRemoveWhenLosingFocus)
{
removeEditorFromDesktop();
}
else
{
m_bRemoveWhenLosingFocus = true;
}
}
juce_UseDebuggingNewOperator
protected:
void addEditorToDesktop()
{
if (m_bIsOnDesktop) return;
m_originalBounds = m_pTextEditor->getBounds();
m_pOriginalParent = m_pTextEditor->getParentComponent();
m_bRemoveWhenLosingFocus = false;
m_pTextEditor->addToDesktop(ComponentPeer::windowIsTemporary);
m_pTextEditor->grabKeyboardFocus();
m_bIsOnDesktop = true;
}
void removeEditorFromDesktop()
{
if (!m_bIsOnDesktop) return;
m_pTextEditor->removeFromDesktop();
if (m_pOriginalParent != 0)
{
m_pOriginalParent->addChildComponent(m_pTextEditor);
}
m_pTextEditor->setBounds(m_originalBounds);
m_bIsOnDesktop = false;
}
private:
bool m_bIsOnDesktop;
bool m_bRemoveWhenLosingFocus;
Rectangle<int> m_originalBounds;
Component* m_pOriginalParent;
TextEditor* m_pTextEditor;
};
#ifndef __MYSLIDERLABEL_HEADER__
#define __MYSLIDERLABEL_HEADER__
#include "MySlider.h"
class MySlider;
class MySliderTextEditor : public TextEditor
{
public:
// if a mouse down event happens, exit the modal text editor window
bool canModalEventBeSentToComponent (const Component* comp)
{
if (comp->isMouseButtonDownAnywhere())
{
exitModalState(0);
}
return false;
}
};
class MySliderLabel : public Label
{
public:
MySliderLabel();
~MySliderLabel();
void setText(const String &text)
{
mText = text;
repaint();
}
const String& getText(){return mText;}
void edit();
bool isBeingEdited(){return mbLabelIsEdited;};
private:
String mText;
MySlider* mpSlider;
bool mbLabelIsEdited;
void textEditorReturnKeyPressed (TextEditor &editor)
{
editor.exitModalState(0);
}
void textEditorEscapeKeyPressed (TextEditor &editor)
{
editor.exitModalState(0);
}
void textEditorFocusLost (TextEditor &editor)
{
editor.exitModalState(0);
}
void mouseUp (const MouseEvent& e);
};
#endif// MySliderLabel gets the focus on the sliderLabel
#include "MySliderLabel.h"
MySliderLabel :: MySliderLabel(Slider* slider)
{
setRepaintsOnMouseActivity(true);
mpSlider = (MySlider*) slider;
mpSlider->setSliderLabelPtr(this);
mbLabelIsEdited = false;
}
MySliderLabel :: ~MySliderLabel()
{
}
// Caledl from MySlider::ShowTextEditor: pops up a modal text editor
void MySliderLabel :: edit()
{
mbLabelIsEdited = true;
MySliderTextEditor* ed = new MySliderTextEditor();
ed->setColour(TextEditor::backgroundColourId,Colours::white);
ed->setColour(TextEditor::textColourId,Colours::black);
ed->setColour(TextEditor::highlightColourId,Colours::black);
ed->setColour(TextEditor::highlightedTextColourId,Colours::white);
ed->setBounds(0, 0, getWidth(), getHeight());
ed->setFont(Font ("Futura", 11, Font::bold));
ed->setText(getText(),false);
Range<int> range(0, getText().length());
ed->setHighlightedRegion(range);
addAndMakeVisible(ed);
ed->addListener(this);
ed->runModalLoop();
setText(ed->getText());
deleteAndZero(ed);
mbLabelIsEdited = false;
}
void MySliderLabel :: mouseUp (const MouseEvent& e)
{
if (e.mouseWasClicked()
&& contains (e.getPosition())
&& ! e.mods.isPopupMenu())
{
mpSlider->showTextBox();
}
}
#include "MyLookAndFeel.h"
#include "MySlider.h"
//==============================================================================
MySlider:: MySlider(const String& componentName)
: Slider (componentName)
{
mpSliderLabel = NULL;
setLookAndFeel (MyLookAndFeel::getInstance());
setBufferedToImage(true);
}
//==============================================================================
MySlider:: ~MySlider()
{
}
//==============================================================================
void MySlider::showTextBox()
{
if (mpSliderLabel)
{
const String suffix = getTextValueSuffix();
mpSliderLabel->setText(getTextFromValue(getValue()).removeCharacters(suffix));
mpSliderLabel->edit();
setValue(getValueFromText(mpSliderLabel->getText()));
}
}
#ifndef __MY_SLIDER_HEADER__
#define __MY_SLIDER_HEADER__
#include "../JuceLibraryCode/JuceHeader.h"
#include "MySliderLabel.h"
class MySliderLabel;
class MySlider: public Slider
{
public:
MySlider(const String& componentName);
~MySlider();
void showTextBox();
void setSliderLabelPtr(MySliderLabel* ptr) {mpSliderLabel = ptr;};
private:
MySliderLabel* mpSliderLabel;
};
#endif
#ifndef _MY_LOOKANDFEEL_HEADER_
#define _MY_LOOKANDFEEL_HEADER_
#include "../JuceLibraryCode/JuceHeader.h"
// ==============================================================================
class MyLookAndFeel: public LookAndFeel
{
public:
static MyLookAndFeel* getInstance();
private:
Label* createSliderTextBox (Slider& slider);
};
#endif
#include "MyLookAndFeel.h"
#include "MySliderLabel.h"
//----------------------------------------------------------------------//
MyLookAndFeel* MyLookAndFeel::getInstance()
{
static MyLookAndFeel myLookAndFeel;
return &myLookAndFeel;
}
//
//==============================================================================
Label* MyLookAndFeel::createSliderTextBox(Slider& slider)
{
MySliderLabel* l = new MySliderLabel(&slider);
l->setJustificationType (Justification::centred);
l->setColour (Label::textColourId, slider.findColour (Slider::textBoxTextColourId));
l->setColour (Label::backgroundColourId,
(slider.getSliderStyle() == Slider::LinearBar) ? Colours::transparentBlack
: slider.findColour (Slider::textBoxBackgroundColourId));
l->setColour (Label::outlineColourId, slider.findColour (Slider::textBoxOutlineColourId));
l->setColour (TextEditor::textColourId, slider.findColour (Slider::textBoxTextColourId));
l->setColour (TextEditor::backgroundColourId,
slider.findColour (Slider::textBoxBackgroundColourId)
.withAlpha (slider.getSliderStyle() == Slider::LinearBar ? 0.7f : 1.0f));
l->setColour (TextEditor::outlineColourId, slider.findColour (Slider::textBoxOutlineColourId));
return l;
}zamrate wrote:It's rather unbelievable that this question comes up ever again, when I've posted a solution, which worked, but for mysterious reasons never made its way into JUCE. Link: viewtopic.php?f=8&t=1662&hilit=keystrokes&start=60 Check out the bottom of page 4 (last code I posted).
I can't find ShowTextBox in Label class.Did you write it on your own?
Though I can't get the control modifier working in your solution, so I can't use it for now.
void convertVstKeyInputToKeyCodeAndTextCharacter(int opCode, int value, int index, int &keyCode, int &textCharacter, int &modifierKey)
{
keyCode=0;
textCharacter=0;
modifierKey = 0;
if (opCode==effEditKeyDown)
{
if (value == VKEY_CONTROL || value == VKEY_SHIFT || value == VKEY_ALT)
{
modifierKey = value;
return;
}
for (int i=0; i<sizeof(vstVirtualKeyCodeConversionTable)/(2*sizeof(int));i++)
{
if (value==vstVirtualKeyCodeConversionTable[i*2])
{
keyCode=vstVirtualKeyCodeConversionTable[i*2+1];
break;
}
}
textCharacter=index; // ascii
}
}
if (opCode == effEditKeyDown || opCode == effEditKeyUp)
{
#if JUCE_WIN32
if (editorComp!=0)
{
int keyCode, textCharacter;
int modifierKey;
convertVstKeyInputToKeyCodeAndTextCharacter(opCode, value, index, keyCode, textCharacter, modifierKey);
ComponentPeer *peer=editorComp->getPeer();
if (peer!=0)
{
if (keyCode!=0 || textCharacter!=0)
{
return peer->handleKeyPress (keyCode, textCharacter);
}
if (modifierKey)
{
int keyMods = 0;
if (modifierKey == VKEY_CONTROL) keyMods |= ModifierKeys::ctrlModifier;
if (modifierKey == VKEY_SHIFT) keyMods |= ModifierKeys::shiftModifier;
if (modifierKey == VKEY_ALT) keyMods |= ModifierKeys::altModifier;
ModifierKeys::getCurrentModifiers().withFlags (keyMods);
}
}
return 0;
}
#endif
class PopupTextEditor;
class PopupTextEditorListener
{
public:
//==============================================================================
juce_UseDebuggingNewOperator
virtual ~PopupTextEditorListener () {};
virtual void textEditAccepted (PopupTextEditor* editor, const juce::String& text) = 0;
virtual void textEditRejected (PopupTextEditor* editor) = 0;
};
class PopupTextEditor
: public TextEditorListener
, public ComponentListener
{
public:
//==============================================================================
juce_UseDebuggingNewOperator
class TextEditorModal : public TextEditor
{
public:
TextEditorModal (const juce::String name) : TextEditor (name) {};
virtual void inputAttemptWhenModal ()
{
returnPressed();
exitModalState (0);
}
};
PopupTextEditor (const juce::String& name, PopupTextEditorListener* listener);
virtual ~PopupTextEditor ();
const juce::String& getName () const;
void setColour (const int colourId, const Colour& colour);
void setFont (const Font& font);
void showOverWithText (Component* anchor, juce::String& text);
virtual void textEditorTextChanged (TextEditor& editor);
virtual void textEditorReturnKeyPressed (TextEditor& editor);
virtual void textEditorEscapeKeyPressed (TextEditor& editor);
virtual void textEditorFocusLost (TextEditor& editor);
protected:
juce::String name;
juce::String text;
PopupTextEditorListener* listener;
TextEditorModal* texteditor;
};
PopupTextEditor::PopupTextEditor (const String& name_, PopupTextEditorListener* listener_)
: name (name_)
, listener (listener_)
{
jassert (listener);
texteditor = new TextEditorModal (name_);
texteditor->addListener (this);
jassert (texteditor);
}
PopupTextEditor::~PopupTextEditor ()
{
if (texteditor)
{
delete texteditor;
}
}
const String& PopupTextEditor::getName () const
{
return name;
}
void PopupTextEditor::setColour (const int colourId, const Colour& colour)
{
texteditor->setColour (colourId, colour);
}
void PopupTextEditor::setFont (const Font& font)
{
texteditor->setFont (font);
}
void PopupTextEditor::showOverWithText (Component* anchor, String& text)
{
ModalComponentManager::Callback* userCallback = 0;
ScopedPointer<ModalComponentManager::Callback> userCallbackDeleter (userCallback);
Component::SafePointer<Component> prevFocused (Component::getCurrentlyFocusedComponent());
Component::SafePointer<Component> prevTopLevel ((prevFocused != 0) ? prevFocused->getTopLevelComponent() : 0);
texteditor->setWantsKeyboardFocus (true);
Rectangle<int> sr (anchor->getBounds ());
sr.setPosition (anchor->getScreenX(), anchor->getScreenY());
int fontheight = texteditor->getFont().getHeight() + 4;
if (sr.getHeight() > fontheight)
{
sr.translate (0, (sr.getHeight() - fontheight)/2);
sr.setHeight (fontheight);
}
texteditor->setAlwaysOnTop (true);
texteditor->setBounds (sr);
texteditor->setText (text);
texteditor->setHighlightedRegion (Range <int> (0, text.length ()));
texteditor->setVisible (true);
texteditor->grabKeyboardFocus();
texteditor->addToDesktop (ComponentPeer::windowIsTemporary, 0);
texteditor->addListener (this);
texteditor->enterModalState (false);
texteditor->grabKeyboardFocus ();
const int result = texteditor->runModalLoop();
{
if (prevTopLevel != 0)
prevTopLevel->toFront (true);
if (prevFocused != 0)
prevFocused->grabKeyboardFocus();
}
}
void PopupTextEditor::textEditorTextChanged (TextEditor& editor)
{
// do nothing until the return or escape key is pressed
}
void PopupTextEditor::textEditorReturnKeyPressed (TextEditor& editor)
{
jassert (listener);
String text = editor.getText ();
listener->textEditAccepted (this, text);
texteditor->exitModalState(1);
}
void PopupTextEditor::textEditorEscapeKeyPressed (TextEditor& editor)
{
jassert (listener);
listener->textEditRejected (this);
texteditor->exitModalState(0);
}
void PopupTextEditor::textEditorFocusLost (TextEditor& editor)
{
texteditor->exitModalState(0);
}
Users browsing this forum: No registered users and 3 guests