Files
2026-08-16 18:24:52 +07:00

365 lines
11 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 "uifontscontroller.h"
#if VSTGUI_LIVE_EDITING
#include "uieditcontroller.h"
#include "uibasedatasource.h"
#include "../../lib/controls/ccolorchooser.h"
#include "../../lib/controls/coptionmenu.h"
#include "../../lib/controls/csearchtextedit.h"
#include "../../lib/platform/platformfactory.h"
#include <sstream>
namespace VSTGUI {
//----------------------------------------------------------------------------------------------------
class UIFontsDataSource : public UIBaseDataSource
{
public:
UIFontsDataSource (UIDescription* description, IActionPerformer* actionPerformer, GenericStringListDataBrowserSourceSelectionChanged* delegate);
protected:
void onUIDescFontChanged (UIDescription* desc) override;
void getNames (std::list<const std::string*>& names) override;
bool addItem (UTF8StringPtr name) override;
bool removeItem (UTF8StringPtr name) override;
bool performNameChange (UTF8StringPtr oldName, UTF8StringPtr newName) override;
UTF8StringPtr getDefaultsName () override { return "UIFontsDataSource"; }
SharedPointer<CColorChooser> colorChooser;
};
//----------------------------------------------------------------------------------------------------
UIFontsDataSource::UIFontsDataSource (UIDescription* description, IActionPerformer* actionPerformer, GenericStringListDataBrowserSourceSelectionChanged* delegate)
: UIBaseDataSource (description, actionPerformer, delegate)
{
}
//----------------------------------------------------------------------------------------------------
void UIFontsDataSource::onUIDescFontChanged (UIDescription* desc)
{
onUIDescriptionUpdate ();
}
//----------------------------------------------------------------------------------------------------
void UIFontsDataSource::getNames (std::list<const std::string*>& names)
{
description->collectFontNames (names);
}
//----------------------------------------------------------------------------------------------------
bool UIFontsDataSource::addItem (UTF8StringPtr name)
{
actionPerformer->performFontChange (name, kNormalFont);
return true;
}
//----------------------------------------------------------------------------------------------------
bool UIFontsDataSource::removeItem (UTF8StringPtr name)
{
actionPerformer->performFontChange (name, kNormalFont, true);
return true;
}
//----------------------------------------------------------------------------------------------------
bool UIFontsDataSource::performNameChange (UTF8StringPtr oldName, UTF8StringPtr newName)
{
actionPerformer->performFontNameChange (oldName, newName);
return true;
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
UIFontsController::UIFontsController (IController* baseController, UIDescription* description, IActionPerformer* actionPerformer)
: DelegationController (baseController)
, editDescription (description)
, actionPerformer (actionPerformer)
, dataSource (nullptr)
, fontMenu (nullptr)
, altTextEdit (nullptr)
, sizeTextEdit (nullptr)
, boldControl (nullptr)
, italicControl (nullptr)
, strikethroughControl (nullptr)
, underlineControl (nullptr)
{
dataSource = new UIFontsDataSource (editDescription, actionPerformer, this);
UIEditController::setupDataSource (dataSource);
}
//----------------------------------------------------------------------------------------------------
UIFontsController::~UIFontsController ()
{
dataSource->forget ();
}
//----------------------------------------------------------------------------------------------------
CView* UIFontsController::createView (const UIAttributes& attributes, const IUIDescription* description)
{
const std::string* name = attributes.getAttributeValue (IUIDescription::kCustomViewName);
if (name)
{
if (*name == "FontsBrowser")
{
CDataBrowser* dataBrowser = new CDataBrowser (CRect (0, 0, 0, 0), dataSource, CDataBrowser::kDrawRowLines|CScrollView::kHorizontalScrollbar | CScrollView::kVerticalScrollbar);
return dataBrowser;
}
}
return DelegationController::createView (attributes, description);
}
//----------------------------------------------------------------------------------------------------
CView* UIFontsController::verifyView (CView* view, const UIAttributes& attributes, const IUIDescription* description)
{
auto searchField = dynamic_cast<CSearchTextEdit*>(view);
if (searchField && searchField->getTag () == kSearchTag)
{
dataSource->setSearchFieldControl (searchField);
return searchField;
}
auto* control = dynamic_cast<CControl*>(view);
if (control)
{
switch (control->getTag ())
{
case kFontMainTag:
{
fontMenu = dynamic_cast<COptionMenu*> (control);
getPlatformFactory ().getAllFontFamilies ([&] (const std::string& name) {
fontMenu->addEntry (name.data ());
return true;
});
fontMenu->setStyle (fontMenu->getStyle () | COptionMenu::kNoTextStyle);
fontMenu->setMouseEnabled (false);
break;
}
case kFontAltTag:
{
altTextEdit = dynamic_cast<CTextEdit*>(control);
control->setMouseEnabled (false);
break;
}
case kFontSizeTag:
{
sizeTextEdit = dynamic_cast<CTextEdit*>(control);
if (sizeTextEdit)
{
sizeTextEdit->setValueToStringFunction (valueToString);
sizeTextEdit->setStringToValueFunction (stringToValue);
}
control->setMouseEnabled (false);
break;
}
case kFontStyleBoldTag:
{
boldControl = control;
control->setMouseEnabled (false);
break;
}
case kFontStyleItalicTag:
{
italicControl = control;
control->setMouseEnabled (false);
break;
}
case kFontStyleStrikethroughTag:
{
strikethroughControl = control;
control->setMouseEnabled (false);
break;
}
case kFontStyleUnderlineTag:
{
underlineControl = control;
control->setMouseEnabled (false);
break;
}
}
}
return controller->verifyView (view, attributes, description);
}
//----------------------------------------------------------------------------------------------------
IControlListener* UIFontsController::getControlListener (UTF8StringPtr name)
{
return this;
}
//----------------------------------------------------------------------------------------------------
void UIFontsController::valueChanged (CControl* pControl)
{
switch (pControl->getTag ())
{
case kAddTag:
{
if (pControl->getValue () == pControl->getMax ())
{
dataSource->add ();
}
break;
}
case kRemoveTag:
{
if (pControl->getValue () == pControl->getMax ())
{
dataSource->remove ();
}
break;
}
case kFontMainTag:
case kFontSizeTag:
case kFontStyleBoldTag:
case kFontStyleItalicTag:
case kFontStyleStrikethroughTag:
case kFontStyleUnderlineTag:
{
if (fontMenu == nullptr || sizeTextEdit == nullptr || selectedFont.empty ())
break;
CMenuItem* menuItem = fontMenu->getCurrent ();
if (menuItem)
{
int32_t style = 0;
if (boldControl && boldControl->getValue () > 0)
style |= kBoldFace;
if (italicControl && italicControl->getValue () > 0)
style |= kItalicFace;
if (underlineControl && underlineControl->getValue () > 0)
style |= kUnderlineFace;
if (strikethroughControl && strikethroughControl->getValue () > 0)
style |= kStrikethroughFace;
auto font = makeOwned<CFontDesc> (menuItem->getTitle (), sizeTextEdit->getValue (), style);
actionPerformer->performFontChange (selectedFont.data (), font);
}
break;
}
case kFontAltTag:
{
actionPerformer->performAlternativeFontChange (selectedFont.data (), altTextEdit->getText ());
break;
}
}
}
//----------------------------------------------------------------------------------------------------
void UIFontsController::dbSelectionChanged (int32_t selectedRow, GenericStringListDataBrowserSource* source)
{
selectedFont = selectedRow != CDataBrowser::kNoSelection ? dataSource->getStringList ()->at (static_cast<uint32_t> (selectedRow)).data () : "";
CFontRef font = editDescription->getFont (selectedFont.data ());
if (font)
{
if (fontMenu && !font->getName ().empty ())
{
const auto& fontName = font->getName ();
CMenuItemList* items = fontMenu->getItems ();
int32_t index = 0;
for (auto& item : *items)
{
if (fontName == item->getTitle ())
{
fontMenu->setValue ((float)index);
break;
}
index++;
}
fontMenu->setStyle (fontMenu->getStyle () & ~COptionMenu::kNoTextStyle);
fontMenu->setMouseEnabled (true);
}
if (sizeTextEdit)
{
sizeTextEdit->setMouseEnabled (true);
std::stringstream str;
str << font->getSize ();
sizeTextEdit->setText (str.str ().data ());
}
if (boldControl)
{
boldControl->setValue (font->getStyle () & kBoldFace ? true : false);
boldControl->invalid ();
boldControl->setMouseEnabled (true);
}
if (italicControl)
{
italicControl->setValue (font->getStyle () & kItalicFace ? true : false);
italicControl->invalid ();
italicControl->setMouseEnabled (true);
}
if (underlineControl)
{
underlineControl->setValue (font->getStyle () & kUnderlineFace ? true : false);
underlineControl->invalid ();
underlineControl->setMouseEnabled (true);
}
if (strikethroughControl)
{
strikethroughControl->setValue (font->getStyle () & kStrikethroughFace ? true : false);
strikethroughControl->invalid ();
strikethroughControl->setMouseEnabled (true);
}
if (altTextEdit)
{
std::string alternativeFonts;
editDescription->getAlternativeFontNames (selectedFont.data (), alternativeFonts);
altTextEdit->setText (alternativeFonts.data ());
altTextEdit->setMouseEnabled (true);
}
}
else
{
if (fontMenu)
{
fontMenu->setStyle (fontMenu->getStyle () | COptionMenu::kNoTextStyle);
fontMenu->setMouseEnabled (false);
}
if (boldControl)
boldControl->setMouseEnabled (false);
if (italicControl)
italicControl->setMouseEnabled (false);
if (underlineControl)
underlineControl->setMouseEnabled (false);
if (strikethroughControl)
strikethroughControl->setMouseEnabled (false);
if (altTextEdit)
{
altTextEdit->setMouseEnabled (false);
altTextEdit->setText (nullptr);
}
if (sizeTextEdit)
{
sizeTextEdit->setMouseEnabled (false);
sizeTextEdit->setText (nullptr);
}
}
}
//----------------------------------------------------------------------------------------------------
bool UIFontsController::valueToString (float value, char utf8String[256], CParamDisplay::ValueToStringUserData* userData)
{
auto* edit = static_cast<CTextEdit*> (userData);
if (edit && edit->getMouseEnabled () == false)
return true;
int32_t intValue = (int32_t)value;
std::stringstream str;
str << intValue;
std::strcpy (utf8String, str.str ().data ());
return true;
}
//----------------------------------------------------------------------------------------------------
bool UIFontsController::stringToValue (UTF8StringPtr txt, float& result, CTextEdit::StringToValueUserData* userData)
{
int32_t value = txt ? (int32_t)strtol (txt, nullptr, 10) : 0;
result = (float)value;
return true;
}
} // VSTGUI
#endif // VSTGUI_LIVE_EDITING