diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2018-04-13 09:43:53 +0000 |
|---|---|---|
| committer | Tavmjong Bah <tavmjong@free.fr> | 2018-04-13 09:43:53 +0000 |
| commit | 1ddfdd2c6d5f915da6a7563c2d29021d53ff07ed (patch) | |
| tree | 21241bccd07beb89b054b746685f118021e4cf93 /src/ui | |
| parent | Remove unused variables. (diff) | |
| download | inkscape-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.txt | 2 | ||||
| -rw-r--r-- | src/ui/dialog/glyphs.cpp | 55 | ||||
| -rw-r--r-- | src/ui/dialog/glyphs.h | 12 | ||||
| -rw-r--r-- | src/ui/dialog/text-edit.cpp | 79 | ||||
| -rw-r--r-- | src/ui/dialog/text-edit.h | 12 | ||||
| -rw-r--r-- | src/ui/widget/font-selector.cpp | 385 | ||||
| -rw-r--r-- | src/ui/widget/font-selector.h | 165 |
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 : |
