mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-02-04 03:40:07 +00:00
Added typeface and kerning support to the Projucer GUI editor
This commit is contained in:
parent
08707ec85c
commit
b28555838d
3 changed files with 275 additions and 40 deletions
|
|
@ -54,9 +54,14 @@ public:
|
|||
|
||||
e->setAttribute ("fontname", l->getProperties().getWithDefault ("typefaceName", FontPropertyComponent::getDefaultFont()).toString());
|
||||
e->setAttribute ("fontsize", roundToInt (l->getFont().getHeight() * 100.0) / 100.0);
|
||||
e->setAttribute ("kerning", roundToInt (l->getFont().getExtraKerningFactor() * 1000.0) / 1000.0);
|
||||
e->setAttribute ("bold", l->getFont().isBold());
|
||||
e->setAttribute ("italic", l->getFont().isItalic());
|
||||
e->setAttribute ("justification", l->getJustificationType().getFlags());
|
||||
if (l->getFont().getTypefaceStyle() != "Regular")
|
||||
{
|
||||
e->setAttribute ("typefaceStyle", l->getFont().getTypefaceStyle());
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
|
@ -74,6 +79,11 @@ public:
|
|||
font.setHeight ((float) xml.getDoubleAttribute ("fontsize", 15.0));
|
||||
font.setBold (xml.getBoolAttribute ("bold", false));
|
||||
font.setItalic (xml.getBoolAttribute ("italic", false));
|
||||
font.setExtraKerningFactor ((float) xml.getDoubleAttribute ("kerning", 0.0));
|
||||
auto fontStyle = xml.getStringAttribute ("typefaceStyle");
|
||||
if (! fontStyle.isEmpty())
|
||||
font.setTypefaceStyle (fontStyle);
|
||||
|
||||
l->setFont (font);
|
||||
|
||||
l->getProperties().set ("typefaceName", xml.getStringAttribute ("fontname", FontPropertyComponent::getDefaultFont()));
|
||||
|
|
@ -162,12 +172,12 @@ public:
|
|||
ComponentTypeHandler::getEditableProperties (component, document, props);
|
||||
|
||||
Label* const l = dynamic_cast<Label*> (component);
|
||||
props.add (new LabelTextProperty (l, document));
|
||||
|
||||
props.add (new LabelTextProperty (l, document));
|
||||
props.add (new LabelJustificationProperty (l, document));
|
||||
props.add (new FontNameProperty (l, document));
|
||||
props.add (new FontSizeProperty (l, document));
|
||||
props.add (new FontStyleProperty (l, document));
|
||||
props.add (new FontNameProperty (l, document));
|
||||
props.add (new FontStyleProperty (l, document));
|
||||
props.add (new FontSizeProperty (l, document));
|
||||
props.add (new FontKerningProperty (l, document));
|
||||
|
||||
addColourProperties (component, document, props);
|
||||
|
||||
|
|
@ -567,10 +577,7 @@ private:
|
|||
{
|
||||
document.addChangeListener (this);
|
||||
|
||||
choices.add ("normal");
|
||||
choices.add ("bold");
|
||||
choices.add ("italic");
|
||||
choices.add ("bold + italic");
|
||||
updateStylesList (label->getFont());
|
||||
}
|
||||
|
||||
~FontStyleProperty()
|
||||
|
|
@ -578,12 +585,44 @@ private:
|
|||
document.removeChangeListener (this);
|
||||
}
|
||||
|
||||
void updateStylesList (const Font& newFont)
|
||||
{
|
||||
if (getNumChildComponents() > 0)
|
||||
{
|
||||
if (auto cb = dynamic_cast<ComboBox*> (getChildComponent (0)))
|
||||
cb->clear();
|
||||
|
||||
getChildComponent (0)->setVisible (false);
|
||||
removeAllChildren();
|
||||
}
|
||||
|
||||
choices.clear();
|
||||
|
||||
choices.add ("Regular");
|
||||
choices.add ("Bold");
|
||||
choices.add ("Italic");
|
||||
choices.add ("Bold Italic");
|
||||
|
||||
choices.mergeArray (newFont.getAvailableStyles());
|
||||
refresh();
|
||||
}
|
||||
|
||||
void setIndex (int newIndex)
|
||||
{
|
||||
Font f (label->getFont());
|
||||
|
||||
f.setBold (newIndex == 1 || newIndex == 3);
|
||||
f.setItalic (newIndex == 2 || newIndex == 3);
|
||||
if (f.getAvailableStyles().contains (choices[newIndex]))
|
||||
{
|
||||
f.setBold (false);
|
||||
f.setItalic (false);
|
||||
f.setTypefaceStyle (choices[newIndex]);
|
||||
}
|
||||
else
|
||||
{
|
||||
f.setTypefaceStyle ("Regular");
|
||||
f.setBold (newIndex == 1 || newIndex == 3);
|
||||
f.setItalic (newIndex == 2 || newIndex == 3);
|
||||
}
|
||||
|
||||
document.perform (new FontStyleChangeAction (label, *document.getComponentLayout(), f),
|
||||
"Change Label font style");
|
||||
|
|
@ -591,17 +630,28 @@ private:
|
|||
|
||||
int getIndex() const
|
||||
{
|
||||
if (label->getFont().isBold() && label->getFont().isItalic())
|
||||
return 3;
|
||||
else if (label->getFont().isBold())
|
||||
return 1;
|
||||
else if (label->getFont().isItalic())
|
||||
return 2;
|
||||
auto f = label->getFont();
|
||||
|
||||
return 0;
|
||||
const auto typefaceIndex = choices.indexOf (f.getTypefaceStyle());
|
||||
if (typefaceIndex == -1)
|
||||
{
|
||||
if (f.isBold() && f.isItalic())
|
||||
return 3;
|
||||
else if (f.isBold())
|
||||
return 1;
|
||||
else if (f.isItalic())
|
||||
return 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return typefaceIndex;
|
||||
}
|
||||
|
||||
void changeListenerCallback (ChangeBroadcaster*) { refresh(); }
|
||||
void changeListenerCallback (ChangeBroadcaster*)
|
||||
{
|
||||
updateStylesList (label->getFont());
|
||||
}
|
||||
|
||||
private:
|
||||
Label* const label;
|
||||
|
|
@ -636,4 +686,78 @@ private:
|
|||
Font newState, oldState;
|
||||
};
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class FontKerningProperty : public SliderPropertyComponent,
|
||||
public ChangeListener
|
||||
{
|
||||
public:
|
||||
FontKerningProperty (Label* const label_, JucerDocument& doc)
|
||||
: SliderPropertyComponent ("kerning", -0.5, 0.5, 0.001),
|
||||
label (label_),
|
||||
document (doc)
|
||||
{
|
||||
document.addChangeListener (this);
|
||||
}
|
||||
|
||||
~FontKerningProperty()
|
||||
{
|
||||
document.removeChangeListener (this);
|
||||
}
|
||||
|
||||
void setValue (double newValue)
|
||||
{
|
||||
document.getUndoManager().undoCurrentTransactionOnly();
|
||||
|
||||
document.perform (new FontKerningChangeAction (label, *document.getComponentLayout(), (float) newValue),
|
||||
"Change Label font kerning");
|
||||
}
|
||||
|
||||
double getValue() const
|
||||
{
|
||||
return label->getFont().getExtraKerningFactor();
|
||||
}
|
||||
|
||||
void changeListenerCallback (ChangeBroadcaster*)
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
|
||||
private:
|
||||
Label* const label;
|
||||
JucerDocument& document;
|
||||
|
||||
class FontKerningChangeAction : public ComponentUndoableAction <Label>
|
||||
{
|
||||
public:
|
||||
FontKerningChangeAction (Label* const comp, ComponentLayout& l, const float newState_)
|
||||
: ComponentUndoableAction <Label> (comp, l),
|
||||
newState (newState_)
|
||||
{
|
||||
oldState = comp->getFont().getExtraKerningFactor();
|
||||
}
|
||||
|
||||
bool perform()
|
||||
{
|
||||
showCorrectTab();
|
||||
Font f (getComponent()->getFont());
|
||||
f.setExtraKerningFactor ((float) newState);
|
||||
getComponent()->setFont (f);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool undo()
|
||||
{
|
||||
showCorrectTab();
|
||||
Font f (getComponent()->getFont());
|
||||
f.setExtraKerningFactor ((float) oldState);
|
||||
getComponent()->setFont (f);
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
float newState, oldState;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ public:
|
|||
props.add (new FontNameProperty (this));
|
||||
props.add (new FontStyleProperty (this));
|
||||
props.add (new FontSizeProperty (this));
|
||||
props.add (new FontKerningProperty (this));
|
||||
props.add (new TextJustificationProperty (this));
|
||||
props.add (new TextToPathProperty (this));
|
||||
}
|
||||
|
|
@ -111,9 +112,14 @@ public:
|
|||
e->setAttribute ("text", text);
|
||||
e->setAttribute ("fontname", typefaceName);
|
||||
e->setAttribute ("fontsize", roundToInt (font.getHeight() * 100.0) / 100.0);
|
||||
e->setAttribute ("kerning", roundToInt (font.getExtraKerningFactor() * 1000.0) / 1000.0);
|
||||
e->setAttribute ("bold", font.isBold());
|
||||
e->setAttribute ("italic", font.isItalic());
|
||||
e->setAttribute ("justification", justification.getFlags());
|
||||
if (font.getTypefaceStyle() != "Regular")
|
||||
{
|
||||
e->setAttribute ("typefaceStyle", font.getTypefaceStyle());
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
|
@ -130,7 +136,11 @@ public:
|
|||
font.setHeight ((float) xml.getDoubleAttribute ("fontsize", 15.0));
|
||||
font.setBold (xml.getBoolAttribute ("bold", false));
|
||||
font.setItalic (xml.getBoolAttribute ("italic", false));
|
||||
font.setExtraKerningFactor ((float) xml.getDoubleAttribute ("kerning", 0.0));
|
||||
justification = Justification (xml.getIntAttribute ("justification", Justification::centred));
|
||||
auto fontStyle = xml.getStringAttribute ("typefaceStyle");
|
||||
if (! fontStyle.isEmpty())
|
||||
font.setTypefaceStyle (fontStyle);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -430,10 +440,7 @@ private:
|
|||
{
|
||||
element->getDocument()->addChangeListener (this);
|
||||
|
||||
choices.add ("normal");
|
||||
choices.add ("bold");
|
||||
choices.add ("italic");
|
||||
choices.add ("bold + italic");
|
||||
updateStylesList (element->getTypefaceName());
|
||||
}
|
||||
|
||||
~FontStyleProperty()
|
||||
|
|
@ -441,29 +448,72 @@ private:
|
|||
element->getDocument()->removeChangeListener (this);
|
||||
}
|
||||
|
||||
void updateStylesList (const String& name)
|
||||
{
|
||||
if (getNumChildComponents() > 0)
|
||||
{
|
||||
if (auto cb = dynamic_cast<ComboBox*> (getChildComponent (0)))
|
||||
cb->clear();
|
||||
|
||||
getChildComponent (0)->setVisible (false);
|
||||
removeAllChildren();
|
||||
}
|
||||
|
||||
choices.clear();
|
||||
|
||||
choices.add ("Regular");
|
||||
choices.add ("Bold");
|
||||
choices.add ("Italic");
|
||||
choices.add ("Bold Italic");
|
||||
|
||||
choices.mergeArray (Font::findAllTypefaceStyles (name));
|
||||
refresh();
|
||||
}
|
||||
|
||||
void setIndex (int newIndex)
|
||||
{
|
||||
Font f (element->getFont());
|
||||
|
||||
f.setBold (newIndex == 1 || newIndex == 3);
|
||||
f.setItalic (newIndex == 2 || newIndex == 3);
|
||||
if (f.getAvailableStyles().contains (choices[newIndex]))
|
||||
{
|
||||
f.setBold (false);
|
||||
f.setItalic (false);
|
||||
f.setTypefaceStyle (choices[newIndex]);
|
||||
}
|
||||
else
|
||||
{
|
||||
f.setTypefaceStyle ("Regular");
|
||||
f.setBold (newIndex == 1 || newIndex == 3);
|
||||
f.setItalic (newIndex == 2 || newIndex == 3);
|
||||
}
|
||||
|
||||
element->setFont (f, true);
|
||||
}
|
||||
|
||||
int getIndex() const
|
||||
{
|
||||
if (element->getFont().isBold() && element->getFont().isItalic())
|
||||
return 3;
|
||||
else if (element->getFont().isBold())
|
||||
return 1;
|
||||
else if (element->getFont().isItalic())
|
||||
return 2;
|
||||
auto f = element->getFont();
|
||||
|
||||
return 0;
|
||||
const auto typefaceIndex = choices.indexOf (f.getTypefaceStyle());
|
||||
if (typefaceIndex == -1)
|
||||
{
|
||||
if (f.isBold() && f.isItalic())
|
||||
return 3;
|
||||
else if (f.isBold())
|
||||
return 1;
|
||||
else if (f.isItalic())
|
||||
return 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return typefaceIndex;
|
||||
}
|
||||
|
||||
void changeListenerCallback (ChangeBroadcaster*) { refresh(); }
|
||||
void changeListenerCallback (ChangeBroadcaster*)
|
||||
{
|
||||
updateStylesList (element->getTypefaceName());
|
||||
}
|
||||
|
||||
private:
|
||||
PaintElementText* const element;
|
||||
|
|
@ -507,6 +557,47 @@ private:
|
|||
PaintElementText* const element;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class FontKerningProperty : public SliderPropertyComponent,
|
||||
public ChangeListener
|
||||
{
|
||||
public:
|
||||
FontKerningProperty (PaintElementText* const e)
|
||||
: SliderPropertyComponent ("kerning", -0.5, 0.5, 0.001),
|
||||
element (e)
|
||||
{
|
||||
element->getDocument()->addChangeListener (this);
|
||||
}
|
||||
|
||||
~FontKerningProperty()
|
||||
{
|
||||
element->getDocument()->removeChangeListener (this);
|
||||
}
|
||||
|
||||
void setValue (double newValue)
|
||||
{
|
||||
element->getDocument()->getUndoManager().undoCurrentTransactionOnly();
|
||||
|
||||
Font f (element->getFont());
|
||||
f.setExtraKerningFactor ((float) newValue);
|
||||
|
||||
element->setFont (f, true);
|
||||
}
|
||||
|
||||
double getValue() const
|
||||
{
|
||||
return element->getFont().getExtraKerningFactor();
|
||||
}
|
||||
|
||||
void changeListenerCallback (ChangeBroadcaster*)
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
|
||||
private:
|
||||
PaintElementText* const element;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TextJustificationProperty : public JustificationProperty,
|
||||
public ChangeListener
|
||||
|
|
|
|||
|
|
@ -84,7 +84,12 @@ public:
|
|||
if (typefaceName == getDefaultSerif()) return Font (Font::getDefaultSerifFontName(), font.getHeight(), font.getStyleFlags());
|
||||
if (typefaceName == getDefaultMono()) return Font (Font::getDefaultMonospacedFontName(), font.getHeight(), font.getStyleFlags());
|
||||
|
||||
return Font (typefaceName, font.getHeight(), font.getStyleFlags());
|
||||
auto f = Font (typefaceName, font.getHeight(), font.getStyleFlags()).withExtraKerningFactor (font.getExtraKerningFactor());
|
||||
if (f.getAvailableStyles().contains (font.getTypefaceStyle()))
|
||||
{
|
||||
f.setTypefaceStyle (font.getTypefaceStyle());
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
static String getTypefaceNameCode (const String& typefaceName)
|
||||
|
|
@ -108,11 +113,26 @@ public:
|
|||
|
||||
static String getCompleteFontCode (const Font& font, const String& typefaceName)
|
||||
{
|
||||
return "Font ("
|
||||
+ getTypefaceNameCode (typefaceName)
|
||||
+ CodeHelpers::floatLiteral (font.getHeight(), 2)
|
||||
+ ", "
|
||||
+ getFontStyleCode (font)
|
||||
+ ")";
|
||||
String s;
|
||||
|
||||
s << "Font ("
|
||||
<< getTypefaceNameCode (typefaceName)
|
||||
<< CodeHelpers::floatLiteral (font.getHeight(), 2)
|
||||
<< ", ";
|
||||
|
||||
if (font.getAvailableStyles().contains(font.getTypefaceStyle()))
|
||||
s << "Font::plain).withTypefaceStyle ("
|
||||
<< CodeHelpers::stringLiteral (font.getTypefaceStyle())
|
||||
<< ")";
|
||||
else
|
||||
s << getFontStyleCode (font)
|
||||
<< ")";
|
||||
|
||||
if (font.getExtraKerningFactor() != 0)
|
||||
s << ".withExtraKerningFactor ("
|
||||
<< CodeHelpers::floatLiteral (font.getExtraKerningFactor(), 3)
|
||||
<< ")";
|
||||
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue