2019-03-05 08:36:59 -03:00
/* jslint esversion: 6 */
/ *
* Copyright 2019 Abakkk
*
* This file is part of DrowOnYourScreen , a drawing extension for GNOME Shell .
* https : //framagit.org/abakkk/DrawOnYourScreen
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
* /
const GObject = imports . gi . GObject ;
const Gtk = imports . gi . Gtk ;
const Lang = imports . lang ;
const ExtensionUtils = imports . misc . extensionUtils ;
const Extension = ExtensionUtils . getCurrentExtension ( ) ;
const Convenience = Extension . imports . convenience ;
const Metadata = Extension . metadata ;
const _ = imports . gettext . domain ( Extension . metadata [ "gettext-domain" ] ) . gettext ;
const MARGIN = 10 ;
var GLOBAL _KEYBINDINGS = {
'toggle-drawing' : "Enter/leave drawing mode" ,
'erase-drawing' : "Erase all drawings"
} ;
var INTERNAL _KEYBINDINGS = {
'undo' : "Undo last brushstroke" ,
'redo' : "Redo last brushstroke" ,
'delete-last-element' : "Erase last brushstroke" ,
2019-03-05 17:08:43 -03:00
'smooth-last-element' : "Smooth last brushstroke" ,
2019-03-05 08:36:59 -03:00
'-separator-1' : '' ,
'increment-line-width' : "Increment line width" ,
'decrement-line-width' : "Decrement line width" ,
'increment-line-width-more' : "Increment line width even more" ,
'decrement-line-width-more' : "Decrement line width even more" ,
'toggle-linejoin' : "Change linejoin" ,
'toggle-linecap' : "Change linecap" ,
'toggle-dash' : "Dashed line" ,
'-separator-2' : '' ,
'select-line-shape' : "Select line" ,
2019-03-07 10:28:35 -03:00
'select-ellipse-shape' : "Select ellipse" ,
2019-03-05 08:36:59 -03:00
'select-rectangle-shape' : "Select rectangle" ,
'select-text-shape' : "Select text" ,
'select-none-shape' : "Unselect shape (free drawing)" ,
'-separator-3' : '' ,
'toggle-font-family' : "Change font family (generic name)" ,
'toggle-font-weight' : "Change font weight" ,
'toggle-font-style' : "Change font style" ,
'-separator-4' : '' ,
'toggle-panel-and-dock-visibility' : "Hide panel and dock" ,
'toggle-background' : "Add a drawing background" ,
2019-03-07 12:32:06 -03:00
'toggle-square-area' : "Square drawing area" ,
2019-03-05 08:36:59 -03:00
'-separator-5' : '' ,
'save-as-svg' : "Save drawing as a SVG file" ,
'open-stylesheet' : "Open stylesheet.css" ,
'toggle-help' : "Show help"
} ;
2019-03-05 18:00:14 -03:00
var OTHER _SHORTCUTS = [
{ desc : "Draw" , shortcut : "Left click" } ,
{ desc : "Draw by filling in" , shortcut : "Right click" } ,
{ desc : "Toggle shape" , shortcut : "Center click" } ,
2019-03-07 10:28:35 -03:00
{ desc : "Transform shape (when drawing)" , shortcut : "Ctrl key" } ,
2019-03-05 18:00:14 -03:00
{ desc : "Increment/decrement line width" , shortcut : "Scroll" } ,
{ desc : "Select color" , shortcut : "Ctrl+1...9" } ,
{ desc : "Select eraser" , shortcut : "Shift key held" } ,
{ desc : "Leave and erase all drawings" , shortcut : "Escape key" }
] ;
2019-03-05 08:36:59 -03:00
function init ( ) {
Convenience . initTranslations ( ) ;
}
function buildPrefsWidget ( ) {
let prefsPage = new PrefsPage ( ) ;
prefsPage . show _all ( ) ;
return prefsPage ;
}
const PrefsPage = new GObject . Class ( {
Name : 'PrefsPage' ,
GTypeName : 'PrefsPage' ,
Extends : Gtk . ScrolledWindow ,
_init : function ( params ) {
this . parent ( ) ;
this . settings = Convenience . getSettings ( ) ;
let box = new Gtk . Box ( { orientation : Gtk . Orientation . VERTICAL , margin : MARGIN * 3 } ) ;
this . add ( box ) ;
let textBox1 = new Gtk . Box ( { orientation : Gtk . Orientation . VERTICAL , margin : MARGIN } ) ;
let text1 = new Gtk . Label ( { wrap : true , justify : 2 , use _markup : true ,
2019-03-07 10:28:35 -03:00
label : "<big> " + _ ( "Start drawing with Super+Alt+D\nThen save your beautiful work by taking a screenshot" ) + "</big>" } ) ;
2019-03-05 08:36:59 -03:00
textBox1 . pack _start ( text1 , false , false , 0 ) ;
box . add ( textBox1 ) ;
let listBox = new Gtk . ListBox ( { selection _mode : 0 , hexpand : true , margin _top : 2 * MARGIN , margin _bottom : 2 * MARGIN } ) ;
box . add ( listBox ) ;
let styleContext = listBox . get _style _context ( ) ;
styleContext . add _class ( 'background' ) ;
let globalTitleBox = new Gtk . Box ( { margin : MARGIN } ) ;
let globalTitleLabel = new Gtk . Label ( { use _markup : true , label : "<b><big>" + _ ( "Global" ) + " :</big></b>" } ) ;
globalTitleLabel . set _halign ( 1 ) ;
globalTitleBox . pack _start ( globalTitleLabel , true , true , 4 ) ;
listBox . add ( globalTitleBox ) ;
let globalKeybindingsWidget = new KeybindingsWidget ( GLOBAL _KEYBINDINGS , this . settings ) ;
globalKeybindingsWidget . margin = MARGIN ;
listBox . add ( globalKeybindingsWidget ) ;
this . addSeparator ( listBox ) ;
let internalTitleBox = new Gtk . Box ( { margin : MARGIN } ) ;
let internalTitleLabel = new Gtk . Label ( { use _markup : true , label : "<b><big>" + _ ( "Internal" ) + " </big></b>" + _ ( "(in drawing mode)" ) + " <b><big>:</big></b>" } ) ;
internalTitleLabel . set _halign ( 1 ) ;
internalTitleBox . pack _start ( internalTitleLabel , true , true , 4 ) ;
listBox . add ( internalTitleBox ) ;
listBox . add ( new Gtk . Box ( { margin _top : MARGIN / 2 , margin _left : MARGIN , margin _right : MARGIN } ) ) ;
2019-03-05 18:00:14 -03:00
for ( let i = 0 ; i < OTHER _SHORTCUTS . length ; i ++ ) {
if ( OTHER _SHORTCUTS [ i ] . desc . indexOf ( '-separator-' ) != - 1 ) {
2019-03-05 08:36:59 -03:00
listBox . add ( new Gtk . Box ( { margin _top : MARGIN , margin _left : MARGIN , margin _right : MARGIN } ) ) ;
continue ;
}
let otherBox = new Gtk . Box ( { margin _left : MARGIN , margin _right : MARGIN } ) ;
2019-03-05 18:00:14 -03:00
let otherLabel = new Gtk . Label ( { label : _ ( OTHER _SHORTCUTS [ i ] . desc ) } ) ;
2019-03-05 08:36:59 -03:00
otherLabel . set _halign ( 1 ) ;
2019-03-05 18:00:14 -03:00
let otherLabel2 = new Gtk . Label ( { label : _ ( OTHER _SHORTCUTS [ i ] . shortcut ) } ) ;
2019-03-05 08:36:59 -03:00
otherBox . pack _start ( otherLabel , true , true , 4 ) ;
otherBox . pack _start ( otherLabel2 , false , false , 4 ) ;
listBox . add ( otherBox ) ;
}
listBox . add ( new Gtk . Box ( { margin _top : MARGIN , margin _left : MARGIN , margin _right : MARGIN } ) ) ;
2019-03-07 10:28:35 -03:00
let controlBox = new Gtk . Box ( { margin _top : MARGIN , margin _left : MARGIN , margin _right : MARGIN , margin _bottom : MARGIN } ) ;
let controlLabel = new Gtk . Label ( {
use _markup : true ,
label : _ ( "By pressing <b>Ctrl</b> key <b>during</b> the drawing process, you can:\n . rotate a rectangle or a text area\n . extend and rotate an ellipse\n . curve a line (cubic Bezier curve)" )
} ) ;
controlLabel . set _halign ( 1 ) ;
controlLabel . get _style _context ( ) . add _class ( "dim-label" ) ;
controlBox . pack _start ( controlLabel , true , true , 4 ) ;
listBox . add ( controlBox ) ;
2019-03-05 17:08:43 -03:00
let smoothBox = new Gtk . Box ( { margin : MARGIN } ) ;
let smoothLabelBox = new Gtk . Box ( { orientation : Gtk . Orientation . VERTICAL } ) ;
let smoothLabel1 = new Gtk . Label ( { label : _ ( "Smooth stroke during the drawing process" ) } ) ;
let smoothLabel2 = new Gtk . Label ( { use _markup : true , halign : 1 , label : "<small>" + _ ( "You can smooth the stroke afterward\nSee" ) + " \"" + _ ( "Smooth last brushstroke" ) + "\"</small>" } ) ;
smoothLabel1 . set _halign ( 1 ) ;
smoothLabel2 . get _style _context ( ) . add _class ( "dim-label" ) ;
smoothLabelBox . pack _start ( smoothLabel1 , true , true , 0 ) ;
smoothLabelBox . pack _start ( smoothLabel2 , true , true , 0 ) ;
let smoothSwitch = new Gtk . Switch ( { valign : 3 } ) ;
this . settings . bind ( "smoothed-stroke" , smoothSwitch , "active" , 0 ) ;
smoothBox . pack _start ( smoothLabelBox , true , true , 4 ) ;
smoothBox . pack _start ( smoothSwitch , false , false , 4 ) ;
listBox . add ( smoothBox ) ;
2019-03-05 08:36:59 -03:00
let internalKeybindingsWidget = new KeybindingsWidget ( INTERNAL _KEYBINDINGS , this . settings ) ;
internalKeybindingsWidget . margin = MARGIN ;
listBox . add ( internalKeybindingsWidget ) ;
let styleBox = new Gtk . Box ( { margin _top : MARGIN , margin _left : MARGIN , margin _right : MARGIN , margin _bottom : MARGIN } ) ;
let styleLabel = new Gtk . Label ( { label : _ ( "Change the style" ) } ) ;
styleLabel . set _halign ( 1 ) ;
let styleLabel2 = new Gtk . Label ( { label : _ ( "See stylesheet.css" ) } ) ;
styleBox . pack _start ( styleLabel , true , true , 4 ) ;
styleBox . pack _start ( styleLabel2 , false , false , 4 ) ;
listBox . add ( styleBox ) ;
let noteBox = new Gtk . Box ( { margin _top : MARGIN , margin _left : MARGIN , margin _right : MARGIN , margin _bottom : MARGIN } ) ;
let noteLabel = new Gtk . Label ( {
use _markup : true ,
2019-03-07 10:28:35 -03:00
label : _ ( "<u>Note</u>: When you save elements made with <b>eraser</b> in a <b>SVG</b> file,\nthey are colored with background color, transparent if it is disabled.\n(See \"Add a drawing background\" or edit the SVG file afterwards)" )
2019-03-05 08:36:59 -03:00
} ) ;
noteLabel . set _halign ( 1 ) ;
2019-03-07 10:28:35 -03:00
noteLabel . get _style _context ( ) . add _class ( "dim-label" ) ;
2019-03-05 08:36:59 -03:00
noteBox . pack _start ( noteLabel , true , true , 4 ) ;
listBox . add ( noteBox ) ;
this . addSeparator ( listBox ) ;
let licence = _ ( "<span size=\"small\">This program comes with ABSOLUTELY NO WARRANTY.\nSee the <a href=\"https://www.gnu.org/licenses/old-licenses/gpl-2.0.html\">GNU General Public License, version 2 or later</a> for details.</span>" ) ;
let textBox2 = new Gtk . Box ( { orientation : Gtk . Orientation . VERTICAL } ) ;
let text2 = new Gtk . Label ( { wrap : true , justify : 2 , use _markup : true ,
label : "<small>Version" + " " + Metadata . version + "</small>\n\n" + "<span><a href=\"" + Metadata . url + "\">" + Metadata . url + "</a></span>" + "\n\n" + licence + "\n" } ) ;
textBox2 . pack _start ( text2 , false , false , 0 ) ;
let creditBox = new Gtk . Box ( { orientation : Gtk . Orientation . HORIZONTAL } ) ;
let leftBox = new Gtk . Box ( { orientation : Gtk . Orientation . VERTICAL } ) ;
let rightBox = new Gtk . Box ( { orientation : Gtk . Orientation . VERTICAL } ) ;
let leftLabel = new Gtk . Label ( { wrap : true , valign : 1 , halign : 2 , justify : 1 , use _markup : true , label : "<small><u>" + _ ( "Credits" ) + ":</u></small>" } ) ;
let rightLabel = new Gtk . Label ( { wrap : true , valign : 1 , halign : 1 , justify : 0 , use _markup : true , label : "<small>Abakkk</small>" } ) ;
leftBox . pack _start ( leftLabel , true , true , 0 ) ;
rightBox . pack _start ( rightLabel , true , true , 0 ) ;
creditBox . pack _start ( leftBox , true , true , 5 ) ;
creditBox . pack _start ( rightBox , true , true , 5 ) ;
textBox2 . pack _start ( creditBox , false , false , 0 ) ;
box . add ( textBox2 ) ;
let children = listBox . get _children ( ) ;
for ( let i = 0 ; i < children . length ; i ++ ) {
if ( children [ i ] . activatable )
children [ i ] . set _activatable ( false ) ;
}
} ,
addSeparator : function ( container ) {
let separatorRow = new Gtk . ListBoxRow ( { sensitive : false } ) ;
separatorRow . add ( new Gtk . Separator ( { margin : MARGIN } ) ) ;
container . add ( separatorRow ) ;
}
} ) ;
// this code comes from Sticky Notes View by Sam Bull, https://extensions.gnome.org/extension/568/notes/
const KeybindingsWidget = new GObject . Class ( {
Name : 'Keybindings.Widget' ,
GTypeName : 'KeybindingsWidget' ,
Extends : Gtk . Box ,
_init : function ( keybindings , settings ) {
this . parent ( ) ;
this . set _orientation ( Gtk . Orientation . VERTICAL ) ;
this . _keybindings = keybindings ;
this . _settings = settings ;
this . _columns = {
NAME : 0 ,
ACCEL _NAME : 1 ,
MODS : 2 ,
KEY : 3
} ;
this . _store = new Gtk . ListStore ( ) ;
this . _store . set _column _types ( [
GObject . TYPE _STRING ,
GObject . TYPE _STRING ,
GObject . TYPE _INT ,
GObject . TYPE _INT
] ) ;
this . _tree _view = new Gtk . TreeView ( {
model : this . _store ,
hexpand : false ,
vexpand : false
} ) ;
this . _tree _view . set _activate _on _single _click ( false ) ;
this . _tree _view . get _selection ( ) . set _mode ( Gtk . SelectionMode . SINGLE ) ;
let action _renderer = new Gtk . CellRendererText ( ) ;
let action _column = new Gtk . TreeViewColumn ( {
title : "" ,
expand : true ,
} ) ;
action _column . pack _start ( action _renderer , true ) ;
action _column . add _attribute ( action _renderer , 'text' , 1 ) ;
this . _tree _view . append _column ( action _column ) ;
let keybinding _renderer = new Gtk . CellRendererAccel ( {
editable : true ,
accel _mode : Gtk . CellRendererAccelMode . GTK ,
xalign : 1
} ) ;
keybinding _renderer . connect ( 'accel-edited' ,
Lang . bind ( this , function ( renderer , iter , key , mods ) {
let value = Gtk . accelerator _name ( key , mods ) ;
let [ success , iterator ] =
this . _store . get _iter _from _string ( iter ) ;
if ( ! success ) {
printerr ( "Can't change keybinding" ) ;
}
let name = this . _store . get _value ( iterator , 0 ) ;
this . _store . set (
iterator ,
[ this . _columns . MODS , this . _columns . KEY ] ,
[ mods , key ]
) ;
this . _settings . set _strv ( name , [ value ] ) ;
} )
) ;
let keybinding _column = new Gtk . TreeViewColumn ( {
title : "" ,
} ) ;
keybinding _column . pack _end ( keybinding _renderer , false ) ;
keybinding _column . add _attribute (
keybinding _renderer ,
'accel-mods' ,
this . _columns . MODS
) ;
keybinding _column . add _attribute (
keybinding _renderer ,
'accel-key' ,
this . _columns . KEY
) ;
this . _tree _view . append _column ( keybinding _column ) ;
this . _tree _view . columns _autosize ( ) ;
this . _tree _view . set _headers _visible ( false ) ;
this . add ( this . _tree _view ) ;
this . keybinding _column = keybinding _column ;
this . action _column = action _column ;
this . _refresh ( ) ;
} ,
_refresh : function ( ) {
this . _store . clear ( ) ;
for ( let settings _key in this . _keybindings ) {
if ( settings _key . indexOf ( '-separator-' ) != - 1 )
continue ;
let [ key , mods ] = Gtk . accelerator _parse (
this . _settings . get _strv ( settings _key ) [ 0 ]
) ;
let iter = this . _store . append ( ) ;
this . _store . set ( iter ,
[
this . _columns . NAME ,
this . _columns . ACCEL _NAME ,
this . _columns . MODS ,
this . _columns . KEY
] ,
[
settings _key ,
_ ( this . _keybindings [ settings _key ] ) ,
mods ,
key
]
) ;
}
}
} ) ;