📄 style.class
字号:
/* style
Base class for all styles.
Reserved attribute names: .proxy
NOTES:
1. ALL styles MUST run .Super.new if they implement their
own .new program
2. Styles may designate a proxy style that will be used in place
of the classname when named styles are to be looked up. The name
of the proxy must be stored in the attribute .proxy. In this way
a derived style need not create a whole new set of named styles
but may inherit them from its super style.
3. Composite styles (styles that contain other styles) should not be
initialized to named styles using the style(name) option in class
declarations. Instead, if this is required, initialize them in a
.new program for the class. Primitive styles (styles that contain
just their own attribue or set of attributes) can be initialized
in a class declaration.
Highly techincal explanation. When an instance is created, the
attributes are copied and the named style will have the right
values, but they will be copies not references. Changes to the
style will NOT be reflected in other copies of the named style.
This cannot be fixed by internally clone1-ing styles because the
.styledex MUST be a copy and not a references or ALL styles will
change the index when any one does.
4. Styles contain only other styles and double or string attributes.
Styles are scheme specific and there may be multiple schemes in
play at any time. The definitions of the styles for any scheme
are kept in the scheme under the stylenames (.classname of the
style object) in the arrays __STYLES.classname, _styles, and
_refs. __STYLES.classname holds the names of the globally defined
named styles, _style holds the names of any named styles added to
the scheme, and _refs holds references to prototype instances for
the named styles. These arrays are all alligned _style has a
placeholder at the last element of __STYLES.classname.
analogs of some of the add and delete programs from codes would be nice.
*/
*! version 1.0.3 05dec2003
version 8
class {
instance:
double styledex /* index into styles if a named style */
from_scheme = 0 /* 1 if name from the scheme */
} , inherit(object)
/* -------------------------------------------------------------------------*/
/*
Usage: .styleclass.new [ , style(named_style) force ]
see setstyle below for syntax
*/
/* internal
program new
.setstyle `0'
end
*/
/* -------------------------------------------------------------------------*/
/*
Usage: .stylename
Returns the name of the style for the current object
*/
/* internal
program define stylename
if "`.styledex'" != "" {
if `.styledex' > 0`.__STYLES.`.classname'.arrnels' {
class exit .`c(curscm)'.`.classname'._styles[`.styledex']
}
else {
class exit .__STYLES.`.classname'[`.styledex']
}
}
class exit `""'
end
program define setting
if "`.styledex'" != "" {
if `.styledex' > 0`.__STYLES.`.classname'.arrnels' {
class exit .`c(curscm)'.`.classname'._styles[`.styledex']
}
else {
class exit .__STYLES.`.classname'[`.styledex']
}
}
class exit `""'
end
program define snm
if "`.styledex'" != "" {
if `.styledex' > 0`.__STYLES.`.classname'.arrnels' {
class exit .`c(curscm)'.`.classname'._styles[`.styledex']
}
else {
class exit .__STYLES.`.classname'[`.styledex']
}
}
class exit `""'
end
*/
/* -------------------------------------------------------------------------*/
/* Does everything necessary to turn the current object into one that matches
the style named in the option style(name) and if necessary to initialize
the style from disk. This means that attribute of the current style
will be made to refer to the same attributes as those in the named style
(assignment by reference). Note that the current object may contain
attributes not in the style and these are unaffected by .setstyle. The
named style may also contain attributes that are not in the current object,
these cases are mentioned, but allowed.
Reads the named style from disk, if necessary.
Usage: .a.b.setstyle, style(stylename)
stylename may take one of four forms
1. the name of a named style for the current object's class
2. "scheme" to get the current scheme's default named style for
the object's class.
3. "scheme schemeid" to get the scheme's named style for schemeid
within the object's class.
4. The absolute name or objkey of an existing style whether named or
not
*/
/* internal
program setstyle
syntax [ , Style(string) FORCE ]
// di in white "setstyle .classname :`.classname': style :`style':"
if "`style'" == "" {
exit /* EXIT */
}
local style0 `style'
local style `._unabbrev `style''
// di in white ":`style':"
local clsnm = cond("`.proxy'"=="", "`.classname'", "`.proxy'")
/* possibly declare current
* style in current scheme */
if "`.`c(curscm)'.`.classname'._styles.isa'" != "array" {
capture {
if "`.`c(curscm)'.`.classname'.isa'" == "" {
.`c(curscm)'.Declare `.classname' = .null.new
}
.`c(curscm)'.`.classname'.Declare _styles = {}
.`c(curscm)'.`.classname'.Declare _refs = {}
}
if _rc {
di in white in smcl "{txt}{p 0 8} (note: could " /*
*/ "not create styles for class `.classname' in " /*
*/ "the current scheme){p_end}"
exit /* EXIT */
}
}
/*
if "`.proxy'" != "" {
if "`.`c(curscm)'.`clsnm'._styles.isa'" != "array" {
capture {
if "`.`c(curscm)'.`clsnm'.isa'" == "" {
.`c(curscm)'.Declare `clsnm' = .null.new
}
.`c(curscm)'.`clsnm'.Declare _styles = {}
.`c(curscm)'.`clsnm'.Declare _refs = {}
}
}
if _rc {
di in white in smcl "{txt}{p 0 8} (note: could " /*
*/ "not create styles for class `clsnm' in " /*
*/ "the current scheme){p_end}"
exit /* EXIT */
}
}
*/
local styles `c(curscm)'.`.classname'._styles
local refs `c(curscm)'.`.classname'._refs
/* Read names for this style from
* graphics environment if this is
* first style of this type */
if 0`.`styles'.arrnels' == 0 {
._populate_stylenames
}
/* make current object refer to
named style */
/* Handle scheme */
local style `.`c(curscm)'.style `clsnm' `style''
local i 0`.__STYLES.`.classname'.arrindexof "`style'"'
if ! `i' {
local i 0`.`styles'.arrindexof "`style'"'
}
/* not safe with multiple schemes
if `i' == 0`.styledex'
if "`.`refs'[`i'].objkey'" != "" {
exit // Exit
}
}
*/
if `i' {
if "`.`refs'[`i'].isa'" == "" {
._read_style `style' `i'
}
._restyle `i'
exit // Exit
}
else if 0`.`style'.isofclass style' {
.Restyle `style'
exit // Exit
}
di in white in smcl "{txt}{p 0 8} (note: named style `style' not " /*
*/ "{txt}found for style `.classname', default attributes used)" /*
*/ "{p_end}"
if `"`style0'"' != `"scheme"' {
.setstyle , style(scheme) // try scheme
}
/* take default values if named style not found */
end
*/
/* internal
program _unabbrev
class exit `"`0'"' // inherits may do more
end
*/
/* -------------------------------------------------------------------------*/
/* Invokes setstyle and logs the editing command to either the current
profile or the named object (must be a full name, not a key), whichever
is appropriate.
Usage: .a.b.setstyle, style(stylename) object(obj_name)
*/
program define logsetstyle
syntax , Style(string) Object(string)
.setstyle, style(`style') /* make the change */
._splitname first rest holder last : `object'
/* push onto object log */
if ! 0`.`holder'.isofclass style' | 0`.`holder'.styledex' == 0 {
.`first'.__LOG.Arrpush `rest'.setstyle , style(`style')
exit /* EXIT */
}
/* push onto scheme log */
/* expects class.style to
* already be in scheme */
.`c(curscm)'.__LOG.Arrpush /*
*/ .styles.`.`holder'.classname'.`.`holder'.stylename'.setstyle , /*
*/ style(`style')
end
/* -------------------------------------------------------------------------*/
/* Returns 1 if _styles has a list of named styles and 0 otherwise */
program define hasstyles
class exit = 0`.`c(curscm)'.`.classname'._styles.arrnels' != 0
end
/* -------------------------------------------------------------------------*/
/* Returns 1 if _styles has a list of named styles and the object's style
* index points to one of these named styles; returns 0 otherwise */
program define namedstyle
if 0`.styledex' <= 0 {
class exit = 0
}
if 0`.styledex' <= 0`.__STYLES.`.classname'.arrnels' {
class exit = 1
}
class exit = "`.`c(curscm)'.`.classname'._styles[`.styledex']'" != ""
end
/* -------------------------------------------------------------------------*/
/* Returns a list of the stylenames. */
program define stylelist
_clsarr2list list1 : .__STYLES.`.classname'
_clsarr2list list2 : .`c(curscm)'.`.classname'._styles
gettoken _placeholder list2 : list2
local list1 `list1' `list2'
local list1 : subinstr local list1 " " " " , all
class exit `"`list1'"'
end
// ---------------------------------------------------------------------------
// Returns 1 if the specified name is among the named styles for this style, 0
// otherwise.
program is_named
class exit = 0`.__STYLES.`.classname'.arrindexof "`1'"'
end
/* -------------------------------------------------------------------------*/
/* Usage: .set_styledex stylename */
program define set_styledex
if 0`.`c(curscm)'.`.classname'._styles.arrnels' == 0 {
._populate_stylenames
}
.styledex = 0`.__STYLES.`.classname'.arrindexof "`1'"'
if ! 0`.styledex' {
.styledex = 0`.`c(curscm)'.`.classname'._styles.arrindexof "`1'"'
}
end
/* -------------------------------------------------------------------------*/
/* Adds the current object to the named styles. Makes the current style one
of the newly created named styles. Each object from the style is added to
the new style by reference.
Usage: .add_style stylename
*/
program define add_style
args name
capture confirm name `name'
if _rc {
di in red `"invalid style name, `name'"'
exit
}
local dex = `.`c(curscm)'.`.classname'._styles.arrnels' + 1
.styledex = `dex'
.`c(curscm)'.`.classname'._styles[`dex'] = "`name'"
local refs `.`c(curscm)'.`.classname'._refs.objkey'
/* empty named style */
.`refs'[`dex'] = .null.new
foreach attrib_arr in instancemv dynamicmv {
forvalues i = 1/0`.`attrib_arr'.arrnels' {
_cls nameoflocal `attrib_arr'[`i']
local attrib `r(name)'
if "`attrib'" == "styledex" {
continue
}
if "`attrib'" == "from_scheme" {
continue
}
if "`attrib'" == "proxy" {
continue
}
.`refs'[`dex'].Declare `attrib' = .`attrib'.ref
}
}
end
/* -------------------------------------------------------------------------*/
/* Remakes the current style as a "copy" of itself. A new reference to each
attributute is created, but, if the attribute is a style, the reference
is to the existing named style for the attribute. if style_name is
specified, the new copy is inserted into the named styles and given the
index of that named style, otherwise, its index is set to 0.
Usage: .remake_as_copy [style_name]
Currently ignores request if the current style is already an unnamed style
(styledex==0) and no new stylename has been specified, can see no reason
for wanting such a copy.
*/
program define remake_as_copy
args stylename force
if "`stylename'" != "" {
if 0`.`c(curscm)'.`.classname'._styles.arrindexof `stylename'' {
di in red "`stylename' already defined for `.classname'"
exit 4017
}
}
if "`stylename'" == "" & 0`.styledex' == 0 & "`force'" == "" {
exit
}
foreach attrib_arr in instancemv dynamicmv {
forvalues i = 1/0`.`attrib_arr'.arrnels' {
_cls nameoflocal `attrib_arr'[`i']
local attrib `r(name)'
if "`attrib'" == "styledex" {
continue
}
if "`attrib'" == "from_scheme" {
continue
}
if "`attrib'" == "proxy" {
continue
}
if `.`attrib'.isofclass style' {
local setting `.`attrib'.snm'
if "`setting'" == "" {
local setting `.`attrib'.setting'
}
capture .`attrib'.ref = .`.`attrib'.classname'.new , ///
style(`setting')
}
else if "`.`attrib'.isa'" == "double" {
capture .`attrib'.ref = .`attrib'.copy
}
else if "`.`attrib'.isa'" == "string" {
capture .`attrib'.ref = .`attrib'.copy
}
}
}
if "`stylename'" == "" {
.styledex = 0
}
else .add_style `stylename'
end
/* -------------------------------------------------------------------------*/
/* Invokes remake_as_copy and logs the command to either the current
profile or the named object (must be a full name, not a key), whichever
is appropriate.
Usage: .log_remake object_name [style_name]
Currently ignores request if the current style is already an unnamed style
(styledex==0) and no new stylename has been specified, can see no reason
for wanting such a copy.
*/
program define log_remake
args object style
if "`stylename'" == "" & `.styledex' == 0 {
exit
}
remake_as_copy `style'
._splitname first rest holder last : `object'
if "`style'" == "" {
.`first'.__LOG.Arrpush `rest'._remake_as_copy
exit /* EXIT */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -