diff --git a/area.js b/area.js
index e8e220b..775bdeb 100644
--- a/area.js
+++ b/area.js
@@ -54,7 +54,7 @@ const ManipulationNames = { 100: "Move", 101: "Resize", 102: "Mirror" };
var Tools = Object.assign({}, Shapes, Manipulations);
var ToolNames = Object.assign({}, ShapeNames, ManipulationNames);
-var FontGenericNames = { 0: 'Theme', 1: 'Sans-Serif', 2: 'Serif', 3: 'Monospace', 4: 'Cursive', 5: 'Fantasy' };
+var FontGenericFamilies = ['Sans-Serif', 'Serif', 'Monospace', 'Cursive', 'Fantasy'];
// DrawingArea is the widget in which we draw, thanks to Cairo.
// It creates and manages a DrawingElement for each "brushstroke".
@@ -82,7 +82,6 @@ var DrawingArea = new Lang.Class({
this.currentElement = null;
this.currentTool = Shapes.NONE;
this.currentImage = 0;
- this.currentFontGeneric = 0;
this.isSquareArea = false;
this.hasGrid = false;
this.hasBackground = false;
@@ -145,6 +144,24 @@ var DrawingArea = new Lang.Class({
return images;
},
+ get currentFontFamily() {
+ return this._currentFontFamily || this.currentThemeFontFamily;
+ },
+
+ set currentFontFamily(fontFamily) {
+ this._currentFontFamily = fontFamily;
+ },
+
+ get fontFamilies() {
+ if (!this._fontFamilies) {
+ let pangoFontFamilies = Elements.getPangoFontFamilies().filter(family => {
+ return family != this.currentThemeFontFamily && FontGenericFamilies.indexOf(family) == -1;
+ });
+ this._fontFamilies = [this.currentThemeFontFamily].concat(FontGenericFamilies, pangoFontFamilies);
+ }
+ return this._fontFamilies;
+ },
+
vfunc_repaint: function() {
let cr = this.get_context();
@@ -198,6 +215,7 @@ var DrawingArea = new Lang.Class({
this.colors[i] = this.colors[i].alpha ? this.colors[i] : this.colors[0];
}
this.currentColor = this.currentColor || this.colors[1];
+ this._fontFamilies = null;
// SVG does not support 'Ultra-heavy' weight (1000)
this.newThemeAttributes.FontWeight = Math.min(this.newThemeAttributes.FontWeight, 900);
this.newThemeAttributes.LineWidth = (this.newThemeAttributes.LineWidth > 0) ? this.newThemeAttributes.LineWidth : 3;
@@ -545,7 +563,7 @@ var DrawingArea = new Lang.Class({
color: this.currentColor.to_string(),
eraser: eraser,
font: {
- family: (this.currentFontGeneric == 0 ? this.currentThemeFontFamily : FontGenericNames[this.currentFontGeneric]),
+ family: this.currentFontFamily,
weight: this.currentFontWeight,
style: this.currentFontStyle,
stretch: this.currentFontStretch,
@@ -913,13 +931,13 @@ var DrawingArea = new Lang.Class({
},
toggleFontFamily: function() {
- this.currentFontGeneric = this.currentFontGeneric == 5 ? 0 : this.currentFontGeneric + 1;
- let currentFontFamily = this.currentFontGeneric == 0 ? this.currentThemeFontFamily : FontGenericNames[this.currentFontGeneric];
+ let index = Math.max(0, this.fontFamilies.indexOf(this.currentFontFamily));
+ this.currentFontFamily = (index == this.fontFamilies.length - 1) ? 0 : this.fontFamilies[index + 1];
if (this.currentElement && this.currentElement.font) {
- this.currentElement.font.family = currentFontFamily;
+ this.currentElement.font.family = this.currentFontFamily;
this._redisplay();
}
- this.emit('show-osd', null, `${_(currentFontFamily)}`, "", -1, false);
+ this.emit('show-osd', null, `${_(this.currentFontFamily)}`, "", -1, false);
},
toggleTextAlignment: function() {
@@ -978,7 +996,7 @@ var DrawingArea = new Lang.Class({
this.stageKeyReleasedHandler = global.stage.connect('key-release-event', this._onStageKeyReleased.bind(this));
this.keyPressedHandler = this.connect('key-press-event', this._onKeyPressed.bind(this));
this.buttonPressedHandler = this.connect('button-press-event', this._onButtonPressed.bind(this));
- this._onKeyboardPopupMenuHandler = this.connect('popup-menu', this._onKeyboardPopupMenu.bind(this));
+ this.keyboardPopupMenuHandler = this.connect('popup-menu', this._onKeyboardPopupMenu.bind(this));
this.scrollHandler = this.connect('scroll-event', this._onScroll.bind(this));
this.get_parent().set_background_color(this.reactive && this.hasBackground ? this.activeBackgroundColor : null);
this._updateStyle();
@@ -1001,9 +1019,9 @@ var DrawingArea = new Lang.Class({
this.disconnect(this.buttonPressedHandler);
this.buttonPressedHandler = null;
}
- if (this._onKeyboardPopupMenuHandler) {
- this.disconnect(this._onKeyboardPopupMenuHandler);
- this._onKeyboardPopupMenuHandler = null;
+ if (this.keyboardPopupMenuHandler) {
+ this.disconnect(this.keyboardPopupMenuHandler);
+ this.keyboardPopupMenuHandler = null;
}
if (this.motionHandler) {
this.disconnect(this.motionHandler);
diff --git a/elements.js b/elements.js
index 4615e93..c2214c7 100644
--- a/elements.js
+++ b/elements.js
@@ -46,6 +46,10 @@ var FontStyleNames = reverseEnumeration(Pango.Style);
var FontStretchNames = reverseEnumeration(Pango.Stretch);
var FontVariantNames = reverseEnumeration(Pango.Variant);
+var getPangoFontFamilies = function() {
+ return PangoCairo.font_map_get_default().list_families().map(fontFamily => fontFamily.get_name()).sort((a,b) => a.localeCompare(b));
+};
+
const SVG_DEBUG_SUPERPOSES_CAIRO = false;
const RADIAN = 180 / Math.PI; // degree
const INVERSION_CIRCLE_RADIUS = 12; // px
diff --git a/menu.js b/menu.js
index 1c64232..b70eca4 100644
--- a/menu.js
+++ b/menu.js
@@ -56,6 +56,9 @@ const FILLRULE_EVENODD_ICON_PATH = ICON_DIR.get_child('fillrule-evenodd-symbolic
const DASHED_LINE_ICON_PATH = ICON_DIR.get_child('dashed-line-symbolic.svg').get_path();
const FULL_LINE_ICON_PATH = ICON_DIR.get_child('full-line-symbolic.svg').get_path();
+// 150 labels with font-family style take ~15Mo
+const FONT_FAMILY_STYLE = true;
+
const getActor = function(object) {
return GS_VERSION < '3.33.0' ? object.actor : object;
};
@@ -180,9 +183,7 @@ var DrawingMenu = new Lang.Class({
this.lineSection = lineSection;
let fontSection = new PopupMenu.PopupMenuSection();
- let FontGenericNamesCopy = Object.create(Area.FontGenericNames);
- FontGenericNamesCopy[0] = this.area.currentThemeFontFamily;
- this._addSubMenuItem(fontSection, 'font-x-generic-symbolic', FontGenericNamesCopy, this.area, 'currentFontGeneric');
+ this._addFontFamilySubMenuItem(fontSection, 'font-x-generic-symbolic');
this._addSubMenuItem(fontSection, 'format-text-bold-symbolic', Elements.FontWeightNames, this.area, 'currentFontWeight');
this._addSubMenuItem(fontSection, 'format-text-italic-symbolic', Elements.FontStyleNames, this.area, 'currentFontStyle');
this._addSwitchItem(fontSection, _("Right aligned"), 'format-justify-left-symbolic', 'format-justify-right-symbolic', this.area, 'currentTextRightAligned');
@@ -342,9 +343,7 @@ var DrawingMenu = new Lang.Class({
GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
for (let i in obj) {
let text;
- if (targetProperty == 'currentFontGeneric')
- text = `${_(obj[i])}`;
- else if (targetProperty == 'currentFontWeight')
+ if (targetProperty == 'currentFontWeight')
text = `${_(obj[i])}`;
else if (targetProperty == 'currentFontStyle')
text = `${_(obj[i])}`;
@@ -391,7 +390,6 @@ var DrawingMenu = new Lang.Class({
this.area.currentColor = this.area.colors[iCaptured];
item.icon.set_style(`color:${this.area.currentColor.to_string().slice(0, 7)};`);
});
- colorItem.label.get_clutter_text().set_use_markup(true);
// Foreground color markup is not displayed since 3.36, use style instead but the transparency is lost.
colorItem.label.set_style(`color:${this.area.colors[i].to_string().slice(0, 7)};`);
}
@@ -401,6 +399,32 @@ var DrawingMenu = new Lang.Class({
return item;
},
+ _addFontFamilySubMenuItem: function(menu, icon) {
+ let item = new PopupMenu.PopupSubMenuMenuItem(this.area.currentFontFamily, true);
+ item.icon.set_icon_name(icon);
+
+ item.menu.itemActivated = () => {
+ item.menu.close();
+ };
+
+ item.menu.openOld = item.menu.open;
+ item.menu.open = (animate) => {
+ if (!item.menu.isOpen && item.menu.isEmpty()) {
+ this.area.fontFamilies.forEach(family => {
+ let subItem = item.menu.addAction(_(family), () => {
+ item.label.set_text(_(family));
+ this.area.currentFontFamily = family;
+ });
+ if (FONT_FAMILY_STYLE)
+ subItem.label.set_style(`font-family:${family}`);
+ });
+ }
+ item.menu.openOld();
+ };
+
+ menu.addMenuItem(item);
+ },
+
_addDrawingNameItem: function(menu) {
this.drawingNameMenuItem = new PopupMenu.PopupMenuItem('', { reactive: false, activate: false });
this.drawingNameMenuItem.setSensitive(false);
@@ -420,8 +444,8 @@ var DrawingMenu = new Lang.Class({
_addOpenDrawingSubMenuItem: function(menu) {
let item = new PopupMenu.PopupSubMenuMenuItem(_("Open drawing"), true);
this.openDrawingSubMenuItem = item;
- this.openDrawingSubMenuItem.setSensitive(Boolean(Files.getJsons().length));
this.openDrawingSubMenu = item.menu;
+ item.setSensitive(Boolean(Files.getJsons().length));
item.icon.set_icon_name('document-open-symbolic');
item.menu.itemActivated = () => {