mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-30 02:40:08 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			696 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			696 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
| /**********************************************************************
 | |
| * 
 | |
| *
 | |
| *
 | |
| **********************************************************************/
 | |
| ((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
 | |
| (function(require){ var module={} // make module AMD/node compatible...
 | |
| /*********************************************************************/
 | |
| 
 | |
| if(typeof(process) != 'undefined'){
 | |
| 	var pathlib = requirejs('path')
 | |
| 	var url = requirejs('url')
 | |
| }
 | |
| 
 | |
| var electron
 | |
| try{
 | |
| 	electron = requirejs('electron')
 | |
| } catch(e){ }
 | |
| 
 | |
| var VERSION = require('version').version
 | |
| 
 | |
| var actions = require('lib/actions')
 | |
| var features = require('lib/features')
 | |
| var toggler = require('lib/toggler')
 | |
| 
 | |
| var core = require('features/core')
 | |
| var base = require('features/base')
 | |
| var widgets = require('features/ui-widgets')
 | |
| 
 | |
| 
 | |
| 
 | |
| /*********************************************************************/
 | |
| 
 | |
| var Widget = 
 | |
| module.Widget = core.ImageGridFeatures.Feature({
 | |
| 	title: '',
 | |
| 	doc: '',
 | |
| 
 | |
| 	tag: 'widget',
 | |
| 	depends: [
 | |
| 		'-ui-app-control',
 | |
| 	],
 | |
| })
 | |
| 
 | |
| 
 | |
| //---------------------------------------------------------------------
 | |
| 
 | |
| var NWHostActions = actions.Actions({
 | |
| 	// window stuff...
 | |
| 	// XXX should this be nested in a .window object???
 | |
| 	get title(){
 | |
| 		return nw.Window.get().title },
 | |
| 	set title(value){
 | |
| 		nw.Window.get().title = value },
 | |
| 	get size(){
 | |
| 		var win = nw.Window.get()
 | |
| 		return [
 | |
| 			win.width,
 | |
| 			win.height,
 | |
| 		]
 | |
| 	},
 | |
| 	set size(value){
 | |
| 		var win = nw.Window.get()
 | |
| 		win.width = value[0]
 | |
| 		win.height = value[1]
 | |
| 	},
 | |
| 	get position(){
 | |
| 		var win = nw.Window.get()
 | |
| 		return [
 | |
| 			win.x,
 | |
| 			win.y,
 | |
| 		]
 | |
| 	},
 | |
| 	set position(value){
 | |
| 		var win = nw.Window.get()
 | |
| 		win.x = value[0]
 | |
| 		win.y = value[1]
 | |
| 	},
 | |
| 
 | |
| 	show: ['- Window/',
 | |
| 		function(){
 | |
| 			nw.Window.get().show() }],
 | |
| 	minimize: ['Window/Minimize',
 | |
| 		function(){
 | |
| 			nw.Window.get().minimize() }],
 | |
| 	toggleFullScreen: ['Window/Full screen mode',
 | |
| 		toggler.CSSClassToggler(
 | |
| 			function(){ return document.body }, 
 | |
| 			'.full-screen-mode',
 | |
| 			function(action){
 | |
| 				var that = this
 | |
| 				var w = nw.Window.get()
 | |
| 
 | |
| 				// change the state only if the target state is not the same
 | |
| 				// as the current state...
 | |
| 				if((w.isFullscreen ? 'on' : 'off') != action){
 | |
| 					this.ribbons.preventTransitions()
 | |
| 
 | |
| 					// hide the viewer to hide any animation crimes...
 | |
| 					this.dom[0].style.visibility = 'hidden'
 | |
| 
 | |
| 					// XXX async...
 | |
| 					// 		...this complicates things as we need to do the next
 | |
| 					// 		bit AFTER the resize is done...
 | |
| 					w.toggleFullscreen()
 | |
| 
 | |
| 					setTimeout(function(){ 
 | |
| 						that
 | |
| 							.centerViewer()
 | |
| 							.focusImage()
 | |
| 							.ribbons
 | |
| 								.restoreTransitions()
 | |
| 
 | |
| 						that.dom[0].style.visibility = ''
 | |
| 					}, 100)
 | |
| 				}
 | |
| 
 | |
| 				// NOTE: we delay this to account for window animation...
 | |
| 				setTimeout(function(){ 
 | |
| 					that.storeWindowGeometry() 
 | |
| 				}, 500)
 | |
| 			})],
 | |
| 
 | |
| 	// XXX add ability to use devtools on background page (node context)...
 | |
| 	// XXX get the devtools stage...
 | |
| 	showDevTools: ['Interface|Development/Show Dev Tools',
 | |
| 		function(action){
 | |
| 			if(action == '?'){
 | |
| 				// XXX get the devtools stage...
 | |
| 				return false
 | |
| 			}
 | |
| 			nw.Window.get().showDevTools &&
 | |
| 				nw.Window.get().showDevTools()
 | |
| 		}],
 | |
| 	showInFolder: ['File|Image/Show in $folder',
 | |
| 		function(image){
 | |
| 			image = this.images[this.data.getImage(image)]
 | |
| 
 | |
| 			var base = image.base_path || this.location.path
 | |
| 			var filename = image.path
 | |
| 			var path = pathlib.normalize(base + '/' + filename)
 | |
| 
 | |
| 			nw.Shell.showItemInFolder(path)
 | |
| 		}],
 | |
| 
 | |
| 	toggleSplashScreen: ['Interface/',
 | |
| 		function(){
 | |
| 		}],
 | |
| })
 | |
| 
 | |
| var NWHost = 
 | |
| module.NWHost = core.ImageGridFeatures.Feature({
 | |
| 	title: '',
 | |
| 	doc: '',
 | |
| 
 | |
| 	tag: 'ui-nw-host',
 | |
| 	exclusive: 'ui-host',
 | |
| 	depends: [],
 | |
| 
 | |
| 	actions: NWHostActions,
 | |
| 
 | |
| 	isApplicable: function(){ return this.runtime.nw },
 | |
| })
 | |
| 
 | |
| 
 | |
| 
 | |
| //---------------------------------------------------------------------
 | |
| 
 | |
| var ElectronHostActions = actions.Actions({
 | |
| 	// window stuff...
 | |
| 	// XXX should this be nested in a .window object???
 | |
| 	// XXX should these be props or methods???
 | |
| 	get title(){
 | |
| 		return electron.remote.getCurrentWindow().getTitle() },
 | |
| 	set title(value){
 | |
| 		electron.remote.getCurrentWindow().setTitle(value) },
 | |
| 	get size(){
 | |
| 		return electron.remote.getCurrentWindow().getSize() },
 | |
| 	set size(value){
 | |
| 		value 
 | |
| 			&& electron.remote.getCurrentWindow()
 | |
| 				.setSize(Math.round(value[0]), Math.round(value[1])) },
 | |
| 	get position(){
 | |
| 		return electron.remote.getCurrentWindow().getPosition() },
 | |
| 	set position(value){
 | |
| 		value 
 | |
| 			&& electron.remote.getCurrentWindow()
 | |
| 				.setPosition(Math.round(value[0]), Math.round(value[1])) },
 | |
| 
 | |
| 	show: ['- Window/',
 | |
| 		function(){
 | |
| 			if(electron.remote.getGlobal('readyToShow')){
 | |
| 				electron.remote.getCurrentWindow().show()
 | |
| 
 | |
| 			} else {
 | |
| 				var win = electron.remote.getCurrentWindow()
 | |
| 				win.once('ready-to-show', function(){
 | |
| 					win.show()
 | |
| 				})
 | |
| 			}
 | |
| 		}],
 | |
| 	minimize: ['Window/Minimize',
 | |
| 		function(){
 | |
| 			electron.remote.getCurrentWindow().minimize() }],
 | |
| 	toggleFullScreen: ['Window/Full screen mode',
 | |
| 		toggler.CSSClassToggler(
 | |
| 			function(){ return document.body }, 
 | |
| 			'.full-screen-mode',
 | |
| 			function(action){
 | |
| 				var that = this
 | |
| 				var win = electron.remote.getCurrentWindow()
 | |
| 
 | |
| 				var state = win.isFullScreen() ? 'on' : 'off'
 | |
| 
 | |
| 				// change the state only if the target state is not the same
 | |
| 				// as the current state...
 | |
| 				if(state != action){
 | |
| 					this.ribbons.preventTransitions()
 | |
| 
 | |
| 					// hide the viewer to hide any animation crimes...
 | |
| 					this.dom[0].style.visibility = 'hidden'
 | |
| 
 | |
| 					// XXX async...
 | |
| 					// 		...this complicates things as we need to do the next
 | |
| 					// 		bit AFTER the resize is done...
 | |
| 					win.setFullScreen(action == 'on' ? true : false)
 | |
| 
 | |
| 					setTimeout(function(){ 
 | |
| 						that
 | |
| 							.centerViewer()
 | |
| 							.focusImage()
 | |
| 							.ribbons
 | |
| 								.restoreTransitions()
 | |
| 
 | |
| 						that.dom[0].style.visibility = ''
 | |
| 					}, 100)
 | |
| 				}
 | |
| 
 | |
| 				// NOTE: we delay this to account for window animation...
 | |
| 				setTimeout(function(){ 
 | |
| 					that.storeWindowGeometry() 
 | |
| 				}, 500)
 | |
| 			})],
 | |
| 
 | |
| 	// XXX should this be a toggler???
 | |
| 	showDevTools: ['Interface|Development/Show Dev Tools',
 | |
| 		function(action){
 | |
| 			var w = electron.remote.getCurrentWindow()
 | |
| 
 | |
| 			if(action == '?'){
 | |
| 				return w.isDevToolsOpened()
 | |
| 			}
 | |
| 				
 | |
| 			w.openDevTools() 
 | |
| 			// focus the devtools if its window is available...
 | |
| 			w.devToolsWebContents
 | |
| 				&& w.devToolsWebContents.focus()
 | |
| 		}],
 | |
| 	// XXX make this portable (osx, linux)...
 | |
| 	showInFolder: ['File|Image/Show in $folder',
 | |
| 		function(image){
 | |
| 			image = this.images[this.data.getImage(image)]
 | |
| 
 | |
| 			var base = image.base_path || this.location.path
 | |
| 			var filename = image.path
 | |
| 			var path = pathlib.normalize(base + '/' + filename)
 | |
| 
 | |
| 			requirejs('child_process')
 | |
| 				// XXX this is windows-specific...
 | |
| 				.exec(`explorer.exe /select,"${ pathlib.normalize(path) }"`)
 | |
| 				// XXX osx...
 | |
| 				//.exec('open -R '+JSON.stringify(path))
 | |
| 		}],
 | |
| 
 | |
| 	// XXX make this a real toggler...
 | |
| 	toggleSplashScreen: ['Interface/',
 | |
| 		function(action){
 | |
| 			var splash = this.splash = (!this.splash || this.splash.isDestroyed()) ?
 | |
| 				electron.remote.getGlobal('splash')
 | |
| 				: this.splash
 | |
| 
 | |
| 			if(action == '?'){
 | |
| 				return !splash || splash.isDestroyed() ? 'off' : 'on'
 | |
| 			}
 | |
| 
 | |
| 			// XXX HACK: use real toggler protocol...
 | |
| 			if(action != 'off' && (!splash || splash.isDestroyed())){
 | |
| 				var splash = this.splash = 
 | |
| 					// XXX move this to splash.js and use both here and in e.js...
 | |
| 					new electron.remote.BrowserWindow({
 | |
| 						// let the window to get ready before we show it to the user...
 | |
| 						show: false,
 | |
| 
 | |
| 						transparent: true,
 | |
| 						frame: false,
 | |
| 						center: true,
 | |
| 						width: 800, 
 | |
| 						height: 500,
 | |
| 
 | |
| 						alwaysOnTop: true,
 | |
| 
 | |
| 						resizable: false,
 | |
| 						movable: false,
 | |
| 						minimizable: false,
 | |
| 						maximizable: false,
 | |
| 						fullscreenable: false,
 | |
| 
 | |
| 						autoHideMenuBar: true,
 | |
| 					})
 | |
| 
 | |
| 				splash.setMenu(null)
 | |
| 
 | |
| 				// and load the index.html of the app.
 | |
| 				splash.loadURL(url.format({
 | |
| 					// XXX unify this with index.html
 | |
| 					pathname: pathlib.join(__dirname, 'splash.html'),
 | |
| 					protocol: 'file:',
 | |
| 					slashes: true
 | |
| 				}))
 | |
| 				
 | |
| 				splash.once('ready-to-show', function(){
 | |
| 					splash.webContents
 | |
| 						.executeJavaScript(
 | |
| 							`document.getElementById("version").innerText = "${VERSION}"`)
 | |
| 					splash.show()
 | |
| 				})
 | |
| 
 | |
| 			} else if(action != 'on' && splash){
 | |
| 				splash.destroy()
 | |
| 			}
 | |
| 		}],
 | |
| })
 | |
| 
 | |
| var ElectronHost = 
 | |
| module.ElectronHost = core.ImageGridFeatures.Feature({
 | |
| 	title: '',
 | |
| 	doc: '',
 | |
| 
 | |
| 	tag: 'ui-electron-host',
 | |
| 	exclusive: 'ui-host',
 | |
| 	depends: [],
 | |
| 
 | |
| 	actions: ElectronHostActions,
 | |
| 
 | |
| 	isApplicable: function(){ return this.runtime.electron },
 | |
| })
 | |
| 
 | |
| 
 | |
| 
 | |
| //---------------------------------------------------------------------
 | |
| // XXX this needs to trigger only when fullwindow browser mode and not 
 | |
| // 		get loaded when in widget mode...
 | |
| 
 | |
| var BrowserHostActions = actions.Actions({
 | |
| 	// window stuff...
 | |
| 	get title(){
 | |
| 		return $('title').text() },
 | |
| 	set title(value){
 | |
| 		$('title').text(value) },
 | |
| })
 | |
| 
 | |
| // NOTE: keep this defined last as a fallback...
 | |
| var BrowserHost = 
 | |
| module.BrowserHost = core.ImageGridFeatures.Feature({
 | |
| 	title: '',
 | |
| 	doc: '',
 | |
| 
 | |
| 	tag: 'ui-browser-host',
 | |
| 	exclusive: 'ui-host',
 | |
| 	depends: [],
 | |
| 
 | |
| 	actions: BrowserHostActions,
 | |
| 
 | |
| 	isApplicable: function(){ return !this.runtime.widget },
 | |
| })
 | |
| 
 | |
| 
 | |
| //---------------------------------------------------------------------
 | |
| 
 | |
| var PortableAppControl = 
 | |
| module.PortableAppControl = core.ImageGridFeatures.Feature({
 | |
| 	title: '',
 | |
| 	doc: '',
 | |
| 
 | |
| 	tag: 'ui-portable-app-control',
 | |
| 	depends: [
 | |
| 		'ui',
 | |
| 		'ui-host',
 | |
| 	],
 | |
| 
 | |
| 	isApplicable: function(){ return this.runtime.browser },
 | |
| 
 | |
| 	config: {
 | |
| 		//'window-title': 'ImageGrid.Viewer (${VERSION}): ${FILENAME}',
 | |
| 		'window-title': '${FILENAME} - ImageGrid.Viewer (${VERSION})',
 | |
| 
 | |
| 	},
 | |
| 
 | |
| 	handlers: [
 | |
| 		// update window title...
 | |
| 		// XXX make this generic...
 | |
| 		['focusImage clear',
 | |
| 			function(){
 | |
| 				if(this.images){
 | |
| 					var img = this.images[this.current]
 | |
| 					this.title = (this.config['window-title'] 
 | |
| 							|| 'ImageGrid.Viewer (${VERSION}): ${FILENAME}')
 | |
| 						// XXX get this from the viewer...
 | |
| 						.replace('${VERSION}', this.version || 'gen4')
 | |
| 						.replace('${FILENAME}', 
 | |
| 							img ? 
 | |
| 									(img.name 
 | |
| 										|| (img.path && img.path.replace(/\.[\\\/]/, ''))
 | |
| 										|| this.current
 | |
| 										|| '')
 | |
| 								: (this.current || ''))
 | |
| 						.replace('${PATH}', 
 | |
| 							(img && img.path) ?
 | |
| 									(img.base_path || '.') 
 | |
| 										+'/'+ img.path.replace(/\.[\\\/]/, '')
 | |
| 								: '')
 | |
| 						/*
 | |
| 						.replace('${DIR}', 
 | |
| 							pathlib.dirname((img.base_path || '.') 
 | |
| 								+'/'+ img.path.replace(/\.[\\\/]/, '')))
 | |
| 						*/
 | |
| 						// XXX add ...
 | |
| 				}
 | |
| 			}],
 | |
| 	],
 | |
| })
 | |
| 
 | |
| 
 | |
| //---------------------------------------------------------------------
 | |
| 
 | |
| // XXX should we create and show the window here???
 | |
| // 		...if yes, then we'll need to start the ui features later as 
 | |
| // 		they need the dom ready...
 | |
| var WindowedAppControlActions = actions.Actions({
 | |
| 	config: {
 | |
| 		// Window state:
 | |
| 		// 'window': {
 | |
| 		// 		width: <number>,
 | |
| 		// 		height: <number>,
 | |
| 		// 		x: <number>,
 | |
| 		// 		y: <number>,
 | |
| 		//
 | |
| 		// 		fullscreen: <bool>,
 | |
| 		//
 | |
| 		// 		devtools: <bool>,
 | |
| 		// },
 | |
| 
 | |
| 		'window-delay-initial-display': 500,
 | |
| 		'splash-screen-delay-hide': 500,
 | |
| 
 | |
| 		'show-splash-screen': 'on',
 | |
| 	},
 | |
| 
 | |
| 	close: ['File|Window/Close viewer',
 | |
| 		function(){ 
 | |
| 			this.stop()
 | |
| 			window.close() 
 | |
| 		}],
 | |
| 
 | |
| 	storeWindowGeometry: ['- Window/Store window state',
 | |
| 		function(){
 | |
| 			// store window parameters (size, state)...
 | |
| 			//var win = nw.Window.get()
 | |
| 			var size = this.size
 | |
| 			var position = this.position
 | |
| 
 | |
| 			// fullscreen...
 | |
| 			// ...avoid overwriting size...
 | |
| 			if(this.toggleFullScreen('?') == 'on'){
 | |
| 				// NOTE: this needs to be rewritten to correctly get stored
 | |
| 				// 		in the config store, especially if a default state
 | |
| 				// 		is defined...
 | |
| 				var cfg = this.config.window = this.config.window || {}
 | |
| 				cfg.fullscreen = true
 | |
| 				cfg.devtools = this.showDevTools('?')
 | |
| 
 | |
| 			} else {
 | |
| 				this.config.window = {
 | |
| 					width: size[0],
 | |
| 					height: size[1],
 | |
| 
 | |
| 					x: position[0],
 | |
| 					y: position[1],
 | |
| 
 | |
| 					fullscreen: false,
 | |
| 					devtools: this.showDevTools('?'),
 | |
| 				}
 | |
| 			}
 | |
| 		}],
 | |
| 	restoreWindowGeometry: ['- Window/Restore window state',
 | |
| 		function(){
 | |
| 			var that = this
 | |
| 			var cfg = this.config.window || {}
 | |
| 
 | |
| 			var fullscreen = cfg.fullscreen || false
 | |
| 
 | |
| 			if(fullscreen){
 | |
| 				that.toggleFullScreen('on')
 | |
| 
 | |
| 			} else {
 | |
| 				var w = cfg.width || 800
 | |
| 				var h = cfg.height || 600 
 | |
| 				var x = cfg.x || (screen.width - w)/2
 | |
| 				var y = cfg.y || (screen.height - h)/2
 | |
| 
 | |
| 				this.position = [x, y]
 | |
| 				this.size = [w, h]
 | |
| 			}
 | |
| 		}],
 | |
| 
 | |
| 	toggleSplashScreenShowing: ['Interface/Splash screen on start',
 | |
| 		core.makeConfigToggler('show-splash-screen', 
 | |
| 			['on', 'off'],
 | |
| 			function(action){
 | |
| 				if(action == 'on'){
 | |
| 					delete localStorage.disableSplashScreen
 | |
| 
 | |
| 				} else if(action == 'off'){
 | |
| 					localStorage.disableSplashScreen = true
 | |
| 				}
 | |
| 			})],
 | |
| })
 | |
| 
 | |
| var WindowedAppControl = 
 | |
| module.WindowedAppControl = core.ImageGridFeatures.Feature({
 | |
| 	title: '',
 | |
| 	doc: '',
 | |
| 
 | |
| 	tag: 'ui-windowed-app-control',
 | |
| 	depends: [
 | |
| 		'ui',
 | |
| 		'ui-host',
 | |
| 	],
 | |
| 
 | |
| 	actions: WindowedAppControlActions,
 | |
| 
 | |
| 	// XXX BUG: when running in electron:
 | |
| 	// 			- loading this breaks the other buttons (menu, collections, ...)
 | |
| 	// 			- .toggleFullScreen(..) works in an odd manner -- ok when 
 | |
| 	// 				explicitly called or button pushed but in opposite manner 
 | |
| 	// 				when F11 (FIXED?)
 | |
| 	// 			- ready protocol breaks -- need to call .ready() to unstall 
 | |
| 	// 				the viewer
 | |
| 	// 		...does this all have anything to do with double init???
 | |
| 	isApplicable: function(){ return this.runtime.desktop },
 | |
| 	//isApplicable: function(){ return this.runtime.desktop && !this.runtime.electron },
 | |
| 
 | |
| 	// XXX show main window...
 | |
| 	handlers: [
 | |
| 		['start.pre',
 | |
| 			function(){ 
 | |
| 				// we are going to declare ready ourselves...
 | |
| 				this.requestReadyAnnounce() }],
 | |
| 		// XXX should we create and show the window here???
 | |
| 		['start',
 | |
| 			function(){ 
 | |
| 				var that = this
 | |
| 				var cfg = this.config.window
 | |
| 
 | |
| 				// set the initial non-fullscreen window geometry...
 | |
| 				// NOTE: this will avoid overwriting the initial geometry
 | |
| 				// 		with the values set in e.js if .fullscreen is set...
 | |
| 				// NOTE: this will also set the size to which the OS will 
 | |
| 				// 		resize the window in state change...
 | |
| 				if(cfg){
 | |
| 					var W = screen.width
 | |
| 					var H = screen.height
 | |
| 					var w = cfg.width || Math.max(0.8 * W, 600)
 | |
| 					var h = cfg.height || Math.max(0.8 * H, 400)
 | |
| 					var x = cfg.x || (W - w)/2
 | |
| 					var y = cfg.y || (H - h)/2
 | |
| 
 | |
| 					this.position = [x, y]
 | |
| 					this.size = [w, h]
 | |
| 
 | |
| 					cfg.devtools
 | |
| 						&& this.showDevTools()
 | |
| 				}
 | |
| 
 | |
| 				// restore actual window state... 
 | |
| 				this.restoreWindowGeometry() 
 | |
| 
 | |
| 				// declare we are ready when DOM is ready...
 | |
| 				$(function(){ 
 | |
| 					that.declareReady() })
 | |
| 			}],
 | |
| 
 | |
| 		// show window + hide splash screen...
 | |
| 		['ready',
 | |
| 			function(){ 
 | |
| 				var that = this
 | |
| 				// NOTE: we delay this to enable the browser time to render
 | |
| 				// 		things before we show them to the user...
 | |
| 				setTimeout(function(){
 | |
| 					// show window...
 | |
| 					that.show()
 | |
| 
 | |
| 					// hide splash screen...
 | |
| 					setTimeout(function(){
 | |
| 						that.toggleSplashScreen('off')
 | |
| 					}, (that.config['splash-screen-delay-hide'] || 0)) 
 | |
| 				}, this.config['window-delay-initial-display'] || 0) }],
 | |
| 
 | |
| 		[[
 | |
| 			'stop.pre',
 | |
| 			'toggleFullScreen.pre',
 | |
| 			'toggleFullScreen',
 | |
| 		],
 | |
| 			function(){ this.storeWindowGeometry() }],
 | |
| 	],
 | |
| })
 | |
| 
 | |
| 
 | |
| //---------------------------------------------------------------------
 | |
| 
 | |
| var AppControl = 
 | |
| module.AppControl = core.ImageGridFeatures.Feature('ui-app-control', [
 | |
| 	'ui-windowed-app-control',
 | |
| 	'ui-portable-app-control',
 | |
| ])
 | |
| 
 | |
| 
 | |
| //---------------------------------------------------------------------
 | |
| // Fullscreen app control buttons...
 | |
| 
 | |
| var AppButtonsActions = actions.Actions({
 | |
| 	config: {
 | |
| 		// append app-specific buttons...
 | |
| 		'app-buttons': Object.assign({},
 | |
| 			widgets.Buttons.actions.config['app-buttons'],
 | |
| 			{
 | |
| 				'_': ['minimize', 
 | |
| 					'minimize -- Minimize'],
 | |
| 				'↙': ['fullscreen always-shown', 
 | |
| 					'toggleFullScreen -- Toggle fullscreen'],
 | |
| 				'×': ['close', 
 | |
| 					'close -- Quit'],
 | |
| 			}),
 | |
| 	},
 | |
| })
 | |
| 
 | |
| var AppButtons = 
 | |
| module.AppButtons = core.ImageGridFeatures.Feature({
 | |
| 	title: '',
 | |
| 	doc: '',
 | |
| 
 | |
| 	tag: 'ui-app-buttons',
 | |
| 	depends: [
 | |
| 		'ui-windowed-app-control',
 | |
| 		'ui-buttons',
 | |
| 	],
 | |
| 	suggested: [
 | |
| 		// needed for reporting info in .makeButtonControls(..)
 | |
| 		'ui-status-bar',
 | |
| 	],
 | |
| 
 | |
| 	actions: AppButtonsActions,
 | |
| 
 | |
| 	handlers: [
 | |
| 		['start.pre', 
 | |
| 			function(){
 | |
| 				this.toggleAppButtons('on')
 | |
| 			}],
 | |
| 		['start toggleFullScreen', 
 | |
| 			function(){
 | |
| 				var fullscreen = this.toggleFullScreen('?')
 | |
| 				var buttons = this.dom.find('.app-buttons')
 | |
| 				
 | |
| 				// fullscreen button...
 | |
| 				buttons.find('.fullscreen.button')
 | |
| 					.html(fullscreen == 'on' ? '↙' : '↗')
 | |
| 					.attr('info', fullscreen == 'on' ? 'Exit fullscreen' : 'Fullscreen')
 | |
| 
 | |
| 				// XXX should this be done by css???
 | |
| 				if(fullscreen == 'on'){
 | |
| 					buttons.find('.button:not(.always-shown)').show()
 | |
| 
 | |
| 				} else {
 | |
| 					buttons.find('.button:not(.always-shown)').hide()
 | |
| 				}
 | |
| 
 | |
| 				//this.toggleFullScreenControls(fullScreen)
 | |
| 			}],
 | |
| 	],
 | |
| })
 | |
| 
 | |
| 
 | |
| 
 | |
| /**********************************************************************
 | |
| * vim:set ts=4 sw=4 :                               */ return module })
 |