plus实现splitter窗口分隔条功能
By
admin
at 2019-12-02 • 0人收藏 • 2057人看过
前几天群里有人问spLitter分隔条的用法,用这个控件试了下, 很方便的实现任意分隔.
但是当我想要把分隔条用图片美化一下的时候, 发现并不能很好的实现美化.
大致看了下这个库的写法 ,
plus支持透明图片 , 于是学着把plus来实现同样的功能, 下面是简单的实验过程,
代码在二楼.
以上, 大致实现需要的功能, 美化效果还未测试. 后续在楼下测试
3 个回复 | 最后更新于 2020-04-28
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();
}登录后方可回帖
第一版 splitterex 库完成
用plus模拟的好处: 可以利用plus的skin属性美化界面
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