303 lines
9.9 KiB
C++
303 lines
9.9 KiB
C++
// This file is part of VSTGUI. It is subject to the license terms
|
|
// in the LICENSE file found in the top-level directory of this
|
|
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
|
|
|
|
#include "cfontchooser.h"
|
|
#include "../cdatabrowser.h"
|
|
#include "../cdrawcontext.h"
|
|
#include "cbuttons.h"
|
|
#include "ctextedit.h"
|
|
#include "cscrollbar.h"
|
|
#include "../cstring.h"
|
|
#include "../platform/platformfactory.h"
|
|
#include "../platform/iplatformfont.h"
|
|
#include <list>
|
|
#include <cmath>
|
|
|
|
namespace VSTGUI {
|
|
|
|
/// @cond ignore
|
|
|
|
namespace CFontChooserInternal {
|
|
|
|
class FontPreviewView : public CView
|
|
{
|
|
public:
|
|
FontPreviewView (const CRect& size, const CColor& color = kWhiteCColor) : CView (size), font (nullptr), fontColor (color) {}
|
|
~FontPreviewView () noexcept override { if (font) font->forget (); }
|
|
|
|
void setFont (CFontRef newFont)
|
|
{
|
|
if (font)
|
|
font->forget ();
|
|
font = newFont;
|
|
if (font)
|
|
font->remember ();
|
|
invalid ();
|
|
}
|
|
|
|
void draw (CDrawContext *context) override
|
|
{
|
|
context->setFontColor (fontColor);
|
|
context->setFont (font);
|
|
std::string text;
|
|
char string[2];
|
|
CRect glyphRect (getViewSize ().left, getViewSize ().top, getViewSize ().left, getViewSize ().top);
|
|
CCoord height = ceil (font->getPlatformFont ()->getAscent () + font->getPlatformFont ()->getDescent () + font->getPlatformFont ()->getLeading () + 2.);
|
|
glyphRect.setHeight (height);
|
|
for (int8_t i = 33; i < 126;)
|
|
{
|
|
while (glyphRect.right < getViewSize ().right && i < 126)
|
|
{
|
|
snprintf (string, 2, "%c", i++);
|
|
text += string;
|
|
glyphRect.setWidth (context->getStringWidth (text.c_str ()));
|
|
}
|
|
context->drawString (text.c_str (), glyphRect, kLeftText);
|
|
glyphRect.left = glyphRect.right = getViewSize ().left;
|
|
glyphRect.offset (0, height);
|
|
text = "";
|
|
}
|
|
setDirty (false);
|
|
}
|
|
|
|
protected:
|
|
CFontRef font;
|
|
CColor fontColor;
|
|
};
|
|
|
|
enum {
|
|
kFontChooserSizeTag,
|
|
kFontChooserBoldTag,
|
|
kFontChooserItalicTag,
|
|
kFontChooserUnderlineTag,
|
|
kFontChooserStrikeoutTag
|
|
};
|
|
|
|
} // CFontChooserInternal
|
|
|
|
/// @endcond
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
CFontChooser::CFontChooser (IFontChooserDelegate* delegate, CFontRef initialFont, const CFontChooserUIDefinition& uiDef)
|
|
: CViewContainer (CRect (0, 0, 300, 500))
|
|
, delegate (nullptr)
|
|
, fontBrowser (nullptr)
|
|
, selFont (nullptr)
|
|
{
|
|
std::list<std::string> fnList;
|
|
getPlatformFactory ().getAllFontFamilies ([&fnList] (const std::string& name) {
|
|
fnList.push_back (name);
|
|
return true;
|
|
});
|
|
fnList.sort ();
|
|
std::list<std::string>::const_iterator it = fnList.begin ();
|
|
while (it != fnList.end ())
|
|
{
|
|
fontNames.emplace_back (*it);
|
|
++it;
|
|
}
|
|
auto* dbSource = new GenericStringListDataBrowserSource (&fontNames, this);
|
|
dbSource->setupUI (uiDef.selectionColor, uiDef.fontColor, uiDef.rowlineColor, uiDef.rowBackColor, uiDef.rowAlternateBackColor, uiDef.font, uiDef.rowHeight);
|
|
int32_t dbStyle = CDataBrowser::kDrawRowLines | CScrollView::kVerticalScrollbar | CScrollView::kDontDrawFrame | CScrollView::kOverlayScrollbars;
|
|
fontBrowser = new CDataBrowser (CRect (0, 0, 200, 500), dbSource, dbStyle, uiDef.scrollbarWidth);
|
|
dbSource->forget ();
|
|
fontBrowser->setAutosizeFlags (kAutosizeLeft | kAutosizeTop | kAutosizeBottom);
|
|
fontBrowser->setTransparency (true);
|
|
CScrollbar* scrollbar = fontBrowser->getVerticalScrollbar ();
|
|
if (scrollbar)
|
|
{
|
|
scrollbar->setBackgroundColor (uiDef.scrollbarBackgroundColor);
|
|
scrollbar->setFrameColor (uiDef.scrollbarFrameColor);
|
|
scrollbar->setScrollerColor (uiDef.scrollbarScrollerColor);
|
|
}
|
|
addView (fontBrowser);
|
|
CRect controlRect (210, 0, 300, 20);
|
|
auto* label = new CTextLabel (controlRect, "Size:");
|
|
label->setFont (uiDef.font);
|
|
label->setFontColor (uiDef.fontColor);
|
|
label->sizeToFit ();
|
|
label->setHoriAlign (kLeftText);
|
|
label->setTransparency (true);
|
|
label->setAutosizeFlags (kAutosizeLeft | kAutosizeTop);
|
|
addView (label);
|
|
CRect teRect = label->getViewSize ();
|
|
teRect.left = teRect.right + 5.;
|
|
teRect.right = controlRect.right;
|
|
sizeEdit = new CTextEdit (teRect, this, CFontChooserInternal::kFontChooserSizeTag);
|
|
sizeEdit->setFont (uiDef.font);
|
|
sizeEdit->setFontColor (uiDef.fontColor);
|
|
sizeEdit->setHoriAlign (kLeftText);
|
|
sizeEdit->setTransparency (true);
|
|
sizeEdit->setAutosizeFlags (kAutosizeLeft | kAutosizeTop);
|
|
sizeEdit->setMax (2000);
|
|
sizeEdit->setMin (6);
|
|
sizeEdit->setValue (2000);
|
|
sizeEdit->sizeToFit ();
|
|
sizeEdit->setStringToValueFunction ([] (UTF8StringPtr txt, float& result, CTextEdit* textEdit) { result = UTF8StringView (txt).toFloat (); return true; });
|
|
addView (sizeEdit);
|
|
controlRect.offset (0, 20);
|
|
boldBox = new CCheckBox (controlRect, this, CFontChooserInternal::kFontChooserBoldTag, "Bold");
|
|
boldBox->setFont (uiDef.font);
|
|
boldBox->setFontColor (uiDef.fontColor);
|
|
boldBox->setAutosizeFlags (kAutosizeLeft | kAutosizeTop);
|
|
boldBox->sizeToFit ();
|
|
addView (boldBox);
|
|
controlRect.offset (0, 20);
|
|
italicBox = new CCheckBox (controlRect, this, CFontChooserInternal::kFontChooserItalicTag, "Italic");
|
|
italicBox->setFont (uiDef.font);
|
|
italicBox->setFontColor (uiDef.fontColor);
|
|
italicBox->setAutosizeFlags (kAutosizeLeft | kAutosizeTop);
|
|
italicBox->sizeToFit ();
|
|
addView (italicBox);
|
|
controlRect.offset (0, 20);
|
|
underlineBox = new CCheckBox (controlRect, this, CFontChooserInternal::kFontChooserUnderlineTag, "Underline");
|
|
underlineBox->setFont (uiDef.font);
|
|
underlineBox->setFontColor (uiDef.fontColor);
|
|
underlineBox->setAutosizeFlags (kAutosizeLeft | kAutosizeTop);
|
|
underlineBox->sizeToFit ();
|
|
addView (underlineBox);
|
|
controlRect.offset (0, 20);
|
|
strikeoutBox = new CCheckBox (controlRect, this, CFontChooserInternal::kFontChooserStrikeoutTag, "Strikeout");
|
|
strikeoutBox->setFont (uiDef.font);
|
|
strikeoutBox->setFontColor (uiDef.fontColor);
|
|
strikeoutBox->setAutosizeFlags (kAutosizeLeft | kAutosizeTop);
|
|
strikeoutBox->sizeToFit ();
|
|
addView (strikeoutBox);
|
|
|
|
CViewContainer* container = new CViewContainer (CRect (controlRect.left, controlRect.bottom+10, 300, 500));
|
|
container->setBackgroundColor (uiDef.previewBackgroundColor);
|
|
container->setAutosizeFlags (kAutosizeTop | kAutosizeBottom | kAutosizeLeft | kAutosizeRight);
|
|
fontPreviewView = new CFontChooserInternal::FontPreviewView (CRect (10, 10, container->getWidth () - 10, container->getHeight () - 10), uiDef.previewTextColor);
|
|
fontPreviewView->setAutosizeFlags (kAutosizeAll);
|
|
container->addView (fontPreviewView);
|
|
addView (container);
|
|
|
|
setFont (initialFont ? initialFont : kSystemFont);
|
|
|
|
sizeToFit ();
|
|
|
|
this->delegate = delegate;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CFontChooser::~CFontChooser () noexcept
|
|
{
|
|
if (selFont)
|
|
selFont->forget ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CFontChooser::setFont (CFontRef font)
|
|
{
|
|
if (font)
|
|
{
|
|
if (selFont)
|
|
selFont->forget ();
|
|
selFont = new CFontDesc (*font);
|
|
sizeEdit->setValue ((float)font->getSize ());
|
|
boldBox->setValue ((font->getStyle () & kBoldFace) ? 1.f : 0.f);
|
|
italicBox->setValue ((font->getStyle () & kItalicFace) ? 1.f : 0.f);
|
|
underlineBox->setValue ((font->getStyle () & kUnderlineFace) ? 1.f : 0.f);
|
|
strikeoutBox->setValue ((font->getStyle () & kStrikethroughFace) ? 1.f : 0.f);
|
|
|
|
auto it = fontNames.begin ();
|
|
int32_t row = 0;
|
|
while (it != fontNames.end ())
|
|
{
|
|
if (*it == font->getName ())
|
|
{
|
|
fontBrowser->setSelectedRow (row, true);
|
|
break;
|
|
}
|
|
++it;
|
|
row++;
|
|
}
|
|
static_cast<CFontChooserInternal::FontPreviewView*> (fontPreviewView)->setFont (selFont);
|
|
}
|
|
invalid ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CFontChooser::valueChanged (CControl* pControl)
|
|
{
|
|
if (selFont == nullptr)
|
|
return;
|
|
|
|
switch (pControl->getTag ())
|
|
{
|
|
case CFontChooserInternal::kFontChooserSizeTag:
|
|
{
|
|
pControl->setValue (pControl->getValue ());
|
|
selFont->setSize (pControl->getValue ());
|
|
break;
|
|
}
|
|
case CFontChooserInternal::kFontChooserBoldTag:
|
|
{
|
|
if (pControl->getValue () == 1)
|
|
selFont->setStyle (selFont->getStyle () | kBoldFace);
|
|
else
|
|
selFont->setStyle (selFont->getStyle () & ~kBoldFace);
|
|
break;
|
|
}
|
|
case CFontChooserInternal::kFontChooserItalicTag:
|
|
{
|
|
if (pControl->getValue () == 1)
|
|
selFont->setStyle (selFont->getStyle () | kItalicFace);
|
|
else
|
|
selFont->setStyle (selFont->getStyle () & ~kItalicFace);
|
|
break;
|
|
}
|
|
case CFontChooserInternal::kFontChooserUnderlineTag:
|
|
{
|
|
if (pControl->getValue () == 1)
|
|
selFont->setStyle (selFont->getStyle () | kUnderlineFace);
|
|
else
|
|
selFont->setStyle (selFont->getStyle () & ~kUnderlineFace);
|
|
break;
|
|
}
|
|
case CFontChooserInternal::kFontChooserStrikeoutTag:
|
|
{
|
|
if (pControl->getValue () == 1)
|
|
selFont->setStyle (selFont->getStyle () | kStrikethroughFace);
|
|
else
|
|
selFont->setStyle (selFont->getStyle () & ~kStrikethroughFace);
|
|
break;
|
|
}
|
|
}
|
|
if (delegate)
|
|
delegate->fontChanged (this, selFont);
|
|
static_cast<CFontChooserInternal::FontPreviewView*> (fontPreviewView)->setFont (selFont);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CFontChooser::dbSelectionChanged (int32_t selectedRow, GenericStringListDataBrowserSource* source)
|
|
{
|
|
if (selectedRow >= 0 && static_cast<size_t> (selectedRow) <= fontNames.size ())
|
|
selFont->setName (fontNames[static_cast<size_t> (selectedRow)].data ());
|
|
static_cast<CFontChooserInternal::FontPreviewView*> (fontPreviewView)->setFont (selFont);
|
|
if (delegate)
|
|
delegate->fontChanged (this, selFont);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool CFontChooser::attached (CView* parent)
|
|
{
|
|
if (CViewContainer::attached (parent))
|
|
{
|
|
fontBrowser->makeRowVisible (fontBrowser->getSelectedRow ());
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CFontChooser::onKeyboardEvent (KeyboardEvent& event)
|
|
{
|
|
fontBrowser->onKeyboardEvent (event);
|
|
}
|
|
|
|
} // VSTGUI
|