summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2018-04-13 09:43:53 +0000
committerTavmjong Bah <tavmjong@free.fr>2018-04-13 09:43:53 +0000
commit1ddfdd2c6d5f915da6a7563c2d29021d53ff07ed (patch)
tree21241bccd07beb89b054b746685f118021e4cf93 /src/ui
parentRemove unused variables. (diff)
downloadinkscape-1ddfdd2c6d5f915da6a7563c2d29021d53ff07ed.tar.gz
inkscape-1ddfdd2c6d5f915da6a7563c2d29021d53ff07ed.zip
Replace C FontSelector by C++ FontSelector.
Fix synchonization problems between users of FontLister (FontSelector/Text toolbar). Hide unused size widget in Glyphs dialog. Display style names in FontSelector using own style.
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/CMakeLists.txt2
-rw-r--r--src/ui/dialog/glyphs.cpp55
-rw-r--r--src/ui/dialog/glyphs.h12
-rw-r--r--src/ui/dialog/text-edit.cpp79
-rw-r--r--src/ui/dialog/text-edit.h12
-rw-r--r--src/ui/widget/font-selector.cpp385
-rw-r--r--src/ui/widget/font-selector.h165
7 files changed, 623 insertions, 87 deletions
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index 1de3d1354..029c00126 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -137,6 +137,7 @@ set(ui_SRC
widget/entry.cpp
widget/filter-effect-chooser.cpp
widget/font-button.cpp
+ widget/font-selector.cpp
widget/font-variants.cpp
widget/frame.cpp
widget/highlight-picker.cpp
@@ -331,6 +332,7 @@ set(ui_SRC
widget/entry.h
widget/filter-effect-chooser.h
widget/font-button.h
+ widget/font-selector.h
widget/font-variants.h
widget/frame.h
widget/highlight-picker.h
diff --git a/src/ui/dialog/glyphs.cpp b/src/ui/dialog/glyphs.cpp
index eb13700ec..07973b4c0 100644
--- a/src/ui/dialog/glyphs.cpp
+++ b/src/ui/dialog/glyphs.cpp
@@ -26,11 +26,12 @@
#include "verbs.h"
#include "libnrtype/font-instance.h"
+#include "libnrtype/font-lister.h"
#include "object/sp-flowtext.h"
#include "object/sp-text.h"
-#include "widgets/font-selector.h"
+#include "ui/widget/font-selector.h"
namespace Inkscape {
namespace UI {
@@ -323,13 +324,6 @@ GlyphColumns *GlyphsPanel::getColumns()
GlyphsPanel::GlyphsPanel() :
Inkscape::UI::Widget::Panel("/dialogs/glyphs", SP_VERB_DIALOG_GLYPHS),
store(Gtk::ListStore::create(*getColumns())),
- iconView(0),
- entry(0),
- label(0),
- insertBtn(0),
- scriptCombo(0),
- fsel(0),
- targetDesktop(0),
deskTrack(),
instanceConns(),
desktopConns()
@@ -340,16 +334,19 @@ GlyphsPanel::GlyphsPanel() :
// -------------------------------
- GtkWidget *fontsel = sp_font_selector_new();
- fsel = SP_FONT_SELECTOR(fontsel);
- sp_font_selector_set_fontspec( fsel, sp_font_selector_get_fontspec(fsel), 12.0 );
-
- gtk_widget_set_size_request (fontsel, 0, 150);
- g_signal_connect( G_OBJECT(fontsel), "font_set", G_CALLBACK(fontChangeCB), this );
+ {
+ fontSelector = new Inkscape::UI::Widget::FontSelector (false);
+ fontSelector->set_fontsize_visible (false);
+ fontSelector->set_size (12.0);
+ fontSelector->set_name ("Glyphs");
- table->attach(*Gtk::manage(Glib::wrap(fontsel)), 0, row, 3, 1);
- row++;
+ sigc::connection conn =
+ fontSelector->connectChanged(sigc::hide(sigc::mem_fun(*this, &GlyphsPanel::rebuild)));
+ instanceConns.push_back(conn);
+ table->attach(*Gtk::manage(fontSelector), 0, row, 3, 1);
+ row++;
+ }
// -------------------------------
@@ -597,13 +594,6 @@ void GlyphsPanel::glyphSelectionChanged()
calcCanInsert();
}
-void GlyphsPanel::fontChangeCB(SPFontSelector * /*fontsel*/, Glib::ustring /*fontspec*/, GlyphsPanel *self)
-{
- if (self) {
- self->rebuild();
- }
-}
-
void GlyphsPanel::selectionModifiedCB(guint flags)
{
bool style = ((flags & ( SP_OBJECT_CHILD_MODIFIED_FLAG |
@@ -636,24 +626,28 @@ void GlyphsPanel::calcCanInsert()
}
}
-void GlyphsPanel::readSelection( bool updateStyle, bool /*updateContent*/ )
+void GlyphsPanel::readSelection( bool updateStyle, bool updateContent )
{
calcCanInsert();
- if (targetDesktop && updateStyle) {
- //SPStyle query(SP_ACTIVE_DOCUMENT);
+ if (updateStyle) {
+ Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance();
+
+ // Update family/style based on selection.
+ fontlister->selection_update();
- //int result_family = sp_desktop_query_style(targetDesktop, &query, QUERY_STYLE_PROPERTY_FONTFAMILY);
- //int result_style = sp_desktop_query_style(targetDesktop, &query, QUERY_STYLE_PROPERTY_FONTSTYLE);
- //int result_numbers = sp_desktop_query_style(targetDesktop, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+ // Get fontspec for selection.
+ Glib::ustring fontspec = fontlister->get_fontspec();
+ // Update GUI.
+ fontSelector->set_fontspec (fontspec);
}
}
void GlyphsPanel::rebuild()
{
- Glib::ustring fontspec = fsel ? sp_font_selector_get_fontspec(fsel) : "";
+ Glib::ustring fontspec = fontSelector->get_fontspec();
font_instance* font = 0;
if( !fontspec.empty() ) {
@@ -661,7 +655,6 @@ void GlyphsPanel::rebuild()
}
if (font) {
- //double sp_font_selector_get_size (SPFontSelector *fsel);
GUnicodeScript script = G_UNICODE_SCRIPT_INVALID_CODE;
Glib::ustring scriptName = scriptCombo->get_active_text();
diff --git a/src/ui/dialog/glyphs.h b/src/ui/dialog/glyphs.h
index 66db421e9..818d38811 100644
--- a/src/ui/dialog/glyphs.h
+++ b/src/ui/dialog/glyphs.h
@@ -20,13 +20,13 @@ class Label;
class ListStore;
}
-struct SPFontSelector;
-class font_instance;
-
-
namespace Inkscape {
namespace UI {
+namespace Widget {
+class FontSelector;
+}
+
namespace Dialog {
class GlyphColumns;
@@ -52,8 +52,6 @@ private:
static GlyphColumns *getColumns();
- static void fontChangeCB(SPFontSelector *fontsel, Glib::ustring fontspec, GlyphsPanel *self);
-
void rebuild();
void glyphActivated(Gtk::TreeModel::Path const & path);
@@ -72,7 +70,7 @@ private:
Gtk::Button *insertBtn;
Gtk::ComboBoxText *scriptCombo;
Gtk::ComboBoxText *rangeCombo;
- SPFontSelector *fsel;
+ Inkscape::UI::Widget::FontSelector *fontSelector;
SPDesktop *targetDesktop;
DesktopTracker deskTrack;
diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp
index f770f1d23..2c122da49 100644
--- a/src/ui/dialog/text-edit.cpp
+++ b/src/ui/dialog/text-edit.cpp
@@ -52,11 +52,10 @@ extern "C" {
#include "ui/icon-names.h"
#include "ui/interface.h"
+#include "ui/widget/font-selector.h"
#include "util/units.h"
-#include "widgets/font-selector.h"
-
namespace Inkscape {
namespace UI {
@@ -87,19 +86,15 @@ TextEdit::TextEdit()
/* Font tab -------------------------------- */
/* Font selector */
- GtkWidget *fontsel = sp_font_selector_new ();
- gtk_widget_set_size_request (fontsel, 0, 150);
- fsel = SP_FONT_SELECTOR(fontsel);
- fontsel_hbox.pack_start(*Gtk::manage(Glib::wrap(fontsel)), true, true);
- fontsel_hbox.set_name("Font Selector HBox");
+ // Do nothing.
/* Font preview */
- preview_label.set_ellipsize(Pango::ELLIPSIZE_END);
- preview_label.set_justify(Gtk::JUSTIFY_CENTER);
- preview_label.set_line_wrap(FALSE);
+ preview_label.set_ellipsize (Pango::ELLIPSIZE_END);
+ preview_label.set_justify (Gtk::JUSTIFY_CENTER);
+ preview_label.set_line_wrap (false);
- font_vbox.pack_start(fontsel_hbox, true, true);
- font_vbox.pack_start(preview_label, true, true, VB_MARGIN);
+ font_vbox.pack_start(font_selector, true, true);
+ font_vbox.pack_start(preview_label, false, false, 5);
/* Text tab -------------------------------- */
scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC );
@@ -133,8 +128,8 @@ TextEdit::TextEdit()
notebook.append_page(font_vbox, font_label);
notebook.append_page(text_vbox, text_label);
notebook.append_page(vari_vbox, vari_label);
-
- /* Buttons (under notebook) ------------------ */
+
+ /* Buttons (below notebook) ------------------ */
setasdefault_button.set_use_underline(true);
apply_button.set_can_default();
button_row.pack_start(setasdefault_button, false, false, 0);
@@ -148,16 +143,18 @@ TextEdit::TextEdit()
contents->pack_start(button_row, false, false, VB_MARGIN);
/* Signal handlers */
- g_signal_connect ( G_OBJECT (fontsel), "font_set", G_CALLBACK (onFontChange), this );
g_signal_connect ( G_OBJECT (text_buffer), "changed", G_CALLBACK (onTextChange), this );
setasdefault_button.signal_clicked().connect(sigc::mem_fun(*this, &TextEdit::onSetDefault));
apply_button.signal_clicked().connect(sigc::mem_fun(*this, &TextEdit::onApply));
close_button.signal_clicked().connect(sigc::bind(_signal_response.make_slot(), GTK_RESPONSE_CLOSE));
+ fontChangedConn = font_selector.connectChanged (sigc::mem_fun(*this, &TextEdit::onFontChange));
fontVariantChangedConn = vari_vbox.connectChanged(sigc::bind(sigc::ptr_fun(&onFontVariantChange), this));
desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TextEdit::setTargetDesktop) );
deskTrack.connect(GTK_WIDGET(gobj()));
+ font_selector.set_name ("TextEdit");
+
show_all_children();
}
@@ -168,6 +165,7 @@ TextEdit::~TextEdit()
selectChangedConn.disconnect();
desktopChangeConn.disconnect();
deskTrack.disconnect();
+ fontChangedConn.disconnect();
fontVariantChangedConn.disconnect();
}
@@ -239,34 +237,29 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ )
// Query style from desktop into it. This returns a result flag and fills query with the
// style of subselection, if any, or selection
- //int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
- int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTFAMILY);
- int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE);
int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
- // If querying returned nothing, read the style from the text tool prefs (default style for new texts)
- // (Ok to not get a font specification - must just rely on the family and style in that case)
- if (result_family == QUERY_STYLE_NOTHING ||
- result_style == QUERY_STYLE_NOTHING ||
- result_numbers == QUERY_STYLE_NOTHING) {
+ // If querying returned nothing, read the style from the text tool prefs (default style for new texts).
+ if (result_numbers == QUERY_STYLE_NOTHING) {
query.readFromPrefs("/tools/text");
}
- // FIXME: process result_family/style == QUERY_STYLE_MULTIPLE_DIFFERENT by showing "Many" in the lists
+ Inkscape::FontLister* font_lister = Inkscape::FontLister::get_instance();
- Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance();
+ // Update family/style based on selection.
+ font_lister->selection_update();
- // This is normally done for us by text-toolbar but only when we are in text editing context
- fontlister->update_font_list(this->desktop->getDocument());
- fontlister->selection_update();
-
- Glib::ustring fontspec = fontlister->get_fontspec();
+ // Get fontspec for selection.
+ Glib::ustring fontspec = font_lister->get_fontspec();
+ font_selector.set_fontspec (fontspec);
+ // Update Size.
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
double size = sp_style_css_size_px_to_units(query.font_size.computed, unit);
- sp_font_selector_set_fontspec(fsel, fontspec, size );
+ font_selector.set_size (size);
+ // Update Preview
setPreviewText (fontspec, phrase);
// Update font variant widget
@@ -293,15 +286,16 @@ void TextEdit::setPreviewText (Glib::ustring font_spec, Glib::ustring phrase)
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
- double pt_size = Inkscape::Util::Quantity::convert(sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit), "px", "pt");
+ double pt_size =
+ Inkscape::Util::Quantity::convert(
+ sp_style_css_size_units_to_px(font_selector.get_fontsize(), unit), "px", "pt");
pt_size = std::min(pt_size, 100.0);
// Pango font size is in 1024ths of a point
Glib::ustring size = std::to_string( int(pt_size * PANGO_SCALE) );
Glib::ustring markup = "<span font=\'" + font_spec_escaped +
- "\' size=\'" + size + "\'>" + phrase_escaped + "</span>";
-
- preview_label.set_markup(markup.c_str());
+ "\' size=\'" + size + "\'>" + phrase + "</span>";
+ preview_label.set_markup (markup);
}
@@ -361,7 +355,7 @@ SPCSSAttr *TextEdit::fillTextStyle ()
{
SPCSSAttr *css = sp_repr_css_attr_new ();
- Glib::ustring fontspec = sp_font_selector_get_fontspec (fsel);
+ Glib::ustring fontspec = font_selector.get_fontspec();
if( !fontspec.empty() ) {
@@ -373,9 +367,10 @@ SPCSSAttr *TextEdit::fillTextStyle ()
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
if (prefs->getBool("/options/font/textOutputPx", true)) {
- os << sp_style_css_size_units_to_px(sp_font_selector_get_size (fsel), unit) << sp_style_get_css_unit_string(SP_CSS_UNIT_PX);
+ os << sp_style_css_size_units_to_px(font_selector.get_fontsize(), unit)
+ << sp_style_get_css_unit_string(SP_CSS_UNIT_PX);
} else {
- os << sp_font_selector_get_size (fsel) << sp_style_get_css_unit_string(unit);
+ os << font_selector.get_fontsize() << sp_style_get_css_unit_string(unit);
}
sp_repr_css_set_property (css, "font-size", os.str().c_str());
}
@@ -433,7 +428,7 @@ void TextEdit::onApply()
}
// Update FontLister
- Glib::ustring fontspec = sp_font_selector_get_fontspec (fsel);
+ Glib::ustring fontspec = font_selector.get_fontspec();
if( !fontspec.empty() ) {
Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance();
fontlister->set_fontspec( fontspec, false );
@@ -461,7 +456,7 @@ void TextEdit::onChange()
gtk_text_buffer_get_bounds (text_buffer, &start, &end);
gchar *str = gtk_text_buffer_get_text(text_buffer, &start, &end, TRUE);
- Glib::ustring fontspec = sp_font_selector_get_fontspec(fsel);
+ Glib::ustring fontspec = font_selector.get_fontspec();
const gchar *phrase = str && *str ? str : samplephrase.c_str();
setPreviewText(fontspec, phrase);
g_free (str);
@@ -477,9 +472,9 @@ void TextEdit::onTextChange (GtkTextBuffer *text_buffer, TextEdit *self)
self->onChange();
}
-void TextEdit::onFontChange(SPFontSelector * /*fontsel*/, gchar* fontspec, TextEdit *self)
+void TextEdit::onFontChange(Glib::ustring fontspec)
{
- self->onChange();
+ onChange();
}
void TextEdit::onFontVariantChange(TextEdit *self)
diff --git a/src/ui/dialog/text-edit.h b/src/ui/dialog/text-edit.h
index f28bc4eaf..e891c8e42 100644
--- a/src/ui/dialog/text-edit.h
+++ b/src/ui/dialog/text-edit.h
@@ -30,6 +30,8 @@
#include "ui/widget/panel.h"
#include "ui/widget/frame.h"
#include "ui/dialog/desktop-tracker.h"
+
+#include "ui/widget/font-selector.h"
#include "ui/widget/font-variants.h"
class SPItem;
@@ -101,19 +103,15 @@ protected:
*
* onFontChange updates the dialog UI. The subfunction setPreviewText updates the preview label.
*
- * @param fontsel pointer to SPFontSelector (currently not used).
* @param fontspec for the text to be previewed.
- * @param self pointer to the current instance of the dialog.
*/
- static void onFontChange (SPFontSelector *fontsel, gchar* fontspec, TextEdit *self);
+ void onFontChange (Glib::ustring fontspec);
/**
* Callback invoked when the user modifies the font variant through the dialog.
*
* onFontChange updates the dialog UI. The subfunction setPreviewText updates the preview label.
*
- * @param fontsel pointer to FontVariant (currently not used).
- * @param fontspec for the text to be previewed.
* @param self pointer to the current instance of the dialog.
*/
static void onFontVariantChange (TextEdit *self);
@@ -166,8 +164,7 @@ private:
Gtk::VBox font_vbox;
Gtk::Label font_label;
- Gtk::Box fontsel_hbox;
- SPFontSelector *fsel;
+ Inkscape::UI::Widget::FontSelector font_selector;
Gtk::Label preview_label; // Share with variants tab?
// Tab 2: Text ---------------------- //
@@ -195,6 +192,7 @@ private:
sigc::connection selectChangedConn;
sigc::connection subselChangedConn;
sigc::connection selectModifiedConn;
+ sigc::connection fontChangedConn;
sigc::connection fontVariantChangedConn;
// Other
diff --git a/src/ui/widget/font-selector.cpp b/src/ui/widget/font-selector.cpp
new file mode 100644
index 000000000..3e535aee4
--- /dev/null
+++ b/src/ui/widget/font-selector.cpp
@@ -0,0 +1,385 @@
+/*
+ * Author:
+ * Tavmjong Bah <tavmjong@free.fr>
+ *
+ * Copyright (C) 2018 Tavmong Bah
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glibmm/i18n.h>
+
+#include "font-selector.h"
+
+#include "libnrtype/font-lister.h"
+#include "libnrtype/font-instance.h"
+
+// For updating from selection
+#include "inkscape.h"
+#include "desktop.h"
+#include "object/sp-text.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+FontSelector::FontSelector (bool with_size)
+ : Gtk::Grid ()
+ , family_frame (_("Font family"))
+ , style_frame (C_("Font selector", "Style"))
+ , size_label (_("Font size"))
+ , size_combobox (true) // With entry
+ , signal_block (false)
+ , font_size (18)
+{
+
+ Inkscape::FontLister* font_lister = Inkscape::FontLister::get_instance();
+
+ // Font family
+ family_treecolumn.pack_start (family_cell, false);
+ family_treecolumn.set_fixed_width (200);
+ family_treecolumn.add_attribute (family_cell, "text", 0);
+ family_treecolumn.set_cell_data_func (family_cell, &font_lister_cell_data_func);
+
+ family_treeview.set_row_separator_func (&font_lister_separator_func);
+ family_treeview.set_model (font_lister->get_font_list());
+ family_treeview.set_name ("FontSelector: Family");
+ family_treeview.set_headers_visible (false);
+ family_treeview.append_column (family_treecolumn);
+
+ family_scroll.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
+ family_scroll.add (family_treeview);
+
+ family_frame.set_hexpand (true);
+ family_frame.set_vexpand (true);
+ family_frame.add (family_scroll);
+
+ // Style
+ style_treecolumn.pack_start (style_cell, false);
+ style_treecolumn.add_attribute (style_cell, "text", 0);
+ //style_treecolumn.set_cell_data_func (style_cell, &font_lister_style_cell_data_func);
+ style_treecolumn.set_cell_data_func (style_cell, sigc::mem_fun(*this, &FontSelector::style_cell_data_func));
+
+ style_treeview.set_model (font_lister->get_style_list());
+ style_treeview.set_name ("FontSelector: Style");
+ style_treeview.append_column ("CSS", font_lister->FontStyleList.cssStyle);
+ //style_treeview.append_column ("Face",font_lister->FontStyleList.displayStyle);
+ style_treeview.append_column (style_treecolumn);
+
+ style_scroll.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
+ style_scroll.add (style_treeview);
+
+ style_frame.set_vexpand (true);
+ style_frame.add (style_scroll);
+
+ // Size
+ size_combobox.set_name ("FontSelector: Size");
+ set_sizes();
+ size_combobox.set_active_text( "18" );
+
+ // Grid
+ set_name ("FontSelector: Grid");
+ attach (family_frame, 0, 0, 1, 2);
+ attach (style_frame, 1, 0, 2, 1);
+ if (with_size) { // Glyph panel does not use size.
+ attach (size_label, 1, 1, 1, 1);
+ attach (size_combobox, 2, 1, 1, 1);
+ }
+
+ // Add signals
+ family_treeview.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FontSelector::on_family_changed));
+ style_treeview.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FontSelector::on_style_changed));
+ size_combobox.signal_changed().connect(sigc::mem_fun(*this, &FontSelector::on_size_changed));
+
+ show_all_children();
+
+ // Initialize font family lists. (May already be done.) Should be done on document change.
+ font_lister->update_font_list(SP_ACTIVE_DESKTOP->getDocument());
+
+ font_lister->connectUpdate(sigc::mem_fun(*this, &FontSelector::set_fontspec));
+}
+
+void
+FontSelector::set_sizes ()
+{
+ size_combobox.remove_all();
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
+
+ int sizes[] = {
+ 4, 6, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 24, 28,
+ 32, 36, 40, 48, 56, 64, 72, 144
+ };
+
+ // Array must be same length as SPCSSUnit in style-internal.h
+ // PX PT PC MM CM IN EM EX %
+ double ratios[] = {1, 1, 1, 10, 4, 40, 100, 16, 8, 0.16};
+
+ for (unsigned int i = 0; i < G_N_ELEMENTS(sizes); ++i)
+ {
+ double size = sizes[i]/ratios[unit];
+ size_combobox.append( Glib::ustring::format(size) );
+ }
+}
+
+void
+FontSelector::set_fontsize_tooltip()
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
+ Glib::ustring tooltip = Glib::ustring::format(_("Font size"), " (", sp_style_get_css_unit_string(unit), ")");
+ size_combobox.set_tooltip_text (tooltip);
+}
+
+// Update GUI. TODO: Rename function
+void
+FontSelector::set_fontspec (const Glib::ustring& fontspec)
+{
+ signal_block = true;
+
+ if (!fontspec.empty()) {
+ Inkscape::FontLister *font_lister = Inkscape::FontLister::get_instance();
+ std::pair<Glib::ustring, Glib::ustring> ui = font_lister->ui_from_fontspec( fontspec );
+ Glib::ustring family = ui.first;
+ Glib::ustring style = ui.second;
+ Gtk::TreePath path;
+
+ // Set font family
+ try {
+ path = font_lister->get_row_for_font (family);
+ } catch (...) {
+ g_warning( "Couldn't find row for font-family: %s", family.c_str() );
+ path.clear();
+ path.push_back(0);
+ }
+ family_treeview.set_cursor (path);
+ family_treeview.scroll_to_row (path);
+
+ // Get font-lister style list for selected family
+ Gtk::TreeModel::Row row = font_lister->get_row_for_font (family);
+ GList *styles;
+ row.get_value(1, styles);
+
+ // Copy font-lister style list to private list store, searching for match.
+ Gtk::TreeModel::iterator match;
+ FontLister::FontStyleListClass FontStyleList;
+ Glib::RefPtr<Gtk::ListStore> local_style_list_store = Gtk::ListStore::create(FontStyleList);
+ for ( ; styles; styles = styles->next ) {
+ Gtk::TreeModel::iterator treeModelIter = local_style_list_store->append();
+ (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames *)styles->data)->CssName;
+ (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames *)styles->data)->DisplayName;
+ if (style == ((StyleNames*)styles->data)->CssName) {
+ match = treeModelIter;
+ }
+ }
+
+ // Attach store to tree view and select row.
+ style_treeview.set_model (local_style_list_store);
+ if (match) {
+ style_treeview.get_selection()->select (match);
+ }
+ }
+
+ signal_block = false;
+}
+
+void
+FontSelector::set_size (double size)
+{
+ signal_block = true;
+
+ // Set font size
+ std::stringstream ss;
+ ss << size;
+ size_combobox.get_entry()->set_text( ss.str() );
+ font_size = size; // Store value
+ set_fontsize_tooltip();
+
+ signal_block = false;
+}
+
+
+Glib::ustring
+FontSelector::get_fontspec() {
+
+ // Build new fontspec from GUI settings
+ Glib::ustring family = "Sans"; // Default...family list may not have been constructed.
+ Gtk::TreeModel::iterator iter = family_treeview.get_selection()->get_selected();
+ if (iter) {
+ (*iter).get_value(0, family);
+ }
+
+ Glib::ustring style = "Normal";
+ iter = style_treeview.get_selection()->get_selected();
+ if (iter) {
+ (*iter).get_value(0, style);
+ }
+
+ if (family.empty()) {
+ std::cerr << "FontSelector::get_fontspec: empty family!" << std::endl;
+ }
+
+ if (style.empty()) {
+ std::cerr << "FontSelector::get_fontspec: empty style!" << std::endl;
+ }
+
+ Glib::ustring fontspec = family + ", " + style;
+
+ return fontspec;
+}
+
+void
+FontSelector::style_cell_data_func (Gtk::CellRenderer *renderer, Gtk::TreeIter const &iter)
+{
+ Glib::ustring family = "Sans"; // Default...family list may not have been constructed.
+ Gtk::TreeModel::iterator iter_family = family_treeview.get_selection()->get_selected();
+ if (iter_family) {
+ (*iter_family).get_value(0, family);
+ }
+
+ Glib::ustring style = "Normal";
+ (*iter).get_value(0, style);
+
+ Glib::ustring style_escaped = Glib::strescape( style );
+ Glib::ustring font_desc = family + ", " + style;
+ Glib::ustring markup;
+
+ markup = "<span font='" + font_desc + "'>" + style_escaped + "</span>";
+
+ // std::cout << " markup: " << markup << " (" << name << ")" << std::endl;
+
+ renderer->set_property("markup", markup);
+}
+
+
+// Callbacks
+
+// Need to update style list
+void
+FontSelector::on_family_changed() {
+
+ if (signal_block) return;
+ signal_block = true;
+
+ Glib::RefPtr<Gtk::TreeModel> model;
+ Gtk::TreeModel::iterator iter = family_treeview.get_selection()->get_selected(model);
+
+ if (!iter) {
+ // This can happen just after the family list is recreated.
+ signal_block = false;
+ return;
+ }
+
+ Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance();
+ fontlister->ensureRowStyles(model, iter);
+
+ Gtk::TreeModel::Row row = *iter;
+
+ // Get family name
+ Glib::ustring family;
+ row.get_value(0, family);
+
+ // Get style list (TO DO: Get rid of GList)
+ GList *styles;
+ row.get_value(1, styles);
+
+ // Find best style match for selected family with current style (e.g. of selected text).
+ Glib::ustring style = fontlister->get_font_style();
+ Glib::ustring best = fontlister->get_best_style_match (family, style);
+
+ // Create are own store of styles for selected font-family (the font-family selected
+ // in the dialog may not be the same as stored in the font-lister class until the
+ // "Apply" button is triggered).
+ Gtk::TreeModel::iterator it_best;
+ FontLister::FontStyleListClass FontStyleList;
+ Glib::RefPtr<Gtk::ListStore> local_style_list_store = Gtk::ListStore::create(FontStyleList);
+
+ // Build list and find best match.
+ for ( ; styles; styles = styles->next ) {
+ Gtk::TreeModel::iterator treeModelIter = local_style_list_store->append();
+ (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames *)styles->data)->CssName;
+ (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames *)styles->data)->DisplayName;
+ if (best == ((StyleNames*)styles->data)->CssName) {
+ it_best = treeModelIter;
+ }
+ }
+
+ // Attach store to tree view and select row.
+ style_treeview.set_model (local_style_list_store);
+ if (it_best) {
+ style_treeview.get_selection()->select (it_best);
+ }
+
+ signal_block = false;
+
+ // Let world know
+ changed_emit();
+}
+
+void
+FontSelector::on_style_changed() {
+
+ if (signal_block) return;
+
+ // Let world know
+ changed_emit();
+}
+
+void
+FontSelector::on_size_changed() {
+
+ if (signal_block) return;
+
+ double size;
+ Glib::ustring input = size_combobox.get_active_text();
+ try {
+ size = std::stod (input);
+ }
+ catch (std::invalid_argument) {
+ std::cerr << "FontSelector::on_size_changed: Invalid input: " << input << std::endl;
+ size = -1;
+ }
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ // Arbitrary: Text and Font preview freezes with huge font sizes.
+ int max_size = prefs->getInt("/dialogs/textandfont/maxFontSize", 10000);
+
+ if (size <= 0) {
+ return;
+ }
+ if (size > max_size)
+ size = max_size;
+
+ if (fabs(font_size - size) > 0.001) {
+ font_size = size;
+ // Let world know
+ changed_emit();
+ }
+}
+
+void
+FontSelector::changed_emit() {
+ signal_block = true;
+ changed_signal.emit (get_fontspec());
+ signal_block = false;
+}
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :
diff --git a/src/ui/widget/font-selector.h b/src/ui/widget/font-selector.h
new file mode 100644
index 000000000..2fd4eee72
--- /dev/null
+++ b/src/ui/widget/font-selector.h
@@ -0,0 +1,165 @@
+/*
+ * Author:
+ * Tavmjong Bah <tavmjong@free.fr>
+ *
+ * Copyright (C) 2018 Tavmong Bah
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ *
+ *
+ * The routines here create and manage a font selector widget with three parts,
+ * one each for font-family, font-style, and font-size.
+ *
+ * It is used by the TextEdit and Glyphs panel dialogs. The FontLister class is used
+ * to access the list of font-families and their associated styles for fonts either
+ * on the system or in the document. The FontLister class is also used by the Text
+ * toolbar. Fonts are kept track of by their "fontspecs" which are the same as the
+ * strings that Pango generates.
+ *
+ * The main functions are:
+ * Create the font-seletor widget.
+ * Update the lists when a new text selection is made.
+ * Update the Style list when a new font-family is selected, highlighting the
+ * best match to the original font style (as not all fonts have the same style options).
+ * Emit a signal when any change is made so that the Text Preview can be updated.
+ * Provide the currently selected values.
+ */
+
+#ifndef INKSCAPE_UI_WIDGET_FONT_SELECTOR_H
+#define INKSCAPE_UI_WIDGET_FONT_SELECTOR_H
+
+#include <gtkmm/grid.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/label.h>
+#include <gtkmm/comboboxtext.h>
+
+// class SPDesktop;
+// class SPObject;
+class SPStyle;
+class SPCSSAttr;
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+/**
+ * A container of widgets for selecting font faces.
+ *
+ * It is used by the TextEdit and Glyphs panel dialogs. The FontSelector class utilizes the
+ * FontLister class to obtain a list of font-families and their associated styles for fonts either
+ * on the system or in the document. The FontLister class is also used by the Text toolbar. Fonts
+ * are kept track of by their "fontspecs" which are the same as the strings that Pango generates.
+ *
+ * The main functions are:
+ * Create the font-selector widget.
+ * Update the child widgets when a new text selection is made.
+ * Update the Style list when a new font-family is selected, highlighting the
+ * best match to the original font style (as not all fonts have the same style options).
+ * Emit a signal when any change is made to a child widget.
+ */
+class FontSelector : public Gtk::Grid
+{
+
+public:
+
+ /**
+ * Constructor
+ */
+ FontSelector (bool with_size = true);
+
+protected:
+
+ // Font family
+ Gtk::Frame family_frame;
+ Gtk::ScrolledWindow family_scroll;
+ Gtk::TreeView family_treeview;
+ Gtk::TreeViewColumn family_treecolumn;
+ Gtk::CellRendererText family_cell;
+
+ // Font style
+ Gtk::Frame style_frame;
+ Gtk::ScrolledWindow style_scroll;
+ Gtk::TreeView style_treeview;
+ Gtk::TreeViewColumn style_treecolumn;
+ Gtk::CellRendererText style_cell;
+
+ // Font size
+ Gtk::Label size_label;
+ Gtk::ComboBoxText size_combobox;
+
+private:
+
+ // Set sizes in font size combobox.
+ void set_sizes();
+ void set_fontsize_tooltip();
+
+ // Use font style when listing style names.
+ void style_cell_data_func (Gtk::CellRenderer *renderer, Gtk::TreeIter const &iter);
+
+ // Signal handlers
+ void on_family_changed();
+ void on_style_changed();
+ void on_size_changed();
+
+ // Signals
+ sigc::signal<void, Glib::ustring> changed_signal;
+ void changed_emit();
+ bool signal_block;
+
+ // Variables
+ double font_size;
+
+public:
+
+ /**
+ * Update GUI based on fontspec
+ */
+ void set_fontspec (const Glib::ustring& fontspec);
+ void set_size (double size);
+
+ /**
+ * Get fontspec based on current settings. (Does not handle size, yet.)
+ */
+ Glib::ustring get_fontspec();
+
+ /**
+ * Get font size. Could be merged with fontspec.
+ */
+ double get_fontsize() { return font_size; };
+
+ /**
+ * Shoe/hide size widgets
+ */
+ void set_fontsize_visible( bool visible = true ) {
+ size_label.set_visible (visible);
+ size_combobox.set_visible (visible);
+ }
+
+ /**
+ * Let others know that user has changed GUI settings.
+ * (Used to enable 'Apply' and 'Default' buttons.)
+ */
+ sigc::connection connectChanged(sigc::slot<void, Glib::ustring> slot) {
+ return changed_signal.connect(slot);
+ }
+};
+
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+#endif // INKSCAPE_UI_WIDGET_FONT_SETTINGS_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 :