diff --git a/bricks/bricks.js b/bricks/bricks.js index 334980a..94a5a37 100644 --- a/bricks/bricks.js +++ b/bricks/bricks.js @@ -560,6 +560,34 @@ bricks.App = class extends bricks.Layout { this.bind('orient_changed', this.screen_orient); }); } + get_color(){ + return getComputedStyle(this.dom_element).color; + return parseRGB(colorStr); + } + get_bgcolor(){ + return getComputedStyle(this.dom_element).backgroundColor; + return parseRGB(colorStr); + } + + get_blinkcolor(){ + var color, bgcolor, blinkcolor; + color = parseRGB(this.get_color()); + bgcolor = parseRGB(this.get_bgcolor()); + console.log('color=', color, 'bgcolor=', bgcolor); + function short1of3(x, y){ + if (x < y) { + return x + (y - x) / 3; + } else { + return x - (x - y) / 3; + } + } + var r = short1of3(color.r, bgcolor.r); + var g = short1of3(color.g, bgcolor.g); + var b = short1of3(color.b, bgcolor.b); + var bc = bricks.obj_fmtstr({r:r, g:g, b:b}, "rgb(${r}, ${g}, ${b})"); + console.log('color=', color, 'bgcolor=', bgcolor, 'bc=', bc); + return bc; + } async getCameras() { try { const devices = await navigator.mediaDevices.enumerateDevices(); diff --git a/bricks/css/bricks.css b/bricks/css/bricks.css index 7cefd08..aef0215 100755 --- a/bricks/css/bricks.css +++ b/bricks/css/bricks.css @@ -3,6 +3,8 @@ body { height: 100%; width: 100%; margin: 0; + color: #8a8a8a; + background-color: #fafafa; overflow: auto; display: flex; } diff --git a/bricks/imgs/node-collapse.svg b/bricks/imgs/node-collapse.svg new file mode 100644 index 0000000..77e2649 --- /dev/null +++ b/bricks/imgs/node-collapse.svg @@ -0,0 +1 @@ + diff --git a/bricks/imgs/node-expand.svg b/bricks/imgs/node-expand.svg new file mode 100644 index 0000000..a324bd8 --- /dev/null +++ b/bricks/imgs/node-expand.svg @@ -0,0 +1 @@ + diff --git a/bricks/svg.js b/bricks/svg.js index 0b07727..3d94098 100644 --- a/bricks/svg.js +++ b/bricks/svg.js @@ -4,6 +4,7 @@ bricks.Svg = class extends bricks.VBox { options:{ rate: url: + blink:false color:* blinkcolor:* blinktime:* @@ -11,11 +12,17 @@ bricks.Svg = class extends bricks.VBox { */ constructor(opts){ opts.rate = opts.rate || 1; - opts.cwidth = opts.cwidth || 1; - opts.cheight = opts.cheight || 1; + opts.cwidth = opts.rate; + opts.cheight = opts.rate; opts.blinktime = opts.blinktime || 0.5; opts.dynsize = true; super(opts); + if (! this.color) { + this.color = bricks.app.get_color(); + } + if (!this.blinkcolor){ + this.blinkcolor = bricks.app.get_blinkcolor() + } if (opts.url){ this.set_url(opts.url); } @@ -26,7 +33,7 @@ bricks.Svg = class extends bricks.VBox { .then(svgText => { this.svgText = svgText; this.set_colored_svg(this.color); - this.blink(); + if (this.blink) this.start_blink(); }); } set_ancent_color(e){ @@ -46,20 +53,20 @@ bricks.Svg = class extends bricks.VBox { var svgText = bricks.obj_fmtstr({color: color}, this.svgText); this.dom_element.innerHTML = svgText; } - blink(){ + _blink(){ if (this.blinktime && this.blinkcolor) { if (this.cur_color == this.color){ this.set_colored_svg(this.blinkcolor); } else { this.set_colored_svg(this.color); } - this.blink_task = schedule_once(this.blink.bind(this), + this.blink_task = schedule_once(this._blink.bind(this), this.blinktime); } } start_blink(){ if (!this.blink_task){ - blink(); + this._blink(); } } end_blink(){ @@ -67,5 +74,27 @@ bricks.Svg = class extends bricks.VBox { } } +bricks.StatedSvg = class extends bricks.Svg { + /* { + states:[{state:aaa,url:} ,,], + state: + } */ + constructor(opts){ + super(opts); + if (this.states){ + if (! this.state){ + this.state = this.states[0].state; + } + var url = this.set_state(this.state); + this.set_url(url); + } + } + set_state(state){ + this.states.forEach(s => { + if (s.state == state) this.set_url(s.url); + }); + } +} bricks.Factory.register('Svg', bricks.Svg); +bricks.Factory.register('StatedSvg', bricks.StatedSvg); diff --git a/bricks/tree.js b/bricks/tree.js index 57adeb1..f9bed99 100644 --- a/bricks/tree.js +++ b/bricks/tree.js @@ -12,8 +12,8 @@ bricks.TreeNode = class extends bricks.VBox { this.user_data = data; this.is_leaf = this.user_data.is_leaf; this.params = bricks.extend(this.tree.params, {id:this.user_data[this.tree.opts.idField]}); - if (this.tree.multitype_tree){ - this.params['type'] = this.user_data[this.tree.opts.typeField]; + if (this.tree.opts.typeField){ + this.params.type = this.user_data[this.tree.opts.typeField]; } var n = new bricks.HBox({ height:this.tree.row_height, @@ -33,6 +33,7 @@ bricks.TreeNode = class extends bricks.VBox { } this.container.hide(); } + this.setup_icon_urls() } getValue(){ var v = this.user_data; @@ -63,7 +64,9 @@ bricks.TreeNode = class extends bricks.VBox { this.collapse() } } + async expand(){ + this.node_state = 'open'; if (this.is_leaf){ return; } @@ -74,6 +77,7 @@ bricks.TreeNode = class extends bricks.VBox { this.container.show(); } collapse(){ + this.node_state = 'close' if (this.is_leaf){ return; } @@ -86,13 +90,21 @@ bricks.TreeNode = class extends bricks.VBox { } else { var srcs = this.tree.opts.node_state_imgs || {}; var sources = {}; - sources['open'] = objget(srcs, 'open', bricks_resource('imgs/down_arrow.png')); - sources['close'] = objget(srcs, 'close', bricks_resource('imgs/right_arrow.png')); - this.trigle = new bricks.MultipleStateIcon({ + sources['open'] = objget(srcs, 'open', bricks_resource('imgs/node-expand.svg')); + sources['close'] = objget(srcs, 'close', bricks_resource('imgs/node-collapse.svg')); + this.trigle = new bricks.StatedSvg({ state:'close', - urls:sources, - height:img_size, - width:img_size + states:[ + { + state: 'open', + url: bricks_resource('imgs/node-expand.svg') + }, + { + state: 'close', + url: bricks_resource('imgs/node-collapse.svg') + } + ], + rate: 1, }); this.trigle.bind('state_changed', this.toggleExpandCollapse.bind(this)); widget.add_widget(this.trigle); @@ -103,15 +115,12 @@ bricks.TreeNode = class extends bricks.VBox { widget.add_widget(this.check_w); this.check_w.bind('changed', this.tree.node_checked.bind(this.tree, this)) } - var dtype = this.user_data[this.tree.opts.typeField]; - var icon = objget(TypeIcons, dtype); - if (!icon && this.tree.opts.default_type){ - icon = objget(TypeIcons, his.tree.opts.default_type); - } - if (!icon){ - icon = bricks_resource('imgs/folder.png'); - } - var img = new bricks.Icon({ + var icon_url = self.this.icons_urls.leaf; + if (this.is_leaf) icon_url = this.icons_urls.leaf; + else if this.node_state == 'expand') this.icon_url = this.icons_urls.open; + else this.icon_url = this.icons_urls.close; + var img = new bricks.Svg({ + rate:1, url:icon }); widget.add_widget(img); @@ -136,13 +145,34 @@ bricks.TreeNode = class extends bricks.VBox { } this.str_w.set_text(this.user_data[this.tree.opts.textField]); } + setup_icon_urls(){ + + if (this.tree.opts.typeField){ + var ntype = this.user_data[this.opts.typeField]; + var icons = null; + if (this.tree.node_state_icons){ + icons = this.tree.node_state_icons[ntype]; + var dt = this.tree.node_state_icons.default_type; + if (dt){ + icon = this.tree.node_state_icons[dt]; + } + } + } + if (! icons){ + icons = { + open: bricks_resource('imgs/open_folders.svg'), + close: bricks_resource('imgs/close_folder.svg'), + leaf: bricks_resource('imgs/close_folder.svg') + }; + } + this.icons_urls = icons; + } } bricks.Tree = class extends bricks.VScrollPanel { /* { row_height: - multitype_tree:false, idField: textField: type_icons: @@ -150,9 +180,13 @@ bricks.Tree = class extends bricks.VScrollPanel { default_type: data: dataurl: - node_state_imgs:{ - open:url, - close:url + node_state_icon:{ + nodetype:{ + open:url, + close:url, + leaf:url + } + default_type: }, admin:{ { diff --git a/bricks/utils.js b/bricks/utils.js index 77ea8f4..e65b5d5 100644 --- a/bricks/utils.js +++ b/bricks/utils.js @@ -1,6 +1,20 @@ var bricks = window.bricks || {}; bricks.bug = false; +function parseRGB(colorStr) { + const match = colorStr.match(/^rgb\s*\(\s*(\d+),\s*(\d+),\s*(\d+)\s*\)$/); + if (!match) return null; + const [, r, g, b] = match.map(Number); + return { r, g, b }; +} + +function parseRGBA(colorStr) { + const match = colorStr.match(/^rgba?\s*\(\s*(\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\s*\)$/); + if (!match) return null; + const [, r, g, b, a] = match; + return { r: +r, g: +g, b: +b, a: a !== undefined ? +a : 1 }; +} + async function streamResponseJson(response, onJson) { const reader = response.body.getReader(); const decoder = new TextDecoder("utf-8");