mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-11-02 04:10:11 +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 {
|
||||
display: inline-block;
|
||||
min-width: 300px;
|
||||
width: initial;
|
||||
background: gray;
|
||||
color: rgba(255,255,255,0.8);
|
||||
padding: 5px;
|
||||
font-family: sans-serif;
|
||||
|
||||
background: gray;
|
||||
/*color: rgba(255,255,255,0.8);*/
|
||||
color: white;
|
||||
}
|
||||
/*
|
||||
.browse:not(:focus) {
|
||||
@ -18,11 +21,9 @@
|
||||
height: auto;
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
border-top: 1px solid rgba(255,255,255, 0.3);
|
||||
}
|
||||
.browse .v-block:first-of-type {
|
||||
border-top: none;
|
||||
.browse .v-block:not(:first-of-type) {
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
.browse .v-block:empty {
|
||||
display: none;
|
||||
@ -30,21 +31,18 @@
|
||||
|
||||
|
||||
|
||||
.browse .title {
|
||||
font-weight: bold;
|
||||
color: rgba(255,255,255,0.9);
|
||||
padding: 5px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************ Path ***/
|
||||
|
||||
.browse .path {
|
||||
padding: 5px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
white-space: nowrap;
|
||||
|
||||
opacity: 0.8;
|
||||
}
|
||||
.browse .path:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
.browse .path:empty {
|
||||
display: block;
|
||||
@ -90,6 +88,8 @@
|
||||
|
||||
|
||||
|
||||
/************************************************************ List ***/
|
||||
|
||||
/* XXX need to make this resizable up but only to a certain size (~80vh) */
|
||||
.browse .list {
|
||||
/* XXX need a way to make this automatic and depend on .browser
|
||||
@ -112,13 +112,25 @@
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
cursor: pointer;
|
||||
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.browse:focus .list div.selected,
|
||||
.browse .path .dir: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... */
|
||||
@ -132,11 +144,39 @@
|
||||
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">
|
||||
<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 {
|
||||
display: inline-block;
|
||||
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>
|
||||
|
||||
<script src="../ext-lib/jquery.js"></script>
|
||||
<script src="../ext-lib/jquery-ui.js"></script>
|
||||
|
||||
<script src="../lib/jli.js"></script>
|
||||
<script src="../lib/toggler.js"></script>
|
||||
|
||||
<script src="../ext-lib/require.js"></script>
|
||||
|
||||
@ -135,6 +159,8 @@ requirejs(['../lib/keyboard', '../object', './browse-dialog'], function(k, o, br
|
||||
},
|
||||
})
|
||||
.focus()
|
||||
|
||||
b.path = '/dir_a/tree/dir_c'
|
||||
})
|
||||
|
||||
$(function(){
|
||||
@ -148,6 +174,16 @@ $(function(){
|
||||
//browser.focus()
|
||||
})
|
||||
|
||||
var themeToggler = CSSClassToggler('body',
|
||||
[
|
||||
'none',
|
||||
'light',
|
||||
'dark',
|
||||
],
|
||||
function(state){
|
||||
$('#theme').text(state)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<body>
|
||||
@ -157,6 +193,11 @@ $(function(){
|
||||
<button onclick="b.prev()">^</button>
|
||||
<button onclick="b.next()">v</button>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
Theme: <button id="theme" onclick="themeToggler()">none</button>
|
||||
|
||||
|
||||
<div class="container">
|
||||
<div class="browse">
|
||||
|
||||
@ -14,8 +14,7 @@ var object = require('../object')
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
// XXX add a hook to render the content of an element...
|
||||
// XXX NOTE: the widget itself does not need a title, that's the job for
|
||||
// NOTE: the widget itself does not need a title, that's the job for
|
||||
// a container widget (dialog, field, ...)
|
||||
// ...it can be implemented trivially via an attribute and a :before
|
||||
// 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 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)??
|
||||
// XXX need base events:
|
||||
// - open
|
||||
// - update
|
||||
// - select (???)
|
||||
// XXX add "current selection" to the path...
|
||||
var BrowserPrototype = {
|
||||
dom: null,
|
||||
|
||||
// option defaults and doc...
|
||||
//
|
||||
// XXX add enable/disable filter option...
|
||||
options: {
|
||||
//path: null,
|
||||
//show_path: null,
|
||||
|
||||
// enable/disable user selection filtering...
|
||||
// NOTE: this only affects .stopFilter(..)
|
||||
filter: true,
|
||||
|
||||
// handle keys that are not bound...
|
||||
//
|
||||
// NOTE: to disable, set ot undefined.
|
||||
logKeys: function(k){ window.DEBUG && console.log(k) },
|
||||
},
|
||||
|
||||
// XXX this should prevent event handler deligation...
|
||||
// XXX this should prevent event handler delegation...
|
||||
keyboard: {
|
||||
// filter mappings...
|
||||
Filter: {
|
||||
@ -124,7 +122,8 @@ var BrowserPrototype = {
|
||||
// base api...
|
||||
// NOTE: to avoid duplicating and syncing data, the actual path is
|
||||
// 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(){
|
||||
var skip = false
|
||||
return this.dom.find('.path .dir:not(.cur)')
|
||||
@ -132,7 +131,6 @@ var BrowserPrototype = {
|
||||
.toArray()
|
||||
},
|
||||
set path(value){
|
||||
// XXX normalize path...
|
||||
return this.update(value)
|
||||
},
|
||||
|
||||
@ -141,11 +139,26 @@ var BrowserPrototype = {
|
||||
// - build the element list
|
||||
//
|
||||
// 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){
|
||||
path = path || this.path
|
||||
var browser = this.dom
|
||||
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 l = browser.find('.list').empty()
|
||||
|
||||
@ -164,14 +177,14 @@ var BrowserPrototype = {
|
||||
.text(e))
|
||||
})
|
||||
|
||||
// add current selction indicator...
|
||||
// add current selection indicator...
|
||||
p.append($('<div>')
|
||||
.addClass('dir cur')
|
||||
.click(function(){
|
||||
that.startFilter()
|
||||
//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...
|
||||
that._hold_blur = true
|
||||
setTimeout(function(){ delete that._hold_blur }, 20)
|
||||
@ -240,15 +253,17 @@ var BrowserPrototype = {
|
||||
// elements will be searched too.
|
||||
//
|
||||
//
|
||||
// XXX pattern modes:
|
||||
// TODO pattern modes:
|
||||
// - lazy match
|
||||
// abc -> *abc* -> ^.*abc.*$
|
||||
// ab cd -> *ab*cd* -> ^.*ab.*cd.*$
|
||||
// - glob
|
||||
// XXX need to support glob / nested patterns...
|
||||
// TODO need to support glob / nested patterns...
|
||||
// ..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(..)?
|
||||
// ...currently I don't think so...
|
||||
filter: function(pattern, a, b){
|
||||
pattern = pattern || '*'
|
||||
var ignore_disabled = typeof(a) == typeof(true) ? a : b
|
||||
@ -347,21 +362,22 @@ var BrowserPrototype = {
|
||||
},
|
||||
// XXX make this a toggler... (???)
|
||||
startFilter: function(){
|
||||
var range = document.createRange()
|
||||
var selection = window.getSelection()
|
||||
if(this.options.filter){
|
||||
var range = document.createRange()
|
||||
var selection = window.getSelection()
|
||||
|
||||
var that = this
|
||||
var e = this.dom.find('.path .dir.cur')
|
||||
.text('')
|
||||
.attr('contenteditable', true)
|
||||
.focus()
|
||||
|
||||
// place the cursor...
|
||||
range.setStart(e[0], 0)
|
||||
range.collapse(true)
|
||||
selection.removeAllRanges()
|
||||
selection.addRange(range)
|
||||
var that = this
|
||||
var e = this.dom.find('.path .dir.cur')
|
||||
.text('')
|
||||
.attr('contenteditable', true)
|
||||
.focus()
|
||||
|
||||
// place the cursor...
|
||||
range.setStart(e[0], 0)
|
||||
range.collapse(true)
|
||||
selection.removeAllRanges()
|
||||
selection.addRange(range)
|
||||
}
|
||||
return this
|
||||
},
|
||||
stopFilter: function(){
|
||||
@ -442,6 +458,9 @@ var BrowserPrototype = {
|
||||
//
|
||||
// XXX Q: should this trigger a "select" event???
|
||||
// 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){
|
||||
var pattern = '.list div:not(.disabled):not(.filtered-out)'
|
||||
var browser = this.dom
|
||||
@ -680,9 +699,6 @@ object.makeConstructor('Browser',
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* vim:set ts=4 sw=4 : */
|
||||
return module })
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user