mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-11-03 04:40:10 +00:00
some basic theaming and some refactoring...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
235b51727e
commit
2b076e499c
@ -1,12 +1,15 @@
|
|||||||
|
|
||||||
|
/********************************************************** Widget ***/
|
||||||
.browse {
|
.browse {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
width: initial;
|
width: initial;
|
||||||
background: gray;
|
|
||||||
color: rgba(255,255,255,0.8);
|
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
|
||||||
|
background: gray;
|
||||||
|
/*color: rgba(255,255,255,0.8);*/
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
.browse:not(:focus) {
|
.browse:not(:focus) {
|
||||||
@ -18,11 +21,9 @@
|
|||||||
height: auto;
|
height: auto;
|
||||||
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
border-top: 1px solid rgba(255,255,255, 0.3);
|
|
||||||
}
|
}
|
||||||
.browse .v-block:first-of-type {
|
.browse .v-block:not(:first-of-type) {
|
||||||
border-top: none;
|
border-top: 1px solid rgba(255, 255, 255, 0.3);
|
||||||
}
|
}
|
||||||
.browse .v-block:empty {
|
.browse .v-block:empty {
|
||||||
display: none;
|
display: none;
|
||||||
@ -30,21 +31,18 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
.browse .title {
|
/************************************************************ Path ***/
|
||||||
font-weight: bold;
|
|
||||||
color: rgba(255,255,255,0.9);
|
|
||||||
padding: 5px;
|
|
||||||
padding-left: 10px;
|
|
||||||
padding-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.browse .path {
|
.browse .path {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
.browse .path:hover {
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
||||||
.browse .path:empty {
|
.browse .path:empty {
|
||||||
display: block;
|
display: block;
|
||||||
@ -90,6 +88,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************ List ***/
|
||||||
|
|
||||||
/* XXX need to make this resizable up but only to a certain size (~80vh) */
|
/* XXX need to make this resizable up but only to a certain size (~80vh) */
|
||||||
.browse .list {
|
.browse .list {
|
||||||
/* XXX need a way to make this automatic and depend on .browser
|
/* XXX need a way to make this automatic and depend on .browser
|
||||||
@ -112,13 +112,25 @@
|
|||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
.browse:focus .list div.selected,
|
.browse:focus .list div.selected,
|
||||||
.browse .path .dir:hover,
|
.browse .path .dir:hover,
|
||||||
.browse .list div:hover {
|
.browse .list div:hover {
|
||||||
color: white;
|
background: rgba(0, 0, 0, 0.05);
|
||||||
background: rgba(0,0,0, 0.05);
|
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
.browse .list div.selected {
|
||||||
|
background: rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
.browse:focus .list div.selected {
|
||||||
|
background: rgba(0, 0, 0, 0.08);
|
||||||
|
box-shadow: rgba(0, 0, 0, 0.2) 0.1em 0.1em 0.2em;
|
||||||
|
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX need to make the next two different... */
|
/* XXX need to make the next two different... */
|
||||||
@ -132,11 +144,39 @@
|
|||||||
opacity: 0.3;
|
opacity: 0.3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.browse:focus .list div.selected {
|
|
||||||
background: rgba(0,0,0, 0.1);
|
|
||||||
box-shadow: rgba(0,0,0,0.2) 0.1em 0.1em 0.2em;
|
/******************************************************** Theaming ***/
|
||||||
|
|
||||||
|
/* Light */
|
||||||
|
.light .browse {
|
||||||
|
background: white;
|
||||||
|
color: rgba(0, 0, 0, 0.8);
|
||||||
|
}
|
||||||
|
.light .browse .v-block:not(:first-of-type) {
|
||||||
|
border-top: 1px solid rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.browse .list div.selected {
|
|
||||||
background: rgba(0,0,0, 0.08);
|
|
||||||
|
/* Dark */
|
||||||
|
.dark .browse {
|
||||||
|
background: #0a0a0a;
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
}
|
}
|
||||||
|
/* XXX can we make this simpler??? */
|
||||||
|
.dark .browse:focus .list div.selected,
|
||||||
|
.dark .browse .path .dir:hover,
|
||||||
|
.dark .browse .list div:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
}
|
||||||
|
.dark .browse .list div.selected {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
.dark .browse:focus .list div.selected {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
|||||||
@ -3,6 +3,56 @@
|
|||||||
<link rel="stylesheet" href="browse-dialog.css">
|
<link rel="stylesheet" href="browse-dialog.css">
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
|
/* scrollbar setup... */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track-piece {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track-piece {
|
||||||
|
background: rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-corner {
|
||||||
|
}
|
||||||
|
::-webkit-resizer {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* theaming... */
|
||||||
|
|
||||||
|
body.dark {
|
||||||
|
background: black;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark ::-webkit-scrollbar-track-piece {
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
}
|
||||||
|
.dark ::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba(255, 255, 255, 0.15);
|
||||||
|
}
|
||||||
|
.dark ::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* testbed... */
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -30,39 +80,13 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-button {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-track {
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-track-piece {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-track-piece {
|
|
||||||
background: rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background: rgba(0, 0, 0, 0.15);
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
|
||||||
background: rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-corner {
|
|
||||||
}
|
|
||||||
::-webkit-resizer {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script src="../ext-lib/jquery.js"></script>
|
<script src="../ext-lib/jquery.js"></script>
|
||||||
<script src="../ext-lib/jquery-ui.js"></script>
|
<script src="../ext-lib/jquery-ui.js"></script>
|
||||||
|
|
||||||
<script src="../lib/jli.js"></script>
|
<script src="../lib/jli.js"></script>
|
||||||
|
<script src="../lib/toggler.js"></script>
|
||||||
|
|
||||||
<script src="../ext-lib/require.js"></script>
|
<script src="../ext-lib/require.js"></script>
|
||||||
|
|
||||||
@ -135,6 +159,8 @@ requirejs(['../lib/keyboard', '../object', './browse-dialog'], function(k, o, br
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.focus()
|
.focus()
|
||||||
|
|
||||||
|
b.path = '/dir_a/tree/dir_c'
|
||||||
})
|
})
|
||||||
|
|
||||||
$(function(){
|
$(function(){
|
||||||
@ -148,6 +174,16 @@ $(function(){
|
|||||||
//browser.focus()
|
//browser.focus()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
var themeToggler = CSSClassToggler('body',
|
||||||
|
[
|
||||||
|
'none',
|
||||||
|
'light',
|
||||||
|
'dark',
|
||||||
|
],
|
||||||
|
function(state){
|
||||||
|
$('#theme').text(state)
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@ -157,6 +193,11 @@ $(function(){
|
|||||||
<button onclick="b.prev()">^</button>
|
<button onclick="b.prev()">^</button>
|
||||||
<button onclick="b.next()">v</button>
|
<button onclick="b.next()">v</button>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Theme: <button id="theme" onclick="themeToggler()">none</button>
|
||||||
|
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="browse">
|
<div class="browse">
|
||||||
|
|||||||
@ -14,8 +14,7 @@ var object = require('../object')
|
|||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
// XXX add a hook to render the content of an element...
|
// NOTE: the widget itself does not need a title, that's the job for
|
||||||
// XXX NOTE: the widget itself does not need a title, that's the job for
|
|
||||||
// a container widget (dialog, field, ...)
|
// a container widget (dialog, field, ...)
|
||||||
// ...it can be implemented trivially via an attribute and a :before
|
// ...it can be implemented trivially via an attribute and a :before
|
||||||
// CSS class...
|
// CSS class...
|
||||||
@ -49,33 +48,32 @@ var BrowserClassPrototype = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX need to scroll only the list, keeping the path always in view...
|
|
||||||
// XXX need to handle long paths -- smart shortening or auto scroll...
|
// XXX need to handle long paths -- smart shortening or auto scroll...
|
||||||
// XXX Q: should we make a base list dialog and build this on that or
|
// XXX Q: should we make a base list dialog and build this on that or
|
||||||
// simplify this to implement a list (removing the path and disbling
|
// simplify this to implement a list (removing the path and disabling
|
||||||
// traversal)??
|
// traversal)??
|
||||||
// XXX need base events:
|
// XXX need base events:
|
||||||
// - open
|
// - open
|
||||||
// - update
|
// - update
|
||||||
// - select (???)
|
// - select (???)
|
||||||
// XXX add "current selection" to the path...
|
|
||||||
var BrowserPrototype = {
|
var BrowserPrototype = {
|
||||||
dom: null,
|
dom: null,
|
||||||
|
|
||||||
// option defaults and doc...
|
// option defaults and doc...
|
||||||
//
|
|
||||||
// XXX add enable/disable filter option...
|
|
||||||
options: {
|
options: {
|
||||||
//path: null,
|
//path: null,
|
||||||
//show_path: null,
|
//show_path: null,
|
||||||
|
|
||||||
|
// enable/disable user selection filtering...
|
||||||
|
// NOTE: this only affects .stopFilter(..)
|
||||||
|
filter: true,
|
||||||
|
|
||||||
// handle keys that are not bound...
|
// handle keys that are not bound...
|
||||||
//
|
|
||||||
// NOTE: to disable, set ot undefined.
|
// NOTE: to disable, set ot undefined.
|
||||||
logKeys: function(k){ window.DEBUG && console.log(k) },
|
logKeys: function(k){ window.DEBUG && console.log(k) },
|
||||||
},
|
},
|
||||||
|
|
||||||
// XXX this should prevent event handler deligation...
|
// XXX this should prevent event handler delegation...
|
||||||
keyboard: {
|
keyboard: {
|
||||||
// filter mappings...
|
// filter mappings...
|
||||||
Filter: {
|
Filter: {
|
||||||
@ -124,7 +122,8 @@ var BrowserPrototype = {
|
|||||||
// base api...
|
// base api...
|
||||||
// NOTE: to avoid duplicating and syncing data, the actual path is
|
// NOTE: to avoid duplicating and syncing data, the actual path is
|
||||||
// stored in DOM...
|
// stored in DOM...
|
||||||
// XXX does the path includes the currently selected element?
|
// NOTE: path does not include the currently selected list element,
|
||||||
|
// just the path to the current list...
|
||||||
get path(){
|
get path(){
|
||||||
var skip = false
|
var skip = false
|
||||||
return this.dom.find('.path .dir:not(.cur)')
|
return this.dom.find('.path .dir:not(.cur)')
|
||||||
@ -132,7 +131,6 @@ var BrowserPrototype = {
|
|||||||
.toArray()
|
.toArray()
|
||||||
},
|
},
|
||||||
set path(value){
|
set path(value){
|
||||||
// XXX normalize path...
|
|
||||||
return this.update(value)
|
return this.update(value)
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -141,11 +139,26 @@ var BrowserPrototype = {
|
|||||||
// - build the element list
|
// - build the element list
|
||||||
//
|
//
|
||||||
// XXX trigger an "update" event...
|
// XXX trigger an "update" event...
|
||||||
|
// XXX do we normalize path here???
|
||||||
|
// XXX need a way to handle path errors in the extension API...
|
||||||
|
// ...for example, if .list(..) can't list or lists a different
|
||||||
|
// path due to an error, we need to be able to render the new
|
||||||
|
// path both in the path and list sections...
|
||||||
|
// NOTE: current behaviour is not wrong, it just not too flexible...
|
||||||
update: function(path){
|
update: function(path){
|
||||||
path = path || this.path
|
path = path || this.path
|
||||||
var browser = this.dom
|
var browser = this.dom
|
||||||
var that = this
|
var that = this
|
||||||
|
|
||||||
|
// normalize path...
|
||||||
|
// XXX is it correct to ignore empty path elements, e.g. 'aa//cc'?
|
||||||
|
var splitter = /[\\\/]/
|
||||||
|
if(typeof(path) == typeof('str') && splitter.test(path)){
|
||||||
|
path = path
|
||||||
|
.split(splitter)
|
||||||
|
.filter(function(e){ return e != '' })
|
||||||
|
}
|
||||||
|
|
||||||
var p = browser.find('.path').empty()
|
var p = browser.find('.path').empty()
|
||||||
var l = browser.find('.list').empty()
|
var l = browser.find('.list').empty()
|
||||||
|
|
||||||
@ -164,14 +177,14 @@ var BrowserPrototype = {
|
|||||||
.text(e))
|
.text(e))
|
||||||
})
|
})
|
||||||
|
|
||||||
// add current selction indicator...
|
// add current selection indicator...
|
||||||
p.append($('<div>')
|
p.append($('<div>')
|
||||||
.addClass('dir cur')
|
.addClass('dir cur')
|
||||||
.click(function(){
|
.click(function(){
|
||||||
that.startFilter()
|
that.startFilter()
|
||||||
//that.update(path.concat($(this).text()))
|
//that.update(path.concat($(this).text()))
|
||||||
|
|
||||||
// XXX HACK: prevents the field from bluring when clicked...
|
// XXX HACK: prevents the field from blurring when clicked...
|
||||||
// ...need to find a better way...
|
// ...need to find a better way...
|
||||||
that._hold_blur = true
|
that._hold_blur = true
|
||||||
setTimeout(function(){ delete that._hold_blur }, 20)
|
setTimeout(function(){ delete that._hold_blur }, 20)
|
||||||
@ -240,15 +253,17 @@ var BrowserPrototype = {
|
|||||||
// elements will be searched too.
|
// elements will be searched too.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// XXX pattern modes:
|
// TODO pattern modes:
|
||||||
// - lazy match
|
// - lazy match
|
||||||
// abc -> *abc* -> ^.*abc.*$
|
// abc -> *abc* -> ^.*abc.*$
|
||||||
// ab cd -> *ab*cd* -> ^.*ab.*cd.*$
|
// ab cd -> *ab*cd* -> ^.*ab.*cd.*$
|
||||||
// - glob
|
// - glob
|
||||||
// XXX need to support glob / nested patterns...
|
// TODO need to support glob / nested patterns...
|
||||||
// ..things like /**/a*/*moo/
|
// ..things like /**/a*/*moo/
|
||||||
// XXX should we unwrap the elements to be more compatible with
|
//
|
||||||
|
// XXX Q: should we unwrap the elements to be more compatible with
|
||||||
// jQuery .filter(..)?
|
// jQuery .filter(..)?
|
||||||
|
// ...currently I don't think so...
|
||||||
filter: function(pattern, a, b){
|
filter: function(pattern, a, b){
|
||||||
pattern = pattern || '*'
|
pattern = pattern || '*'
|
||||||
var ignore_disabled = typeof(a) == typeof(true) ? a : b
|
var ignore_disabled = typeof(a) == typeof(true) ? a : b
|
||||||
@ -347,21 +362,22 @@ var BrowserPrototype = {
|
|||||||
},
|
},
|
||||||
// XXX make this a toggler... (???)
|
// XXX make this a toggler... (???)
|
||||||
startFilter: function(){
|
startFilter: function(){
|
||||||
var range = document.createRange()
|
if(this.options.filter){
|
||||||
var selection = window.getSelection()
|
var range = document.createRange()
|
||||||
|
var selection = window.getSelection()
|
||||||
|
|
||||||
var that = this
|
var that = this
|
||||||
var e = this.dom.find('.path .dir.cur')
|
var e = this.dom.find('.path .dir.cur')
|
||||||
.text('')
|
.text('')
|
||||||
.attr('contenteditable', true)
|
.attr('contenteditable', true)
|
||||||
.focus()
|
.focus()
|
||||||
|
|
||||||
// place the cursor...
|
|
||||||
range.setStart(e[0], 0)
|
|
||||||
range.collapse(true)
|
|
||||||
selection.removeAllRanges()
|
|
||||||
selection.addRange(range)
|
|
||||||
|
|
||||||
|
// place the cursor...
|
||||||
|
range.setStart(e[0], 0)
|
||||||
|
range.collapse(true)
|
||||||
|
selection.removeAllRanges()
|
||||||
|
selection.addRange(range)
|
||||||
|
}
|
||||||
return this
|
return this
|
||||||
},
|
},
|
||||||
stopFilter: function(){
|
stopFilter: function(){
|
||||||
@ -442,6 +458,9 @@ var BrowserPrototype = {
|
|||||||
//
|
//
|
||||||
// XXX Q: should this trigger a "select" event???
|
// XXX Q: should this trigger a "select" event???
|
||||||
// XXX the scroll handling might be a bit inaccurate...
|
// XXX the scroll handling might be a bit inaccurate...
|
||||||
|
// XXX Q: should this have a version that will just return the
|
||||||
|
// selected element without affecting the ui?
|
||||||
|
// ...something like .filter(..) vs. .showFiltered(..)
|
||||||
select: function(elem, filtering){
|
select: function(elem, filtering){
|
||||||
var pattern = '.list div:not(.disabled):not(.filtered-out)'
|
var pattern = '.list div:not(.disabled):not(.filtered-out)'
|
||||||
var browser = this.dom
|
var browser = this.dom
|
||||||
@ -680,9 +699,6 @@ object.makeConstructor('Browser',
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* vim:set ts=4 sw=4 : */
|
* vim:set ts=4 sw=4 : */
|
||||||
return module })
|
return module })
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user