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 }