📄 textbox.class
字号:
/* textbox
Base class for areas containing text. Allows multiline text
Note that changes to orientation MUST be made through .set or _set_
so that the stretch information for the view is correctly maintained.
See also, _fr_textbox_parse_and_log for parsing and loggin all of
the settings and style settings.
*/
*! version 1.0.4 07apr2005
version 8
class {
array text
style = .textboxstyle.new
orientation = .tb_orientstyle.new, style(horizontal)
draw_view = .yesno.new, style(yes)
fill_if_undrawn = .yesno.new, style(no)
xoffset = 0 // in gmetric
yoffset = 0
} , inherit(view)
/* -------------------------------------------------------------------------*/
program define new
.xstretch.set free
.ystretch.set fixed
.set `0'
end
/* -------------------------------------------------------------------------*/
program define set
/*
while 0`.text.arrnels' > 0 {
.text.Arrpop
}
*/
.text = {}
.edit `0'
end
program define edit
syntax [ , Orientation(string) Style(passthru) ///
XOFFset(real 0) YOFFset(real 0) MText(string asis) ///
PREFIX SUFFIX REPLACE ///
Text1(string) Text2(string) Text3(string) Text4(string) ///
Text5(string) Text6(string) Text7(string) Text8(string) ///
Text9(string) ///
* ]
if `:word count `prefix' `suffix'' > 1 {
di as error "options prefix and suffix may not be combined"
exit 198
}
.xoffset = `xoffset'
.yoffset = `yoffset'
// multi-line text
local unused : subinstr local mtext `"""' `"""', count(local ct)
if `ct' == 0 {
local mtext `""`mtext'""'
}
local i = cond("`suffix'" == "", 0, `.text.arrnels')
gettoken line mtext : mtext
if "`replace'" != "" {
while 0`.text.arrnels' {
.text.Arrpop
}
}
if "`prefix'" == "" {
while `"`line'"' != `""' {
.text[`++i'] = `"`line'"'
gettoken line mtext : mtext
}
}
else {
tempname newtext
local textarr `newtext'
.`textarr' = {}
while `"`line'"' != `""' {
.`textarr'[`++i'] = `"`line'"'
gettoken line mtext : mtext
}
forvalues j = 1/0`.text.arrnels' {
.`textarr'[`++i'] = .text[`j'].ref
}
.text.ref = .`textarr'.ref
}
forvalues i = 1/9 {
if `"`text`i''"' != `""' { // line-at-a-time text
.text[`i'] = `"`text`i''"'
}
}
if `"`style'"' != `""' {
.style.setstyle, `style'
}
if "`orientation'" != "" & "`orientation'" != "`.orientation.setting'" {
_set_orientation `orientation'
}
if `"`options'"' != "" {
.Super.set, `options'
}
end
/* -------------------------------------------------------------------------*/
/* Return the current text in a list `"<line1>"' `"<line2>"' ...
*/
program get_text
local list `"`"`.text[1]'"'"'
forvalues i=2/0`.text.arrnels' {
local list `"`list' `"`.text[`i']'"'"'
}
class exit `"`list'"'
end
/* -------------------------------------------------------------------------*/
program not_drawn
class exit = `.text.arrnels' == 0
end
/* -------------------------------------------------------------------------*/
program xsize
if 0`.text.arrnels' == 0 {
class exit 0
}
if index("`.orientation.setting'", "vertical") {
if `.style.drawbox.istrue' {
class exit = `.textheight' + ///
`.style.boxmargin.gmleft' + `.style.boxmargin.gmright'
}
else {
class exit `.textheight'
}
}
else {
class exit 0
}
end
program ysize
if 0`.text.arrnels' == 0 {
class exit 0
}
if index("`.orientation.setting'", "horizontal") {
if `.style.drawbox.istrue' {
class exit = `.textheight' + ///
`.style.boxmargin.gmbottom' + ///
`.style.boxmargin.gmtop'
}
else {
class exit = `.textheight'
}
}
else {
class exit = 0
}
end
program textheight
local lines = 0`.text.arrnels'
class exit = `lines' * `.style.size.gmval' + ///
max(0, `lines' - 1) * `.style.linegap.gmval'
end
/* -------------------------------------------------------------------------*/
program define draw
syntax [, XSize(real -1) YSize(real -1) ] /* need missing */
if ! `.draw_view.istrue' {
exit /* Exit */
}
if 0`.text.arrnels' == 0 {
exit /* Exit */
}
/* set rendered size */
if `xsize' == -1 {
.xsize_ren = `.xsize'
}
else .xsize_ren = `xsize'
if `ysize' == -1 {
.ysize_ren = `.ysize'
}
else .ysize_ren = `ysize'
/* set style to gdi */
.style.setgdifull , angle(`.orientation.val')
local x `.xoffset' /* set location */
local y `.yoffset'
if `.style.drawbox.istrue' { /* draw bounding box */
.style.boxmargin.setgdi, view(`.objkey') /* margins */
._draw_box `x' `y' `=`.xsize_ren'+`x'' `=`.ysize_ren'+`y''
}
.style.margin.setgdi, view(`.objkey')
._get_x_y_delta x y xdelta ydelta : `x' `y'
forvalues i = 1/0`.text.arrnels' {
gdi text `x' `y' `.text[`i']'
local x = `x' + 0`xdelta'
local y = `y' + 0`ydelta'
}
end
program _get_x_y_delta
args xmac ymac xdmac ydmac colon x y
local orient `.orientation.setting'
local widthloc `.style.horizontal.setting'
local heightloc `.style.vertical.setting'
if "`orient'" == "horizontal" {
if "`widthloc'" == "right" {
local x = `x' + `.xsize_ren'
}
else if "`widthloc'" == "center" | "`widthloc'" == "default" {
local x = `x' + `.xsize_ren' / 2
}
if "`heightloc'" == "top" {
local y = `y' + `.ysize_ren'
}
else if "`heightloc'" == "middle" {
local y = `y' + (`.ysize_ren' + `.textheight' - ///
`.style.size.gmval') / 2
}
else {
local y = `y' + `.textheight' - `.style.size.gmval'
}
local xdelta 0
local ydelta = - (`.style.size.gmval' + `.style.linegap.gmval')
}
else if "`orient'"=="rhorizontal" | "`orient'"=="reverse_horizontal" {
if "`widthloc'" == "left" {
local x = `x' + `.xsize_ren'
}
else if "`widthloc'" == "center" | "`widthloc'" == "default" {
local x = `x' + `.xsize_ren' / 2
}
if "`heightloc'" == "middle" {
local y = `y' + (`.ysize_ren' - `.textheight' + ///
`.style.size.gmval') / 2
}
else if "`heightloc'" != "top" {
local y = `y' + `.style.size.gmval'
}
local xdelta 0
local ydelta = `.style.size.gmval' + `.style.linegap.gmval'
}
else if "`orient'" == "vertical" {
if "`widthloc'" == "right" {
local y = `y' + `.ysize_ren'
}
else if "`widthloc'" == "center" | "`widthloc'" == "default" {
local y = `y' + `.ysize_ren' / 2
}
if "`heightloc'" == "top" {
local x = `x'
}
else if "`heightloc'" == "middle" {
local x = `x' + (`.xsize_ren' - `.textheight' + ///
`.style.size.gmval') / 2
}
else {
local x = `x' + `.style.size.gmval'
}
local xdelta = `.style.size.gmval' + `.style.linegap.gmval'
local ydelta 0
}
else if "`orient'" == "rvertical" | "`orient'" == "reverse_vertical" {
if "`widthloc'" == "left" {
local y = `y' + `.ysize_ren'
}
else if "`widthloc'" == "center" | "`widthloc'" == "default" {
local y = `y' + `.ysize_ren' / 2
}
if "`heightloc'" == "top" {
local x = `x' + `.xsize_ren'
}
else if "`heightloc'" == "middle" {
local x = `x' + (`.xsize_ren' + `.textheight' - ///
`.style.size.gmval') / 2
}
else {
local x = `x' + `.xsize_ren' - `.style.size.gmval'
}
local xdelta = - (`.style.size.gmval' + `.style.linegap.gmval')
local ydelta 0
}
else {
di in white "(note: invalid orientation setting -- `orient')"
}
c_local `xmac' `x'
c_local `ymac' `y'
c_local `xdmac' `xdelta'
c_local `ydmac' `ydelta'
end
program _draw_box // too bad we cannot use areastyle.draw
if 0`.style.linestyle.patterned_line' | 0`.style.linestyle.blank_line' {
tempname linesty
.`linesty' = .linestyle.new, style(background)
.`linesty'.setgdifull
gdi rectangle `0'
if ! 0`.style.linestyle.blank_line' {
.style.setgdifull
_gr_drawrect `0'
}
}
else {
.style.setgdifull
gdi rectangle `0'
}
end
/* -------------------------------------------------------------------------*/
/* Break/rebreak the text into multiple lines to provide an optimal fit in
a specified aspect ratio of the box.
Solves : P * W = N * A
(P: piece length, W: char width, N: # of pieces, A: aspect ratio,
and N = L / P , L: lenth of all text)
*/
program rebreak_aspect
args aspect
local full `"`.text[1]'"'
forvalues i = 2/0`.text.arrnels' {
local full `"`full' `.text[`i']'"'
}
local len_g : _length `"`full'"'
local width = sqrt(`:length local full'^2 * `aspect' / `len_g')
local width = max(2, round(`width'))
.text = {}
if `"`full'"' == `""' {
.text[1] = ""
exit
}
local i 1
local line : piece 1 `width' of `"`full'"' , nobreak
while `"`line'"' != "" {
.text[`i'] = `"`line'"'
local line : piece `++i' `width' of `"`full'"' , nobreak
}
end
/* -------------------------------------------------------------------------*/
/* The following _set_... programs are used by dialog boxes (and possibly
interactively or by others) to update value w/ side effects -- substitute
for a trigger
*/
program _set_orientation
if "`1'" == "`.orientation.setting'" {
exit
}
.orientation.setstyle , style(`1')
.style.editstyle angle(`1') editcopy
if "`.as_textbox.isa'" == "" | 0`.as_textbox.istrue' {
if index("`1'", "horizontal") {
.xstretch.set free
.ystretch.set fixed
}
if index("`1'", "vertical") {
.xstretch.set fixed
.ystretch.set free
}
}
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -