界面库

绘图
This commit is contained in:
tslediter 2024-02-05 17:24:07 +08:00
parent 32151f8d94
commit b99970fa64
2 changed files with 220 additions and 99 deletions

View File

@ -2697,24 +2697,24 @@ type TcustomCanvas = class(TSLUIBASE)
R.handle := bthandle;
return r;
end
function SetWorldTransform(trans);
function SetWorldTransform(t);
begin
{**
@explan(说明)文本旋转%%
@param(trans)(array) array(cos,-sin,sin,cos,x,y)%%
@param(t)(array) array(cos,-sin,sin,cos,x,y)%%
**}
{$ifdef linux}
return r;
{$endif}
_xformobj.em11 := trans[0];
_xformobj.em12 := trans[1];
_xformobj.em21 := trans[2];
_xformobj.em22 := trans[3];
_xformobj.edx := trans[4];
_xformobj.edy := trans[5];
_xformobj.em11 := t[0];
_xformobj.em12 := t[1];
_xformobj.em21 := t[2];
_xformobj.em22 := t[3];
_xformobj.edx := t[4];
_xformobj.edy := t[5];
return _wapi.SetWorldTransform(FHandle,_xformobj._getptr_);
end
function trans(ag,x,y);
function trans(ag,x,y,clockwise);
begin
{**
@explan(说明)文本旋转%%
@ -2722,9 +2722,10 @@ type TcustomCanvas = class(TSLUIBASE)
**}
{$ifdef linux}
_wapi.cairo_translate(FHandle,x,y);
_wapi.cairo_rotate(FHandle,-ag);
_wapi.cairo_rotate(FHandle,clockwise?ag:(-ag));
return 1;
{$endif}
if clockwise then return trans(-ag,x,y);
_xformobj.em11 := cos(ag);
_xformobj.em12 := -sin(ag);
_xformobj.em21 := sin(ag);

View File

@ -33,6 +33,9 @@ uses utslvclauxiliary;
基础功能:
markinfo 标记信息 tg_mark_info 类型
lineinfo 画笔信息 tg_line_info 类型
line_mode 是否画线
mark_mode 是否画点的标记
clip_state 是否裁剪区域
Coordinate_Mapping(x,y,z,var _x,var _y) 通过坐标点计算画布点位置
Coordinate_unMapping(x,y,var x_,var y_,var z_) 通过画布点计算坐标点
set_lineinfo_to_canvas(cvs,peninfo) 设置当前画笔信息到画布
@ -43,6 +46,7 @@ uses utslvclauxiliary;
add_axes(axes) 添加坐标系
del_axes(axes) 删除坐标系
executecommand(cmd,p); //命令行执行
paint(cvs); 送入画布绘制各个图形如果是窗口在onpaint消息中调用该函数
属性:
rec_getter function() 返回画布区域 array(左上右下)
fresh_caller: function() //刷新回调
@ -90,18 +94,21 @@ uses utslvclauxiliary;
tg_Polyline 线图以tg_graph为父类
closed 是否封闭的图像
line_mode 是否画线
mark_mode 是否画点的标记
polyline_style 线类型, tgc_LS_interpolated tgc_LS_bar tgc_LS_filled tgc_LS_arrowed tgc_LS_barplot tgc_LS_staircase
bar_width 柱状图类型时候的宽度
tg_legend 图例
location 位置 tgc_in_upper_left tgc_in_lower_left ..... tgc_by_coordinates
postion 定位为tgc_by_coordinates设置具体位置 array(x,y)
line_mode 边框线
links 关联的绘图tg_graph 数组
texts 文本内容,字符串数组
text 文本内容,字符串数组
tg_tips 数据点提示父节点为tg_graph 对象
text 文本数组
data_idx 绑定数据序号
tg_text 文本展示
text 字符串数组
font_angle 角度
data array(x,y,z) 相对于坐标系的位置
tg_WinControl:绘图展示窗口对象,管理了一个 tg_figure 对象在paint消息的时候构造tg_canvas 对象并调用tg_figrue的paint函数实现图形的绘制
其仅仅作为一个案例,用户可以按照其原理构造自己的画布对象,驱动绘制,得到图形
@ -195,9 +202,8 @@ type tg_WinControl = class(tcustomcontrol,tg_const) //
end
function DoMouseWheel(o,e);override;
begin
p1 := ScreenToClient(e.xpos,e.ypos);
ffigure.executecommand("zoom_inc",array("delta":e.delta,"pos":p1));
p := ScreenToClient(e.xpos,e.ypos);
ffigure.executecommand("zoom_inc",array("delta":e.delta,"x":p[0],"y":p[1]));
end
function DoWMSIZE(o,e);override;
begin
@ -350,17 +356,17 @@ type tg_axes = class(tg_base) //
"zoom_inc":
begin
if not ifarray(pm) then return ;
p := pm["pos"];
flg := false;
p0 := pm["x"];
p1 := pm["y"];
for i := 0 to 1 do
begin
a0 := fzoom_box[i,0];
b0 := fzoom_box[i,1];
if not xy_in_paint_rect(p[0],p[1]) then
if not xy_in_paint_rect(p0,p1) then
begin
continue;
end
if not Coordinate_unMapping(p[0],p[1],x,y,z) then continue ;
if not Coordinate_unMapping(p0,p1,x,y,z) then continue ;
dx := ((pm["delta"]>0)?(1.05):(1/1.05));
if not zoom_bound_op(a0,b0,dx,array(x,y)[i],a,b) then continue ;
rt := 1;
@ -378,10 +384,7 @@ type tg_axes = class(tg_base) //
if cg=2 then continue;
fzoom_box[i] := array(a,b);
f_changed .|= c_g_data_zoombox;
flg := true;
end
if flg then prop_changed("Coordinate",f_changed);
return flg;
end
"node_add_in":
begin
@ -401,7 +404,6 @@ type tg_axes = class(tg_base) //
f_changed .|= c_g_data_changed;
f_changed .|= c_g_data_zoombox;
end
end ;
if ochanged<>f_changed then prop_changed("data_changed",f_changed);
end
@ -426,14 +428,14 @@ type tg_axes = class(tg_base) //
end
function axes_mapping(x,y,z,_x,_y);override;//坐标系相对位置到画布
begin
if not(fFigure ) then return 0;
if not(fFigure ) then return false;
_x := p_left+p_width*x ;
_y := p_top +p_height*y;
return true;
end
function axes_unmapping(x,y,_x,_y,_z);override;//画布位置到坐标系相对位置
begin
if not(fFigure ) then return 0;
if not(fFigure ) then return false;
_x := (x-p_left)/p_width;
_y := (y-p_top)/p_height;
return true;
@ -789,28 +791,34 @@ type tg_axes = class(tg_base) //
begin
y +=ax.fontinfo.size*2;
end
if fx_label.location=tgc_by_coordinates then
Coordinate_unMapping(x,y,_x,_y,_z);
else axes_unmapping(x,y,_x,_y,_z);
p := array(_x,_y);
fx_label.auto_postion_value := p;
fx_label.executecommand("auto_position_value",p);
end
end
if fy_label and (fy_label.visible=tgc_on) and (fy_label.auto_position=tgc_on) then
begin
s := fy_label.text;
fsz := fy_label.fontinfo.size;
if s then
begin
y := p_top+(p_height-length(s)*10)/2;
y := p_top+(p_height-length(s)*fsz)/2;
if (fy_location= tgc_left) then
begin
x := p_left+p_width+5;
x := p_left+p_width+5+fsz*2;
end
else
begin
x := p_left-5;
x := p_left-5;//-fy_label.fontinfo.size;
end
if fy_label.location=tgc_by_coordinates then
Coordinate_unMapping(x,y,_x,_y,_z);
else axes_unmapping(x,y,_x,_y,_z);
p := array(_x,_y);
fy_label.auto_postion_value := p;
fy_label.executecommand("auto_position_value",p);
end
end
if ftitle and (ftitle.visible=tgc_on) and (ftitle.auto_position=tgc_on) then
@ -825,8 +833,10 @@ type tg_axes = class(tg_base) //
y -=(ax.fontinfo.size*2);
end
x := p_left+(p_width-length(s)*10)/2;
if ftitle.location=tgc_by_coordinates then
Coordinate_unMapping(x,y,_x,_y,_z);
ftitle.auto_postion_value := array(_x,_y);;
else axes_unmapping(x,y,_x,_y,_z);
ftitle.executecommand("auto_position_value",array(_x,_y));
end
end
end
@ -1152,6 +1162,7 @@ type tg_label_axes = class(tg_label) //
function create(pms);
begin
inherited;
clip_state := tgc_off;
auto_position := tgc_on;
end
protected
@ -1173,6 +1184,7 @@ type tg_axis = class(tg_base) //
function create(pms);
begin
inherited;
clip_state := tgc_off;
fticksize := 12;
fsubticksize := 6;
ftics_direction := tgc_bottom; //
@ -1201,6 +1213,8 @@ type tg_axis = class(tg_base) //
function paint(cvs);override;
begin
if visible<>tgc_on then return ;
if clip_state=tgc_on then cvs.axesclip();
else cvs.axesunclip();
subtks := array();
idx := 0;
if fsub_tics>1 then
@ -1550,13 +1564,108 @@ type tg_axis = class(tg_base) //
end
end
end
type tg_text = class(tg_base)
public
function create(pms);
begin
inherited;
clip_state := tgc_off;
ftext := array();
fdata := array();
ffont_angle := 0;
end
function paint(cvs);override;
begin
if (visible<>tgc_on) then return ;
if not fdata then return ;
if not Coordinate_Mapping(fdata[0],fdata[1],fdata[2],x,y) then return ;
if clip_state=tgc_on then cvs.axesclip();
else cvs.axesunclip();
get_text_size(w,h,hi);
set_lineinfo_to_canvas(cvs);
if ffont_angle<>0 then
begin
cvs.SaveDC();
cvs.trans(-ffont_angle,x,y);
x := 0;
y := 0;
end
if line_mode then
begin
rc := array(x,y,x+w,y+h);
cvs.draw_rect().rect(rc).draw();
end
set_fontinfo_to_canvas(cvs);
for i,v in ftext do
begin
cvs.textout(v,array(x,y+i*hi));
end
if ffont_angle<>0 then
cvs.RestoreDC();
end
published
property text read ftext write set_text;
property data read fdata write set_data;
property font_angle read ffont_angle write set_font_angle;
private
ftext;
fdata;
ffont_angle;
private
function get_text_size(w,h,hi);
begin
fw := fontinfo.size;
fh := fw*2;
hi:=fh+2;
w := 0;
h := 0;
for i,v in ftext do
begin
si := v;
w := max(w,length(si)*fw);
h+=fh;
end
h+=2;
end
function set_text(v);
begin
tx := array();
for i,vi in v do
begin
if ifstring(vi) then tx[length(tx)] := vi;
end
if ftext<>tx then
begin
ftext :=tx;
prop_changed("text",tx);
end
end
function set_data(d);
begin
if fdata<>d and ifarray(d) and ifnumber(d[0]) and ifnumber(d[1]) then
begin
fdata := d;
prop_changed("data",d);
end
end
function set_font_angle(arg);
begin
if arg<>ffont_angle then
begin
ffont_angle := arg;
prop_changed("font_angle",arg);
end
end
end
type tg_label =class(tg_base) //标签对象
function create(pms);
begin
inherited;
clip_state := tgc_off;
ftext := false;
flocation := 0;
flocation := tgc_by_coordinates;
fposition := array(0,0);
ffill_mode := false;
ffont_angle := 0;
@ -1566,6 +1675,8 @@ type tg_label =class(tg_base) //
begin
if tgc_on<>visible then return ;
if not ftext then return ;
if clip_state=tgc_on then cvs.axesclip();
else cvs.axesunclip();
set_fontinfo_to_canvas(cvs);
p := fposition;
@ -1588,12 +1699,23 @@ type tg_label =class(tg_base) //
if ffont_angle<>0 then
begin
cvs.SaveDC();
cvs.trans(ffont_angle,x_,y_);
cvs.trans(-ffont_angle,x_,y_);
cvs.textout(ftext,array(0,0));
cvs.RestoreDC();
end else
cvs.textout(ftext,array(x_,y_));
end
function executecommand(cmd,p);override;
begin
case cmd of
"auto_position_value":
begin
fauto_position_value := p;
return ;
end
end;
return inherited;
end
protected
function check_parent(p);override;
begin
@ -1604,7 +1726,7 @@ type tg_label =class(tg_base) //
property position read fposition write set_positon;//[-27.697388,-1.7130177]
property location read flocation write Set_location;
property auto_position read fauto_position write set_auto_position;//"on"
property auto_postion_value read fauto_position_value write fauto_position_value;//"on"
//property auto_position_value read fauto_position_value write fauto_position_value;//"on"
property auto_rotation read fauto_rotation write set_auto_rotation;//"on"
property font_angle read ffont_angle write set_font_angle;//90
//font_foreground ;//= 6
@ -1695,7 +1817,7 @@ type tg_tips = class(tg_base) //
flocation := tgc_by_coordinates;
fdisplay_components := "xy";
fbox_mode := tgc_on;
fmark_mode := tgc_on;
mark_mode := tgc_on;
markinfo.Style := tgc_mks_square;
markinfo.size := 5;
fline_style := 0;
@ -1726,6 +1848,8 @@ type tg_tips = class(tg_base) //
ss := get_text();
if not ss then return ;
if not(f_ps and ifnumber(f_ps[0]) and ifnumber(f_ps[1])) then return ;
if clip_state=tgc_on then cvs.axesclip();
else cvs.axesunclip();
ws := 0;
hs := array();
w := fontinfo.size;
@ -1737,7 +1861,7 @@ type tg_tips = class(tg_base) //
end
Coordinate_Mapping(d[0],d[1],z,x_,y_);
sz := array(ws,sum(hs));
if fmark_mode = tgc_on then
if mark_mode = tgc_on then
begin
mk := markinfo;
msz := max(ceil(mk.size/2),2);
@ -1771,17 +1895,15 @@ type tg_tips = class(tg_base) //
//property interp_mode read finterp_mode write finterp_mode; //"on"
property location read flocation write set_location;
property box_mode read fbox_mode write set_box_mode; //"on"
property mark_mode read fmark_mode write set_mark_mode; //"on"
property display_components read fdisplay_components write set_display_components; //"xy"
property data_idx read fdata_idx write set_data_idx;
property display_function read fdisplay_function write fdisplay_function;
property texts read get_text write set_text;
property text read get_text write set_text;
property data read get_data;
private
[weakref]fdisplay_function;
flocation;
fbox_mode;
fmark_mode;
//finterp_mode;
fdisplay_components;
fdata_idx;
@ -1902,15 +2024,6 @@ type tg_tips = class(tg_base) //
prop_changed("box_mode",nv);
end
end
function set_mark_mode(v);
begin
if not tg_boolen_value(v,nv) then return ;
if nv<>fmark_mode then
begin
fmark_mode := nv;
prop_changed("mark_mode",nv);
end
end
function d_comp_ok(dcp);
begin
t := array("x":1,"y":1,"z":1);
@ -1927,7 +2040,7 @@ type tg_legend = class(tg_base) //ͼ
function create(pms);
begin
inherited;
fline_mode := tgc_on;
clip_state := tgc_off;
flocation := tgc_in_upper_right;
flinks := array();
FText := array();
@ -1936,6 +2049,8 @@ type tg_legend = class(tg_base) //ͼ
function paint(cvs);override;
begin
if tgc_on<>visible then return ;
if clip_state=tgc_on then cvs.axesclip();
else cvs.axesunclip();
get_lenged_sizes(lw,lh,ws,hs,objs,ss);
arec := cvs.axesrec;
rc := arec;
@ -2045,9 +2160,8 @@ type tg_legend = class(tg_base) //ͼ
published
property location read flocation write set_location;
property postion read fposition write set_postion;
property line_mode read fline_mode write set_line_mode;
property links read flinks write set_links;
property texts read FText write set_text;
property text read FText write set_text;
protected
function check_parent(p);override;
begin
@ -2055,7 +2169,6 @@ type tg_legend = class(tg_base) //ͼ
end
private
[weakref] flinks;
fline_mode;
flocation;
FText;
fposition;
@ -2155,15 +2268,6 @@ type tg_legend = class(tg_base) //ͼ
flocation := v;
end
end
function set_line_mode(v);
begin
if not tg_boolen_value(v,nv) then return ;
if nv<>fline_mode then
begin
fline_mode := nv;
prop_changed("line_mode",nv);
end
end
end
type tg_graph_base = class(tg_base) //兼容绘图和goup两个类型
function create(pm);
@ -2243,9 +2347,10 @@ type tg_Polyline = class(tg_graph) //
function create(pms);
begin
inherited;
clip_state := tgc_on;
fclosed := tgc_off;
fline_mode := tgc_on;
fmark_mode := tgc_off;
line_mode := tgc_on;
mark_mode := tgc_off;
fpolyline_style := tgc_LS_interpolated;// interpolated,staircase,barplot,arrowed,filled,bar
fbar_width := 0;
fdata_bounds := array((0,1),(0,1),(0,1));
@ -2257,7 +2362,8 @@ type tg_Polyline = class(tg_graph) //
function paint(cvs);override;
begin
if tgc_on<> visible then return ;
cvs.axesclip();
if clip_state=tgc_on then cvs.axesclip();
else cvs.axesunclip();
xys := array();
set_lineinfo_to_canvas(cvs);
for i,v in fgraph_data do
@ -2266,7 +2372,7 @@ type tg_Polyline = class(tg_graph) //
xys[i] := array(integer(x),integer(y));
end
Coordinate_Mapping(0,0,0,x,y);
paint_lines(cvs,fpolyline_style,xys,fclosed,array("line_mode":fline_mode,"bar_width":fbar_width,"color":lineinfo.color,"bkcolor":lineinfo.bkcolor,"x":x,"y":y));
paint_lines(cvs,fpolyline_style,xys,fclosed,array("line_mode":line_mode,"bar_width":fbar_width,"color":lineinfo.color,"bkcolor":lineinfo.bkcolor,"x":x,"y":y));
mk := markinfo;
if mark_mode=tgc_on and mk.size>2 then
begin
@ -2291,7 +2397,7 @@ type tg_Polyline = class(tg_graph) //
dis := ceil((rec[2]-rec[0])/5);
xys := array((rec[0]+dis,y0),(rec[0]+4*dis,y0));
set_lineinfo_to_canvas(cvs);
paint_lines(cvs,tgc_LS_interpolated,xys,0,array("line_mode":fline_mode,"bar_width":fbar_width,"color":lineinfo.color,"bkcolor":lineinfo.bkcolor));
paint_lines(cvs,tgc_LS_interpolated,xys,0,array("line_mode":line_mode,"bar_width":fbar_width,"color":lineinfo.color,"bkcolor":lineinfo.bkcolor));
mk := markinfo;
if mark_mode=tgc_on and mk.size>2 then
begin
@ -2300,8 +2406,6 @@ type tg_Polyline = class(tg_graph) //
end
end
property closed read fclosed write fclosed;//= "off"
property line_mode read fline_mode write set_line_mode;//= "0"
property mark_mode read fmark_mode write set_mark_mode;//= "0"
property polyline_style read fpolyline_style write set_polyline_style;//= "0"
property bar_width read fbar_width write fbar_width;//= "0"
private
@ -2309,8 +2413,6 @@ type tg_Polyline = class(tg_graph) //
fclosed;
fforeground;
fbackground;
fline_mode;
fmark_mode;
fpolyline_style;
fbar_width;
//datatips;//: ["Datatip";"Datatip"]
@ -2353,22 +2455,7 @@ type tg_Polyline = class(tg_graph) //
fpolyline_style := v;
end
end
function set_line_mode(v);
begin
if not tg_boolen_value(v,nv) then return ;
if nv<>fline_mode then
begin
fline_mode := nv;
end
end
function set_mark_mode(v);
begin
if not tg_boolen_value(v,nv) then return ;
if nv<>fmark_mode then
begin
fmark_mode := nv;
end
end
end
type tg_line_info = class(tg_const)
function create();
@ -2434,7 +2521,10 @@ type tg_base = class(TNode,tg_const) //
function create(pms);
begin
class(TNode).create();
fclip_state := tgc_on;
fvisibe := tgc_on;
fline_mode := tgc_off;
fmark_mode := tgc_off;
flineinfo := new tg_line_info();
fmarkinfo := new tg_mark_info();
ffontinfo := new tg_font_info();
@ -2513,6 +2603,9 @@ type tg_base = class(TNode,tg_const) //
cvs.font.height := fi.size*2;
end
published
property line_mode read fline_mode write set_line_mode;
property mark_mode read fmark_mode write set_mark_mode;
property clip_state read fclip_state write set_clip_state;
property axes read get_axes write set_axes;
property visible read fvisibe write setvisible;
property lineinfo read flineinfo;
@ -2558,10 +2651,37 @@ type tg_base = class(TNode,tg_const) //
return r;
end
private
fclip_state;
fline_mode;
fmark_mode;
fvisibe;
flineinfo;
fmarkinfo;
ffontinfo;
function set_clip_state(v);
begin
if tg_boolen_value(v,nv) and (nv<>fclip_state) then
begin
fclip_state := nv;
prop_changed("clip_state",nv);
end
end
function set_line_mode(v);
begin
if tg_boolen_value(v,nv) and (nv<>fline_mode) then
begin
fline_mode := nv;
prop_changed("line_mode",nv);
end
end
function set_mark_mode(v);
begin
if tg_boolen_value(v,nv) and nv<>fmark_mode then
begin
fmark_mode := nv;
prop_changed("mark_mode",nv);
end
end
function setvisible(v);//设置可见
begin
if tg_boolen_value(v,nv) and (nv<>fvisibe) then