plus实现splitter窗口分隔条功能

By admin at 2019-12-02 • 0人收藏 • 842人看过

前几天群里有人问spLitter分隔条的用法,用这个控件试了下, 很方便的实现任意分隔.

但是当我想要把分隔条用图片美化一下的时候, 发现并不能很好的实现美化.

大致看了下这个库的写法 , 

plus支持透明图片 , 于是学着把plus来实现同样的功能, 下面是简单的实验过程,


代码在二楼.


以上, 大致实现需要的功能, 美化效果还未测试. 后续在楼下测试


3 个回复 | 最后更新于 2020-04-28
2019-12-02   #1

第一版 splitterex 库完成

用plus模拟的好处: 可以利用plus的skin属性美化界面

GIF.gif

splitterex.aardio 库代码如下:

//分隔条自定义库
import win.ui;
class splitterex{
	ctor( plusCtrl,horz=true ){
		this = plusCtrl;
		this.horz = horz;//是否水平分隔
		this.notify = true;//开启事件回调
		this.onMouseEnter = function(wParam,lParam){
			..win.ui.waitCursor(true,::User32.LoadCursor(null, this.horz ? 0x7F85/*_IDC_SIZENS*/ : 0x7F84/*_IDC_SIZEWE*/));
		}
		this.onMouseLeave = function(wParam,lParam){
    		..win.ui.waitCursor(false);
		}
		
		this.rec = null;
		this.onMouseDrag = function(wParam,lParam){ 
			var Hdc = ::GetDC(this.parent.hwnd);
    		if(this.rec!=null){
    			::DrawFocusRect(Hdc,this.rec);	
    		}
    		var x,y = ..win.getMessagePos(lParam);
    		var px,py = this.getPos();
    		var parentRect = this.parent.getClientRect();
    		if(this.horz){
    			if((py+y)<=0){
    				this.rec = ::RECT(px,0,px+this.width,this.height);	
    			}elseif((py+y)>=(parentRect.bottom-this.height)){
    				this.rec = ::RECT(px,parentRect.bottom-this.height,px+this.width,parentRect.bottom);
    			}else {
    				this.rec = ::RECT(px,py+y,px+this.width,py+y+this.height);
    			}
    		}else {
    			if((px+x)<=0){
    				this.rec = ::RECT(0,py,this.width,py+this.height);	
    			}elseif((px+x)>=(parentRect.right-this.width)){
    				this.rec = ::RECT(parentRect.right-this.width,py,parentRect.right,py+this.height);
    			}else {
    				this.rec = ::RECT(px+x,py,px+x+this.width,py+this.height);
    			}
    		}
    		::DrawFocusRect(Hdc,this.rec);
			::ReleaseDC(this.parent.hwnd,Hdc);
		}
		this.onMouseUp = function(wParam,lParam){
   			if(this.rec!=null){
   				var Hdc = ::GetDC(this.parent.hwnd);
    			::DrawFocusRect(Hdc,this.rec);
				::ReleaseDC(this.parent.hwnd,Hdc);	
    			this.setPos(this.rec.left,this.rec.top);
    			this.rec = null;
    			this.redrawTransparent();
    		}
			
		}
		
		this.adjust = function( cx,cy,wParam ) {	 
			var x,y = this.getPos();
			if(this.onMoveEnd){
				this.onMoveEnd(x,y,cx,cy);
			}
		};
		
		return this;
	};	
}

namespace splitterex;

/**intellisense()
splitterex = Plus分隔条扩展模块
splitterex(.(plus控件名,是否为水平分隔) = Plus分隔条扩展模块 
splitterex() = !splitterexplus.
end intellisense**/

/**intellisense(!splitterexplus)
onMoveEnd = @.onMoveEnd = function( x,y,cx,cy ){
	__/*分隔条移动结束触发此函数,返回此时分隔条的位置信息*/
}
end intellisense**/


使用简单示例如下:

import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=759;bottom=469)
winform.add(
plus={cls="plus";left=135;top=421;right=588;bottom=457;bgcolor=15780518;notify=1;z=1};
plus2={cls="plus";left=360;top=96;right=388;bottom=386;bgcolor=10789024;notify=1;z=2}
)
/*}}*/

var bskin = {
	background={
		active=0xFFF78987;
		default=0xFF8FB2B0;
		disabled=0xE8FF002F;
		hover=0xFF928BB3
	};
}
winform.plus.skin(bskin)
winform.plus2.skin(bskin)

import console
console.open()
import splitterex;

var s1 = splitterex(winform.plus2,false);
var s2 = splitterex(winform.plus,true);
s1.onMoveEnd = function( x,y,cx,cy ){
	console.log("s1",x,y,cx,cy)
}
s2.onMoveEnd = function( x,y,cx,cy ){
	console.log("s2",x,y,cx,cy)
}



winform.show();
win.loopMessage();
return winform;


利用这个库, 把上面顶楼的工程重新修改了下,

主界面mainform.aardio 代码如下:

import win.ui;
/*DSG{{*/
mainForm = win.form(text="aardio工程6";right=760;bottom=471)
mainForm.add(
custom={cls="custom";text="自定义控件";left=0;top=0;right=760;bottom=213;bgcolor=15780518;dt=1;z=1};
custom2={cls="custom";text="自定义控件";left=1;top=223;right=761;bottom=472;bgcolor=12639424;db=1;z=2};
plus={cls="plus";left=0;top=212;right=759;bottom=225;bgcolor=128;notify=1;z=3}
)
/*}}*/

mainForm.custom.loadForm("\dlg\1.aardio")
mainForm.custom2.loadForm("\dlg\2.aardio")

var bskin = {
	background={
		active=0xFFF78987;
		default=0xFF8FB2B0;
		disabled=0xE8FF002F;
		hover=0xFF928BB3
	};
}
mainForm.plus.skin(bskin)


import splitterex;
var px = splitterex(mainForm.plus,true);
px.onMoveEnd = function( x,y,cx,cy ){
	mainForm.custom.setPos(,,mainForm.custom.width,y);
	var xx,yy,ccx,ccy = mainForm.custom2.getPos();
	mainForm.custom2.setPos(x,y+cy,ccx,ccy+(yy-y-cy));
}


mainForm.show();
return win.loopMessage();

其他代码, 下载后可以看看,


链接:https://pan.baidu.com/s/1oy-oTce_J6gBIbj6psdu5w 

提取码:y0al 



2020-04-28   #2
namespace lzch.winui{
    import win;
    import win.ui;
    import table;

function splitter_plus( plusCtrl, skin, ...){
    plusCtrl.horz = plusCtrl.width > plusCtrl.height;//是否水平分隔
    var skin0 = {
                background={
                    active=0xFFF78987;
                    default=0xFF8FB2B0;
                    disabled=0xE8FF002F;
                    hover=0xFF928BB3
                };
            }
    var ctrls;
    
    if( skin && !skin.isForm )    {    ctrls = {          ...};    plusCtrl.skin(skin ); }
    else                         {    ctrls = {skin;    ...};     plusCtrl.skin(skin0);}
    
    plusCtrl.ctrls1 = {}; // 左或上控件列表
    plusCtrl.ctrls2 = {}; // 右或下控件列表
    
    var x,y = plusCtrl.left, plusCtrl.top;
    
    // 传进来了拆分条两边的控件
    if( #ctrls ){    //    根据控件与拆分的距离关系, 自动
        for(_,v in ctrls){
            if( plusCtrl.horz ){ // 水平
                if( v.top < y )    {    table.push(plusCtrl.ctrls1, v);    v._n = y - v.bottom;    }// 控件的底到拆分条的距离
                else            {    table.push(plusCtrl.ctrls2, v);    v._n = v.top - y;         }// 控件的顶到拆分条的距离
            }
            else{
                if( v.left < x ){    table.push(plusCtrl.ctrls1, v);    v._n = x - v.right;        }// 控件的右到拆分条的距离
                else            {    table.push(plusCtrl.ctrls2, v);    v._n = v.left - x;        }// 控件的左到拆分条的距离
            }
        }
    }
    else{    // 如果没有输入控件的 自动中父控件中搜索符合条件的加入
        var cls_not = { // 排除的控件类
                button = 1;
                calendar = 1;
                checkbox = 1;
                datetimepick = 1;
                hotkey = 1;
                radiobutton = 1;
                spin = 1;
                static = 1;
            }
        var x1,x2,y1,y2 = x, plusCtrl.right, y, plusCtrl.bottom;
        
        for(name,ctrl in plusCtrl.parent.eachControl() ){    
            if( cls_not[ctrl.cls] || ctrl == plusCtrl ){ continue; }
            
            if( plusCtrl.horz ){
                if( ctrl.left >= x1 && ctrl.right <= x2 ){
                    if( ctrl.top < y )    {    table.push(plusCtrl.ctrls1, { ctrl = ctrl; n = y - ctrl.bottom; }) }// 控件的底到拆分条的距离
                    else                {    table.push(plusCtrl.ctrls2, { ctrl = ctrl; n = ctrl.top - y;     }) }// 控件的顶到拆分条的距离
                }
            }
            else{
                if( ctrl.top >= y1 && ctrl.bottom <= y2 ){
                    if( ctrl.left < x )    {    table.push(plusCtrl.ctrls1, { ctrl = ctrl;    n = x - ctrl.right; }) }// 控件的右到拆分条的距离
                    else                {    table.push(plusCtrl.ctrls2, { ctrl = ctrl;    n = ctrl.left - x;  }) }// 控件的左到拆分条的距离
                }
            }
        }
    }
    
    plusCtrl.notify = true;//开启事件回调
    plusCtrl.onMouseEnter = function(wParam,lParam){    win.ui.waitCursor(true,::User32.LoadCursor(null, plusCtrl.horz ? 0x7F85/*_IDC_SIZENS*/ : 0x7F84/*_IDC_SIZEWE*/));    }
    plusCtrl.onMouseLeave = function(wParam,lParam){    win.ui.waitCursor(false);    }
    
    plusCtrl.rec = null;
    plusCtrl.onMouseDrag = function(wParam,lParam){ 
        var Hdc = ::GetDC(plusCtrl.parent.hwnd);
        if(plusCtrl.rec!=null){
            ::DrawFocusRect(Hdc,plusCtrl.rec);    
        }
        var x,y = ..win.getMessagePos(lParam);
        var px,py = plusCtrl.getPos();
        var parentRect = plusCtrl.parent.getClientRect();
        if(plusCtrl.horz){
                if((py+y)<=0                                  ){    plusCtrl.rec = ::RECT(px,0,px+plusCtrl.width,plusCtrl.height);    }
            elseif((py+y)>=(parentRect.bottom-plusCtrl.height)){    plusCtrl.rec = ::RECT(px,parentRect.bottom-plusCtrl.height,px+plusCtrl.width,parentRect.bottom);    }
            else                                                {    plusCtrl.rec = ::RECT(px,py+y,px+plusCtrl.width,py+y+plusCtrl.height);            }
        }else {
                if((px+x)<=0                                ){    plusCtrl.rec = ::RECT(0,py,plusCtrl.width,py+plusCtrl.height);    }
            elseif((px+x)>=(parentRect.right-plusCtrl.width)){    plusCtrl.rec = ::RECT(parentRect.right-plusCtrl.width,py,parentRect.right,py+plusCtrl.height);    }
            else                                             {    plusCtrl.rec = ::RECT(px+x,py,px+x+plusCtrl.width,py+plusCtrl.height);        }
        }
        ::DrawFocusRect(Hdc,plusCtrl.rec);
        ::ReleaseDC(plusCtrl.parent.hwnd,Hdc);
    }
    plusCtrl.onMouseUp = function(wParam,lParam){
        if(plusCtrl.rec!=null){
            var Hdc = ::GetDC(plusCtrl.parent.hwnd);
            ::DrawFocusRect(Hdc,plusCtrl.rec);
            ::ReleaseDC(plusCtrl.parent.hwnd,Hdc);    
            plusCtrl.setPos(plusCtrl.rec.left,plusCtrl.rec.top);// call adjust
            plusCtrl.rec = null;
            plusCtrl.redrawTransparent();
        }
    }
    
    plusCtrl.adjust = function( cx,cy,wParam ) {     
        var x,y = plusCtrl.getPos();

        if( owner.horz ){ // 水平
            for(_,v in owner.ctrls1 ){    // 上边的控件
                if( v.ctrl.top >= (y - v.n) ){ // 看不到了
                    v.ctrl.show(false);
                }
                else{
                    v.ctrl.setPos(,, v.ctrl.width, y-v.n-v.ctrl.top);
                    if( !win.isVisible(v.ctrl.hwnd) ){ // 如果已经隐藏了就显示出来
                        v.ctrl.show(true);
                    }
                }
            }
            for(_,v in owner.ctrls2 ){    // 下边的控件
                if( v.ctrl.bottom < (y + v.n) ){ // 看不到了
                    v.ctrl.show(false);
                }
                else{
                    v.ctrl.setPos( v.ctrl.left, y+v.n, v.ctrl.width, v.ctrl.bottom - (y+v.n) );
                    if( !win.isVisible(v.ctrl.hwnd) ){ // 如果已经隐藏了就显示出来
                        v.ctrl.show(true);
                    }
                }
            }
        }
        else{ // 垂直
            for(_,v in owner.ctrls1 ){    // 左边的控件
                if( v.ctrl.left >= (x - v.n) ){ // 看不到了
                    v.ctrl.show(false);
                }
                else{
                    v.ctrl.setPos(,, x-v.n-v.ctrl.left, v.ctrl.height);
                    if( !win.isVisible(v.ctrl.hwnd) ){ // 如果已经隐藏了就显示出来
                        v.ctrl.show(true);
                    }
                }
            }
            for(_,v in owner.ctrls2 ){    // 右边的控件
                if( v.ctrl.right < (x + v.n) ){ // 看不到了
                    v.ctrl.show(false);
                }
                else{
                    v.ctrl.setPos( x + v.n, v.ctrl.top, v.ctrl.right - (x+v.n), v.ctrl.height );
                    if( !win.isVisible(v.ctrl.hwnd) ){ // 如果已经隐藏了就显示出来
                        v.ctrl.show(true);
                    }
                }
            }
        }
    };
}
function splitter_plus_auto(form, skin){
    for(hwnd,ctrl in form.eachControlEx("plus") ){
        if( ctrl.text == "splitter" ){
            ctrl.text = "";
            splitter_plus(ctrl, skin);
        }
    }
}

    
}


if( !owner ){
    import win.ui;
    import lzch.winui;
    /*DSG{{*/
    var winform = win.form(text="aardio form";right=759;bottom=469)
    winform.add(
    checklist={cls="checklist";left=8;top=244;right=340;bottom=460;db=1;dl=1;edge=1;items={};z=5};
    edit={cls="edit";text="Edit";left=8;top=16;right=168;bottom=212;dl=1;dt=1;edge=1;multiline=1;z=1};
    listview={cls="listview";left=424;top=244;right=752;bottom=460;db=1;dr=1;edge=1;z=7};
    plus={cls="plus";text="splitter";left=176;top=16;right=196;bottom=212;dl=1;dt=1;z=3};
    plus2={cls="plus";text="splitter";left=8;top=220;right=752;bottom=240;dl=1;dt=1;z=4};
    plus3={cls="plus";text="splitter";left=352;top=244;right=372;bottom=460;db=1;dl=1;z=6};
    richedit={cls="richedit";text="RichEdit";left=204;top=16;right=752;bottom=212;dr=1;dt=1;edge=1;multiline=1;z=2}
    )
    /*}}*/
    
    lzch.winui.splitter_plus_auto(winform);
    winform.show();
    win.loopMessage();
    
}


2020-04-28   #3

借用你的代码, 写了个函数, 感觉用起来更方便

登录后方可回帖

登 录
信息栏
本站永久域名:HtmLayout.Cn
纯私人站,当笔记本用的,学到哪写到哪,目前正在学aardio+halcon机器视觉.
Sciter中文在线文档Sciter在线学习文档
本 站 主 站:Stm32cube中文网
Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
aardio在线手册Aardio在线手册
C大Aardio论坛:Aar爱好者论坛
简码教程网:简码编程
AARDIO语言QQ群:70517368
赞助商:才仁机械
下载站:非凡软件站
Loading...