diff --git a/bricks/bricks.js b/bricks/bricks.js index f8d6b58..bead350 100644 --- a/bricks/bricks.js +++ b/bricks/bricks.js @@ -219,13 +219,27 @@ bricks.universal_handler = async function(from_widget, widget, desc, event){ event); } bricks.buildEventHandler = async function(w, desc, event){ - var target = bricks.getWidgetById(desc.target, w); + var target; + if (desc.target == 'Popup'){ + var popts = bricks.get_popup_default_options(); + var opt1 = desc.popup_options || {}; + bricks.extend(popts, opt1); + target = new bricks.Popup(popts); + } else if (desc.target == 'PopupWindow') { + var popts = bricks.get_popupwindow_default_options(); + var opt1 = desc.popup_options || {}; + bricks.extend(popts, opt1); + target = new bricks.PopupWindow(popts); + } else { + target = bricks.getWidgetById(desc.target, w); + } if (! target){ bricks.debug('target miss desc=', desc, 'w=', w); return null } var rtdata = {}; desc.event_params = event.params || {} ; + desc.event = event; if (desc.rtdata) rtdata = desc.rtdata; else if (desc.datawidget){ var data_desc = { @@ -236,15 +250,6 @@ bricks.buildEventHandler = async function(w, desc, event){ } rtdata = await bricks.getRealtimeData(w, data_desc); } - /* - if (typeof event.params == typeof {}){ - rtdata = bricks.extend(rtdata, event.params); - } else if (event.params instanceof FormData){ - for ( const [key, value] of Object.entries(rtdata)){ - params.append(key, value); - } - } - */ switch (desc.actiontype){ case 'urlwidget': return bricks.buildUrlwidgetHandler(w, target, rtdata, desc); @@ -290,45 +295,31 @@ bricks.getRealtimeData = async function(w, desc){ return null; } -var _buildWidget = async function(from_widget, target, mode, options){ - bricks.debug('target=', target, 'mode=', mode, 'options=', options); - var w = await (bricks.widgetBuild(options, from_widget)); - if (!w){ - bricks.debug('options=', options, 'widgetBuild() failed'); - return; - } +var _buildWidget = async function(from_widget, target, mode, options, desc){ + bricks.debug('target=', target, 'mode=', mode, 'options=', options); + var w = await (bricks.widgetBuild(options, from_widget)); + if (!w){ + bricks.debug('options=', options, 'widgetBuild() failed'); + return; + } - if (w.parent) return; + if (w.parent) return; - if (mode == 'replace'){ - target.clear_widgets(); - target.add_widget(w); - } else if (mode == 'insert'){ - target.add_widget(w, 0); - } else { - target.add_widget(w); - } + if (mode == 'replace'){ + target.clear_widgets(); + target.add_widget(w); + } else if (mode == 'insert'){ + target.add_widget(w, 0); + } else { + target.add_widget(w); + } + if ((target instanceof bricks.Popup || target instanceof bricks.PopupWindow) \ + && desc.popup_options.eventpos){ + target.bind('opened', bricks.relocate_by_eventpos.bind(None, desc.event, target)); + } } bricks.buildUrlwidgetHandler = function(w, target, rtdata, desc){ - /* - var f = async function(target, mode, options){ - bricks.debug('target=', target, 'mode=', mode, 'options=', options); - var w = await (bricks.widgetBuild(options, w)); - if (!w){ - bricks.debug('options=', options, 'widgetBuild() failed'); - return; - } - if (mode == 'replace'){ - target.clear_widgets(); - target.add_widget(w); - } else if (mode == 'insert'){ - target.add_widget(w, 0); - } else { - target.add_widget(w); - } - } - */ var options = objcopy(desc.options||{}); var params = options.params || {}; if (desc.event_params instanceof FormData){ @@ -352,27 +343,13 @@ bricks.buildUrlwidgetHandler = function(w, target, rtdata, desc){ "widgettype":"urlwidget", "options":options } - return _buildWidget.bind(w, target, target, desc.mode || 'replace', opts); + return _buildWidget.bind(None, w, target, desc.mode || 'replace', opts, desc); } bricks.buildBricksHandler = function(w, target, rtdata, desc){ - /* - var f = async function(target, mode, options){ - bricks.debug('target=', target, 'mode=', mode, 'options=', options); - var w = await (bricks.widgetBuild(options, wa)); - if (!w){ - bricks.debug('options=', options, 'widgetBuild() failed'); - return; - } - if (mode == 'replace'){ - target.clear_widgets(); - } - target.add_widget(w); - } - */ var options = objcopy(desc.options||{}); rtdata = bricks.extend(rtdata, inputdata2dic(desc.event_params)); options = bricks.apply_data(options, rtdata); - return _buildWidget.bind(w, target, target, desc.mode || 'replace', options); + return _buildWidget.bind(w, target, target, desc.mode || 'replace', options, desc); } bricks.buildRegisterFunctionHandler = function(w, target, rtdata, desc){ var f = bricks.RF.get(desc.rfname); @@ -449,7 +426,7 @@ bricks.getWidgetById = function(id, from_widget){ el = bricks.app.root.dom_element; continue; } - if (ids[i]=='app'){ + if (ids[i]=='app' || ids[i] == 'body'){ return bricks.app; } if (ids[i] == 'window'){ diff --git a/bricks/popup.js b/bricks/popup.js index 9401219..3fde4eb 100644 --- a/bricks/popup.js +++ b/bricks/popup.js @@ -1,5 +1,17 @@ var bricks = window.bricks || {}; +bricks.get_popup_default_options = function(){ + return { + timeout:0, + archor:'cc', + auto_open:true, + auto_dismiss:true, + auto_destroy:true, + movable:true, + resizable:false, + modal:true + } +} bricks.Popup = class extends bricks.VBox { /* { @@ -52,13 +64,17 @@ bricks.Popup = class extends bricks.VBox { async load_content(){ var w = await bricks.widgetBuild(this.content, this); if (w){ - if (this.content.dismiss_event){ - w.bind(this.content.dismiss_event, this.distroy.bind(this)); - } + this.set_dismiss_events(w); this.content_w.clear_widgets(); this.content_w.add_widget(w); } } + set_dismiss_events(w){ + if (!this.dismiss_events) return; + this.dismiss_events.forEach(ename => { + w.bind(ename, this.distroy.bind(this)); + }); + } bring_to_top(){ if (this == bricks.app.toppopup){ return; @@ -324,23 +340,34 @@ bricks.Popup = class extends bricks.VBox { } } add_widget(w, i){ - return this.content_box.add_widget(w, i); + this.set_dismiss_events(w); + return this.content_w.add_widget(w, i); } remove_widget(w){ - return this.content_box.remove_widget(w); + return this.content_w.remove_widget(w); } clear_widgets(){ - return this.content_box.clear_widgets(); + return this.content_w.clear_widgets(); } } +bricks.get_popupwindow_default_options = function(){ + return { + timeout:0, + archor:'cc', + auto_open:true, + auto_dismiss:true, + auto_destroy:true, + movable:true, + resizable:true, + modal:true + } +} bricks.PopupWindow = class extends bricks.Popup { /* { title: icon: - params: - url: } */ constructor(opts){ @@ -354,11 +381,12 @@ bricks.PopupWindow = class extends bricks.Popup { this.auto_open = ao; this.title_bar = new bricks.HBox({css:'titlebar', cheight:2, width:'100%'}); this.moving_w = this.title_bar; - super.add_widget(this.title_bar); + this.add_widget(this.title_bar); this.build_title_bar(); var filler = new bricks.Filler({}); - super.add_widget(filler) - this.content_w = new bricks.Layout({}); + this.add_widget(filler) + + this.content_w = new bricks.Layout({height:'100%', width:'100%'}); this.content_w.set_css('flexbox'); filler.add_widget(this.content_w); if (this.auto_open){ diff --git a/bricks/utils.js b/bricks/utils.js index e52b0c1..edbf7b9 100644 --- a/bricks/utils.js +++ b/bricks/utils.js @@ -1,5 +1,29 @@ var bricks = window.bricks || {}; bricks.bug = false; + +var bricks.relocate_by_eventpos = function(event, widget){ + var ex,ey; + var x,y; + var xsize = bricks.Body.dom_element.clientWidth; + var ysize = bricks.Body.dom_element.clientHeight; + ex = event.clientX; + ey = event.clientY; + var mxs = widget.dom_element.offsetWidth; + var mys = widget.dom_element.offsetHeight; + if (ex < (xsize / 2)) { + x = ex + bricks.app.charsize; + } else { + x = ex - mxs - bricks.app.charsize; + } + if (ey < (ysize / 2)) { + y = ey + bricks.app.charsize; + } else { + y = ey - mys - bricks.app.charsize; + } + widget.set_style('left', x + 'px'); + widget.set_style('top', y + 'px'); +} + var formdata2object = function(formdata){ let result = {}; formdata.forEach((value, key) => { diff --git a/bricks/widget.js b/bricks/widget.js index a05ac7d..d64db9a 100644 --- a/bricks/widget.js +++ b/bricks/widget.js @@ -511,36 +511,22 @@ bricks.Tooltip = class extends bricks.Text { this.set_otext(otext); this.set_style('zIndex', 999999999); this.set_style('display', 'block'); - var ex,ey; - var x,y; - var xsize = bricks.Body.dom_element.clientWidth; - var ysize = bricks.Body.dom_element.clientHeight; - ex = event.clientX; - ey = event.clientY; - var mxs = this.dom_element.offsetWidth; - var mys = this.dom_element.offsetHeight; - if (ex < (xsize / 2)) { - x = ex + bricks.app.charsize; - } else { - x = ex - mxs - bricks.app.charsize; - } - if (ey < (ysize / 2)) { - y = ey + bricks.app.charsize; - } else { - y = ey - mys - bricks.app.charsize; - } - this.set_style('left', x + 'px'); - this.set_style('top', y + 'px'); + bricks.relocate_by_eventpos(event, this); if (this.auto_task){ this.auto_task.cancel(); + this.auto_task = null; } this.auto_task = schedule_once(this.hide.bind(this), 6); } hide(){ + try { if (this.auto_task){ this.auto_task.cancel(); this.auto_task = null; } + } catch(e){ + console.log('Exception:', e); + } this.set_style('display', 'none'); } } diff --git a/docs/cn/event.md b/docs/cn/event.md index 13871cd..f09c14b 100644 --- a/docs/cn/event.md +++ b/docs/cn/event.md @@ -39,6 +39,14 @@ bricks的事件处理是在控件描述文件的binds区域中添加事件处理 ### dataparams 获取动态参数时需给定的参数, 可选,对象类型,k,v形式给定参数 +### popup_options +当target为“Popup“或“PopupWindow”时,定义Popup或PopupWindow的参数 + +#### dismiss_events +字符串数组,每个字符串定义一个Popup, PopupWindow的子控件的事件,这些事件发生时将导致Popup, PopupWindow关闭 + +#### eventpos +Popup, PopupWindow窗体移动到鼠标位置 ### 获取动态参数说明 绑定任务获取实时数据作为参数,需要给定以下属性: @@ -50,7 +58,15 @@ bricks的事件处理是在控件描述文件的binds区域中添加事件处理 datamethod 优先datascript,从datawidget控件中通过datamethod ### target -字符串或控件实例,目标控件实例,如果是字符串,使用”getWidgetById“函数获得目标控件实例,关于target规则请查看[控件id](widgetid.md) +支持一下形式的target定义: +* 目标控件实例对象 +* 字符串,且等于“Popup“ +* 字符串,且等于”PopupWindow“ +* 其他字符串(控件对象的id) +当actiontype为"urlwidget"时,target应该是一个容器控件,所生成的控件将插入或替代到“target”所代表的对象中,如果actiontype是其他类型,则在此对象中执行方法,脚本,定义函数,或定义事件 + + + ### conform 如果一个事件处理需要用户确认,可以在事件处理中指定一个conform属性来引发,当此事件发生时,会弹出一个确认窗口,用户确认后才会处理此事件,否则不处理