tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/examples/ft6336/touchpaint/main.go (about)

     1  package main
     2  
     3  import (
     4  	"image/color"
     5  	"math"
     6  
     7  	"tinygo.org/x/drivers"
     8  	"tinygo.org/x/drivers/touch"
     9  )
    10  
    11  type touchPaintDisplay interface {
    12  	drivers.Displayer
    13  	FillRectangle(x, y, width, height int16, c color.RGBA) error
    14  	DrawRectangle(x, y, w, h int16, c color.RGBA) error
    15  }
    16  
    17  var (
    18  	white   = color.RGBA{255, 255, 255, 255}
    19  	black   = color.RGBA{0, 0, 0, 255}
    20  	red     = color.RGBA{255, 0, 0, 255}
    21  	green   = color.RGBA{0, 255, 0, 255}
    22  	blue    = color.RGBA{0, 0, 255, 255}
    23  	magenta = color.RGBA{255, 0, 255, 255}
    24  	yellow  = color.RGBA{255, 255, 0, 255}
    25  	cyan    = color.RGBA{0, 255, 255, 255}
    26  
    27  	oldColor     color.RGBA
    28  	currentColor color.RGBA
    29  )
    30  
    31  const (
    32  	penRadius = 3
    33  	boxSize   = 30
    34  
    35  	Xmin = 0
    36  	Xmax = 0xFFFF
    37  	Ymin = 0
    38  	Ymax = 0xFFFF
    39  )
    40  
    41  func main() {
    42  	display, resistiveTouch, _ := initDevices()
    43  
    44  	// fill the background and activate the backlight
    45  	width, height := display.Size()
    46  	display.FillRectangle(0, 0, width, height, black)
    47  
    48  	// make color selection boxes
    49  	display.FillRectangle(0, 0, boxSize, boxSize, red)
    50  	display.FillRectangle(boxSize, 0, boxSize, boxSize, yellow)
    51  	display.FillRectangle(boxSize*2, 0, boxSize, boxSize, green)
    52  	display.FillRectangle(boxSize*3, 0, boxSize, boxSize, cyan)
    53  	display.FillRectangle(boxSize*4, 0, boxSize, boxSize, blue)
    54  	display.FillRectangle(boxSize*5, 0, boxSize, boxSize, magenta)
    55  	display.FillRectangle(boxSize*6, 0, boxSize, boxSize, black)
    56  	display.FillRectangle(boxSize*7, 0, boxSize, boxSize, white)
    57  
    58  	// set the initial color to red and draw a box to highlight it
    59  	oldColor = red
    60  	currentColor = red
    61  	display.DrawRectangle(0, 0, boxSize, boxSize, white)
    62  
    63  	last := touch.Point{}
    64  
    65  	// loop and poll for touches, including performing debouncing
    66  	debounce := 0
    67  	for {
    68  
    69  		point := resistiveTouch.ReadTouchPoint()
    70  		touch := touch.Point{}
    71  		if point.Z>>6 > 100 {
    72  			rawX := mapval(point.X, Xmin, Xmax, 0, int(width))
    73  			rawY := mapval(point.Y, Ymin, Ymax, 0, int(height))
    74  			touch.X = rawX
    75  			touch.Y = rawY
    76  			touch.Z = 1
    77  		} else {
    78  			touch.X = 0
    79  			touch.Y = 0
    80  			touch.Z = 0
    81  		}
    82  
    83  		if last.Z != touch.Z {
    84  			debounce = 0
    85  			last = touch
    86  		} else if math.Abs(float64(touch.X-last.X)) > 4 ||
    87  			math.Abs(float64(touch.Y-last.Y)) > 4 {
    88  			debounce = 0
    89  			last = touch
    90  		} else if debounce > 1 {
    91  			debounce = 0
    92  			HandleTouch(display, last)
    93  		} else if touch.Z > 0 {
    94  			debounce++
    95  		} else {
    96  			last = touch
    97  			debounce = 0
    98  		}
    99  
   100  	}
   101  }
   102  
   103  // based on Arduino's "map" function
   104  func mapval(x int, inMin int, inMax int, outMin int, outMax int) int {
   105  	return (x-inMin)*(outMax-outMin)/(inMax-inMin) + outMin
   106  }
   107  
   108  func HandleTouch(display touchPaintDisplay, touch touch.Point) {
   109  
   110  	if int16(touch.Y) < boxSize {
   111  		oldColor = currentColor
   112  		x := int16(touch.X)
   113  		switch {
   114  		case x < boxSize:
   115  			currentColor = red
   116  		case x < boxSize*2:
   117  			currentColor = yellow
   118  		case x < boxSize*3:
   119  			currentColor = green
   120  		case x < boxSize*4:
   121  			currentColor = cyan
   122  		case x < boxSize*5:
   123  			currentColor = blue
   124  		case x < boxSize*6:
   125  			currentColor = magenta
   126  		case x < boxSize*7:
   127  			currentColor = black
   128  		case x < boxSize*8:
   129  			currentColor = white
   130  		}
   131  
   132  		if oldColor == currentColor {
   133  			return
   134  		}
   135  
   136  		display.DrawRectangle((x/boxSize)*boxSize, 0, boxSize, boxSize, white)
   137  		switch oldColor {
   138  		case red:
   139  			x = 0
   140  		case yellow:
   141  			x = boxSize
   142  		case green:
   143  			x = boxSize * 2
   144  		case cyan:
   145  			x = boxSize * 3
   146  		case blue:
   147  			x = boxSize * 4
   148  		case magenta:
   149  			x = boxSize * 5
   150  		case black:
   151  			x = boxSize * 6
   152  		case white:
   153  			x = boxSize * 7
   154  		}
   155  		display.FillRectangle(int16(x), 0, boxSize, boxSize, oldColor)
   156  
   157  	}
   158  
   159  	if (int16(touch.Y) - penRadius) > boxSize {
   160  		display.FillRectangle(
   161  			int16(touch.X), int16(touch.Y), penRadius*2, penRadius*2, currentColor)
   162  	}
   163  }