diff --git a/funcext/tvclib/utslvclgdi.tsf b/funcext/tvclib/utslvclgdi.tsf index b9193c2..6be0d24 100644 --- a/funcext/tvclib/utslvclgdi.tsf +++ b/funcext/tvclib/utslvclgdi.tsf @@ -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); diff --git a/funcext/tvclib/utvclgraphics.tsf b/funcext/tvclib/utvclgraphics.tsf index 92369eb..858b2e8 100644 --- a/funcext/tvclib/utvclgraphics.tsf +++ b/funcext/tvclib/utvclgraphics.tsf @@ -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,19 +94,22 @@ 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 图例 - + 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 文本内容,字符串数组 - tg_tips 数据点提示,父节点为tg_graph 对象 - + 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函数实现图形的绘制 其仅仅作为一个案例,用户可以按照其原理构造自己的画布对象,驱动绘制,得到图形 } @@ -194,10 +201,9 @@ type tg_WinControl = class(tcustomcontrol,tg_const) // inherited; end function DoMouseWheel(o,e);override; - begin - - p1 := ScreenToClient(e.xpos,e.ypos); - ffigure.executecommand("zoom_inc",array("delta":e.delta,"pos":p1)); + begin + 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 @@ -400,8 +403,7 @@ type tg_axes = class(tg_base) // begin f_changed .|= c_g_data_changed; f_changed .|= c_g_data_zoombox; - end - + 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 - Coordinate_unMapping(x,y,_x,_y,_z); + 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 - Coordinate_unMapping(x,y,_x,_y,_z); + 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; - Coordinate_unMapping(x,y,_x,_y,_z); - ftitle.auto_postion_value := array(_x,_y);; + if ftitle.location=tgc_by_coordinates then + Coordinate_unMapping(x,y,_x,_y,_z); + 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 + 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; @@ -1901,16 +2023,7 @@ type tg_tips = class(tg_base) // fbox_mode := nv; 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 + 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; + 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