9fans.net/go@v0.0.5/draw/frame/frinit.go (about)

     1  package frame
     2  
     3  import (
     4  	"9fans.net/go/draw"
     5  )
     6  
     7  // Init prepares the frame f so characters drawn in it
     8  // will appear in the font ft.
     9  // It then calls SetRects and InitTick to initialize the geometry for the frame.
    10  // The image b is where the frame is to be drawn;
    11  // the rectangle r defines the limit of the portion of the
    12  // image the text will occupy.
    13  // The image pointer may be null,
    14  // allowing the other routines to be called to maintain the
    15  // associated data structure in, for example, an obscured window.
    16  // The array of images cols sets the colors in which text and
    17  // borders will be drawn.  The background of the frame will be
    18  // drawn in cols[BACK]; the background of highlighted text in
    19  // cols[HIGH]; borders and scroll bar in cols[BORD]; regular
    20  // text in cols[TEXT]; and highlighted text in cols[HTEXT].
    21  func (f *Frame) Init(r draw.Rectangle, ft *draw.Font, b *draw.Image, cols []*draw.Image) {
    22  	f.Font = ft
    23  	f.Display = b.Display
    24  	f.MaxTab = 8 * ft.StringWidth("0")
    25  	f.box = nil
    26  	f.NumChars = 0
    27  	f.NumLines = 0
    28  	f.P0 = 0
    29  	f.P1 = 0
    30  	f.LastLineFull = false
    31  	copy(f.Cols[:], cols)
    32  	f.SetRects(r, b)
    33  	if f.tick == nil && f.Cols[BACK] != nil {
    34  		f.InitTick()
    35  	}
    36  }
    37  
    38  // InitTick initializes the frame's tick images.
    39  // It is called during the Init method and must be called again
    40  // each time the frame's font changes.
    41  func (f *Frame) InitTick() {
    42  	if f.Cols[BACK] == nil || f.Display == nil {
    43  		return
    44  	}
    45  	f.tickscale = f.Display.ScaleSize(1)
    46  	b := f.Display.ScreenImage
    47  	if b == nil {
    48  		drawerror(f.Display, "missing screenimage")
    49  	}
    50  	ft := f.Font
    51  	if f.tick != nil {
    52  		f.tick.Free()
    53  	}
    54  	f.tick, _ = f.Display.AllocImage(draw.Rect(0, 0, f.tickscale*_FRTICKW, ft.Height), b.Pix, false, draw.White)
    55  	if f.tick == nil {
    56  		return
    57  	}
    58  	if f.tickback != nil {
    59  		f.tickback.Free()
    60  	}
    61  	f.tickback, _ = f.Display.AllocImage(f.tick.R, b.Pix, false, draw.White)
    62  	if f.tickback == nil {
    63  		f.tick.Free()
    64  		f.tick = nil
    65  		return
    66  	}
    67  
    68  	// background color
    69  	f.tick.Draw(f.tick.R, f.Cols[BACK], nil, draw.ZP)
    70  	// vertical line
    71  	f.tick.Draw(draw.Rect(f.tickscale*(_FRTICKW/2), 0, f.tickscale*(_FRTICKW/2+1), ft.Height), f.Display.Black, nil, draw.ZP)
    72  	// box on each end
    73  	f.tick.Draw(draw.Rect(0, 0, f.tickscale*_FRTICKW, f.tickscale*_FRTICKW), f.Cols[TEXT], nil, draw.ZP)
    74  	f.tick.Draw(draw.Rect(0, ft.Height-f.tickscale*_FRTICKW, f.tickscale*_FRTICKW, ft.Height), f.Cols[TEXT], nil, draw.ZP)
    75  }
    76  
    77  func (f *Frame) SetRects(r draw.Rectangle, b *draw.Image) {
    78  	f.B = b
    79  	f.Entire = r
    80  	f.R = r
    81  	f.R.Max.Y -= (r.Max.Y - r.Min.Y) % f.Font.Height
    82  	f.MaxLines = (r.Max.Y - r.Min.Y) / f.Font.Height
    83  }
    84  
    85  // Clear frees the internal structures associated with f,
    86  // permitting another Init or SetRects on the Frame.
    87  // It does not clear the associated display.
    88  // If f is to be deallocated, the associated Font and Image (as passed to Init)
    89  // must be freed separately.
    90  // The newFont argument should be true if the frame is to be
    91  // redrawn with a different font; otherwise the frame will
    92  // maintain some data structures associated with the font.
    93  //
    94  // To resize a frame, use Clear and Init and then Insert
    95  // to recreate the display. If a frame is being moved
    96  // but not resized, that is, if the shape of its containing
    97  // rectangle is unchanged, it is sufficient to use Draw on the
    98  // underlying image to copy the containing rectangle
    99  // from the old to the new location and then call SetRects
   100  // to establish the new geometry.
   101  // (It is unnecessary to call frinittick unless the font size
   102  // has changed.)  No redrawing is necessary.
   103  func (f *Frame) Clear(newFont bool) {
   104  	if len(f.box) > 0 {
   105  		f.delbox(0, len(f.box)-1)
   106  	}
   107  	f.box = nil
   108  	f.Ticked = false
   109  	if newFont {
   110  		f.tick.Free()
   111  		f.tickback.Free()
   112  		f.tick = nil
   113  		f.tickback = nil
   114  	}
   115  }