/dt_base.go
Go | 458 lines | 199 code | 60 blank | 199 comment | 45 complexity | aa6bc1847477cbb9028da70f64ddbb88 MD5 | raw file
- /*
- Mnemonic: dt_base.go
- Abstract: The base for all drawing things. Any dt should include an unnamed field wth the
- dt_base tpe in it's struct as the first element to pull common fields from the
- definition here. This module implements dummy functions for anything that is
- not possible with the base struct, but may be implemented by other drawing things.
- For example, Set_endpt() does nothing for Dt_rect, but is implemented by Dt_line.
- Date: 20 Apr 2018 (HBD CR)
- Author: Scott Daniels
- */
- package drawingthings
- import (
- "fmt"
- "encoding/json"
- "bitbucket.org/EScottDaniels/data_mgr"
- "bitbucket.org/EScottDaniels/sketch"
- )
- /*
- Field names must be public as we need to support json (un)packing.
- */
- type Dt_base struct {
- Id string // creator assigned id
- Kind int // one of the DT_* consts that identifies the type
- Colour string // colur name or rgb string
- Xo float64 // 'origin' point; upper left x,y or center x,y depending on thing
- Yo float64
- Scale float64 // Different things need scale info for different reasons; it's kept here
- Rot_angle float64 // rotation, degrees anti-clock with "3:00" being 0
- Rot_vertex float64 // the vertex around which rotation happens
- Visible bool
- Vis_threshold float64 // scale value below which the thing isn't painted
- updated bool // internal housekeeping that can't be set via json load etc.
- preserved_id string // default values preserved during an update
- preserved_kind int
- }
- /*
- Generic (dt) make funciton
- */
- func Mk_drawingthing(id string, kind dt_kind, xo float64, yo float64) (dt *Dt_base) {
- return &Dt_base{
- Kind: DT_BASE,
- Id: id,
- Xo: xo,
- Yo: yo,
- Colour: "#909090", // default to grey
- Rot_angle: 0, // no rotaion
- Scale: 1.0,
- }
- }
- // -----------------------------------------------------------------------------
- /*
- These are generic functions which fall into one of two categories:
- 1) dummy function that returns a nil/empty/zero value and are
- implemented such that they only need to be implemented in
- a drawingthing module if that type of thing supports the
- concept (e.g. Get_data() is only supported by graphs and
- data oriented things).
- 2) Functions which support management of the base class fields
- (e.g. setting/getting the drawingthing ID).
- Drawingthing modules are able to easily implement the interface
- by including this base structure as an unnamed field at which
- point they suppy only the interface functions that are needed
- to provide support for the thing; others are covered by the
- functions supplied here.
- */
- /*
- Contains returns true if the x,y coord passed in is within the bounding
- box of the thing. As a generic function, likely not suitable for many things,
- true is returned if the point is +/- 5 px in each direction. We expect
- that most things will override this.
- */
- func ( dt *Dt_base ) Contains( x float64, y float64 ) ( bool ) {
- if dt != nil {
- if x < dt.Xo - 5 || x > dt.Xo + 5 {
- return false
- }
- if y < dt.Yo - 5 || y > dt.Yo + 5 {
- return false
- }
- return true
- }
- return false
- }
- /*
- Get_data returns the data group associated with the drawing thing or nil
- if the drawing thing does not support/use data.
- */
- func (dt *Dt_base ) Get_data() ( *data_mgr.Data_group ) {
- return nil
- }
- /*
- Get_id returns the drawingthing's ID.
- */
- func (dt *Dt_base ) Get_id() ( string ) {
- if dt == nil {
- return "unknown-id"
- }
- return dt.Id
- }
- /*
- Get_text returns the text string associated with the drawing thing or ""
- if the drawing thing does not support/use data. This is a specialised
- form of Get_data() which relieves the caller from getting an interface
- and needing to sort out the type.
- */
- func (dt *Dt_base ) Get_text() ( string ) {
- return ""
- }
- /*
- Is_kind returns true if the kind passed in (DT_* const) is the same kind as the struct.
- */
- func (dt *Dt_base) Is_kind(kind int) bool {
- if dt == nil {
- return false
- }
- return dt.Kind == kind
- }
- /*
- Is_visible returns true if the thing's visible setting is true and the current
- value of scale is >= the vis_threshold value.
- */
- func (dt *Dt_base) Is_visible( scale float64 ) bool {
- if dt == nil {
- return false
- }
- return dt.Visible && ( scale >= dt.Vis_threshold )
- }
- /*
- Nuke will do any cleanup that is necessary.
- */
- func ( dt *Dt_base ) Nuke( sketch.Graphics_api ) {
- return
- }
- /*
- Paint causes the drawingthing to be rendered using the sketch graphics context
- which is passed in. Scale is used by drawing things only to determine visibility
- based on current display scale, and does NOT affect the rendering of the thing.
- */
- func ( dt *Dt_base ) Paint( gc sketch.Graphics_api, scale float64 ) {
- return
- }
- /*
- Rotate captures the information needed to rotate the triangle when painted.
- The rotation point is given as a vertex number (1, 2, 3 etc.); rotation is
- then computed using the coordinates of the vertex. For some drawingthings,
- the vertex 0 indicates the center, and for some the vertex is ignored as
- the thing has a single definition of rotation.
- */
- func ( dt *Dt_base ) Rotate( vertex float64, angle float64 ) {
- if dt == nil {
- return
- }
- dt.Rot_angle = angle
- dt.Rot_vertex = vertex
- dt.updated = true
- }
- /*
- Preserve allows the drawingthing to stash away information that it wants to
- ensure does not change during an update. By default we save/restore just the
- ID and kind. Each object may decide to do more and implement their own
- version of this function.
- */
- func (dt *Dt_base) Preserve() {
- if dt == nil {
- return
- }
- dt.preserved_id = dt.Id
- dt.preserved_kind = dt.Kind
- }
- /*
- Restore allows the drawing thing to restore anything preserved, and/or to force
- additional computations on the next paint assuming that something affecting
- the paint (size, location, etc.) has changed. As a default, the ID will be
- restored and the updated boolean will be marked true.
- */
- func (dt *Dt_base) Restore() {
- if dt == nil {
- return
- }
- dt.Id = dt.preserved_id
- dt.Kind = dt.preserved_kind
- dt.updated = true
- }
- /*
- Set_colur allows the drawingthing colur to be changed. For most drawingthings this is
- the outline or stroke colour, and for some drawing things (e.g. graphs) setting the
- colour likely has no effect. Cname (colouor name) can be a recognised name (e.g. green,
- red, or orange) or a hex rgb value in the form of either #rrggbb or 0xrrggbb.
- */
- func (dt *Dt_base) Set_colour(cname string) {
- if dt == nil {
- return
- }
- dt.Colour = cname
- }
- /*
- Set_data allows a new piece of data to be added to the drawing thing.
- Data is different for each drawing thing. For a graph data will be a data group
- or possibly a data set, but for a text thing, the data will likely be a string.
-
- This is a dummy function for things that don't support/use data.
- */
- func (dt *Dt_base) Set_data( data_thing interface{} ) {
- return
- }
- /*
- Set_endpt allows an x,y coordinate to be passed to the drawingthing to set/adjust
- the thing's concept of an endpoint. For a line, this is the second point and
- for multi-pointed things this probably has no effect.
- */
- func (dt *Dt_base) Set_endpt(x1 float64, y1 float64) {
- return
- }
- /*
- Set_fill allows the fill property (boolean) to be turned on or off.
- Passing true, sets the property and if the drawingthing has a concept
- of being filled, it will be filled when painted.
- */
- func (dt *Dt_base) Set_fill(state bool) {
- return
- }
- /*
- Set_fill_colour allows the fill colour to be adjusted. If the fill property is
- enabled (true) and the drawingthing supports the concept of being filled, the
- colour given will be used.
- */
- func (dt *Dt_base) Set_fill_colour(cname string) {
- return
- }
- /*
- Set_line_style allows the line style (e.g. solid, dashed) to be set for those
- drawingthings which support it.
- */
- func (dt *Dt_base) Set_line_style( style int ) {
- return
- }
- /*
- Set_origin allows the origin point to be changed effectively moving the object
- in the drawing plane. The internal updated flag is set as for some drawing things
- the change to the origin may cause a recomputation of other vertices.
- */
- func (dt *Dt_base) Set_origin(new_xo float64, new_yo float64) {
- if dt == nil {
- return
- }
- dt.updated = true
- dt.Xo = new_xo
- dt.Yo = new_yo
- }
- /*
- Set_delta_hw allows the height and width of a datathing to be changed by relative
- value. If the drawing thing supporst the concept of height and width, each are
- adjusted by adding the delta values passed to this funciton to the current height
- and width of the thing.
- */
- func (dt *Dt_base) Set_delta_hw( dheight float64, dwidth float64 ) {
- return
- }
- /*
- Set_delta_length allows the length of a drawing thing to be changed by a
- relative value. If the drawingthing supports the concept of length, it is
- adjusted by adding the value passed to this function.
- */
- func (dt *Dt_base) Set_delta_length( length float64 ) {
- return
- }
- /*
- Set_hw allows the absolute height and width of the drawing thing to be set
- provided the drawing thing supports the concept of height and width.
- */
- func (dt *Dt_base) Set_hw( height float64, width float64 ) {
- return
- }
- /*
- Set_hw allows the absolute length of the drawing thing to be set
- provided the drawing thing supports the concept of length.
- */
- func (dt *Dt_base) Set_length( length float64 ) {
- return
- }
- /*
- Set_rel_origin changes the origin for the DT by adding the delta values
- to the current origin values.
- */
- func (dt *Dt_base) Set_rel_origin(delta_xo float64, delta_yo float64) {
- if dt == nil {
- return
- }
- dt.Xo += delta_xo
- dt.Yo += delta_yo
- }
- /*
- Set_iscale sets the painting scale for the drawingthing. The value passed is
- added to the current setting rather than used as an absolute. Some things, like graphs,
- might need to reset themselves if the scale is changed.
- See note about scale in drawingthing.go.
- */
- func ( dt *Dt_base ) Set_iscale( increment float64 ) {
- if dt != nil {
- dt.Scale += increment
- dt.updated = true
- }
- }
- /*
- Set_scale sets the painting scale for the drawingthing. Some things, like graphs,
- might need to reset themselves if the scale is changed.
- See note about scale in drawingthing.go.
- */
- func ( dt *Dt_base ) Set_scale( new_scale float64 ) {
- if dt != nil {
- dt.Scale = new_scale
- dt.updated = true
- }
- }
- /*
- Set_vis_threshold sets the scale threshold below which a drawing
- thing will not be painted. If the threshold is set to 2.0, then
- when the current scale is < 2.0 the effect will be to hide the thing.
- */
- func ( dt *Dt_base ) Set_vis_threshold( new_t float64 ) {
- if dt != nil {
- dt.Vis_threshold = new_t
- }
- }
- /*
- Set_updated toggles the internal updated flag.
- */
- func (dt *Dt_base) Set_updated(state bool) {
- if dt == nil {
- return
- }
- dt.updated = true
- }
- /*
- Set_visibility allows the visible flag to be toggled. If the thing isn't visible
- it shouldn't paint.
- */
- func (dt *Dt_base) Set_visibility(state bool) {
- if dt == nil {
- return
- }
- dt.Visible = state
- }
- /*
- String implements the stringer interface allowing the object to be passed to
- fmt.*() functions etc. We get lazy and just bang the struct into json.
- */
- func (dt *Dt_base) String() string {
- if dt == nil {
- return "<nil>"
- }
- jb, err := json.Marshal( dt )
- if err == nil {
- return string( jb )
- }
- return fmt.Sprintf( "dt: error converting to string: %s", err )
- }
- /*
- Find the value in the map, and if it's there return it, else return the default.
- func (dt *Dt_base) update_value(data map[string]string, field string, def_val interface{}) interface{} {
- if dt == nil {
- return def_val
- }
- dv, ok := data[field] // pull data value if there
- if !ok {
- return def_val
- }
- dt.updated = true
- return str2value(dv, def_val)
- }
- */
- /*
- A tickle from the outside world. data contains needed information in a format
- that is unique to the underlying thing.
- */
- func ( dt *Dt_base ) Tickle( data interface{} ) {
- return
- }
- /*
- To_json converts the underlying drawing thing into a json blob in a string, and retruns it
- */
- func ( dt *Dt_base ) To_json( ) ( string, error ) {
- if dt == nil {
- return "{}", nil
- }
- jbytes, err := json.Marshal( dt )
- if err == nil {
- return string( jbytes ), nil
- } else {
- return "", err
- }
- }