294 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			294 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#  UPIWIN - Micro Pi Windowing Framework Kernel
 | 
						|
#  Copyright (C) 2019 Amy Bowersox/Erbosoft Metaverse Design Solutions
 | 
						|
#
 | 
						|
#  This program is free software; you can redistribute it and/or modify
 | 
						|
#  it under the terms of the GNU General Public License as published by
 | 
						|
#  the Free Software Foundation; either version 2 of the License, or
 | 
						|
#  (at your option) any later version.
 | 
						|
#
 | 
						|
#  This program is distributed in the hope that it will be useful,
 | 
						|
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
#  GNU General Public License for more details.
 | 
						|
#
 | 
						|
#  You should have received a copy of the GNU General Public License along
 | 
						|
#  with this program; if not, write to the Free Software Foundation, Inc.,
 | 
						|
#  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
						|
#  ------------------------------------------------------------------------
 | 
						|
#  Demo script that implements a simple drawing program
 | 
						|
import upiwin
 | 
						|
 | 
						|
# Save off some color values.
 | 
						|
BLACK = upiwin.rgb(0, 0, 0)
 | 
						|
WHITE = upiwin.rgb(255, 255, 255)
 | 
						|
LTGRAY = upiwin.rgb(204, 204, 204)
 | 
						|
RED = upiwin.rgb(255, 0, 0)
 | 
						|
GREEN = upiwin.rgb(0, 255, 0)
 | 
						|
BLUE = upiwin.rgb(0, 0, 255)
 | 
						|
CYAN = upiwin.rgb(0, 255, 255)
 | 
						|
MAGENTA = upiwin.rgb(255, 0, 255)
 | 
						|
YELLOW = upiwin.rgb(255, 255, 0)
 | 
						|
 | 
						|
# Get the stock bitmaps.
 | 
						|
bmp_freehand = upiwin.Bitmap(stock='freehand')
 | 
						|
bmp_line = upiwin.Bitmap(stock='line')
 | 
						|
bmp_rect = upiwin.Bitmap(stock='rect')
 | 
						|
bmp_fillrect = upiwin.Bitmap(stock='fillrect')
 | 
						|
bmp_undo = upiwin.Bitmap(stock='undo')
 | 
						|
bmp_clear = upiwin.Bitmap(stock='clear')
 | 
						|
 | 
						|
hdc = upiwin.DevCtxt(type='screen')
 | 
						|
hdc_bits = upiwin.DevCtxt(type='memory')
 | 
						|
 | 
						|
# divide the screen into "drawing" and "command" areas
 | 
						|
screen_rect = hdc.get_clip_rect()
 | 
						|
drawing_rect = (screen_rect[0], screen_rect[1], screen_rect[2] - 60, screen_rect[3])
 | 
						|
command_rect = (drawing_rect[2], screen_rect[1], screen_rect[2], screen_rect[3])
 | 
						|
 | 
						|
# further divide up the "command" area
 | 
						|
tool_select_rect = (command_rect[0], command_rect[1], command_rect[2], 60)
 | 
						|
color_select_rect = (command_rect[0], 60, command_rect[2], 120)
 | 
						|
undo_rect = (command_rect[0], 120, command_rect[2], 180)
 | 
						|
clear_rect = (command_rect[0], 180, command_rect[2], command_rect[3])
 | 
						|
 | 
						|
def point_in_rect(rect, x, y):
 | 
						|
	return (x >= rect[0]) and (x < rect[2]) and (y >= rect[1]) and (y < rect[3])
 | 
						|
	
 | 
						|
# --- Backlight control ---
 | 
						|
 | 
						|
backlight_level_list = [1023, 768, 512, 256]
 | 
						|
current_backlight = 0
 | 
						|
 | 
						|
def do_backlight():
 | 
						|
	upiwin.set_backlight_level(backlight_level_list[current_backlight])
 | 
						|
	
 | 
						|
def select_next_backlight():
 | 
						|
	global current_backlight
 | 
						|
	current_backlight += 1
 | 
						|
	if current_backlight == len(backlight_level_list):
 | 
						|
		current_backlight = 0
 | 
						|
	do_backlight()
 | 
						|
 | 
						|
# --- Color selections ---
 | 
						|
 | 
						|
color_list = [WHITE, RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW]
 | 
						|
current_color = 0
 | 
						|
 | 
						|
def draw_current_color():
 | 
						|
	hdc.text_color = color_list[current_color]
 | 
						|
	hdc.rop2 = upiwin.R2_COPYPEN
 | 
						|
	hdc.solid_rectangle(color_select_rect[0] + 6, color_select_rect[1] + 6, color_select_rect[0] + 54, color_select_rect[1] + 54)
 | 
						|
	
 | 
						|
def select_next_color():
 | 
						|
	global current_color
 | 
						|
	current_color += 1
 | 
						|
	if current_color == len(color_list):
 | 
						|
		current_color = 0
 | 
						|
	draw_current_color()
 | 
						|
 | 
						|
# --- Object drawing ---
 | 
						|
 | 
						|
def draw_freehand(color, data):
 | 
						|
	hdc.text_color = color
 | 
						|
	hdc.rop2 = upiwin.R2_COPYPEN
 | 
						|
	hdc.move_to(data[0][0], data[0][1])
 | 
						|
	for pt in data[1:]:
 | 
						|
		hdc.line_to(pt[0], pt[1])
 | 
						|
		
 | 
						|
def draw_line(color, data):
 | 
						|
	hdc.text_color = color
 | 
						|
	hdc.rop2 = upiwin.R2_COPYPEN
 | 
						|
	hdc.move_to(data[0][0], data[0][1])
 | 
						|
	hdc.line_to(data[1][0], data[1][1])
 | 
						|
	
 | 
						|
def draw_rectangle(color, data):
 | 
						|
	hdc.text_color = color
 | 
						|
	hdc.rop2 = upiwin.R2_COPYPEN
 | 
						|
	hdc.rectangle(data[0], data[1], data[2], data[3])
 | 
						|
 | 
						|
def draw_filled_rectangle(color, data):
 | 
						|
	hdc.text_color = color
 | 
						|
	hdc.rop2 = upiwin.R2_COPYPEN
 | 
						|
	hdc.solid_rectangle(data[0], data[1], data[2], data[3])
 | 
						|
	
 | 
						|
def draw_object(obj):
 | 
						|
	obj['draw'](obj['color'], obj['data'])
 | 
						|
 | 
						|
# --- Master object list ---
 | 
						|
 | 
						|
objects_drawn = []
 | 
						|
 | 
						|
def repaint():
 | 
						|
	global drawing_rect, objects_drawn
 | 
						|
	hdc.text_color = BLACK
 | 
						|
	hdc.rop2 = upiwin.R2_COPYPEN
 | 
						|
	hdc.solid_rectangle(drawing_rect[0], drawing_rect[1], drawing_rect[2], drawing_rect[3])
 | 
						|
	for obj in objects_drawn:
 | 
						|
		draw_object(obj)
 | 
						|
		
 | 
						|
def undo_last():
 | 
						|
	global objects_drawn
 | 
						|
	if len(objects_drawn) > 0:
 | 
						|
		last = len(objects_drawn) - 1
 | 
						|
		del objects_drawn[last]
 | 
						|
		repaint()
 | 
						|
		
 | 
						|
def clear_all():
 | 
						|
	global objects_drawn
 | 
						|
	if len(objects_drawn) > 0:
 | 
						|
		objects_drawn.clear()
 | 
						|
		repaint()
 | 
						|
 | 
						|
# --- Graphic feedback --
 | 
						|
 | 
						|
origin_x = 0
 | 
						|
origin_y = 0
 | 
						|
current_x = 0
 | 
						|
current_y = 0
 | 
						|
freehand_points = []
 | 
						|
 | 
						|
def freehand_draw(x, y, down, up):
 | 
						|
	global current_x, current_y, freehand_points
 | 
						|
	if down:
 | 
						|
		freehand_points = []
 | 
						|
	else:
 | 
						|
		hdc.text_color = color_list[current_color]
 | 
						|
		hdc.rop2 = upiwin.R2_COPYPEN
 | 
						|
		hdc.move_to(current_x, current_y)
 | 
						|
		hdc.line_to(x, y)
 | 
						|
	current_x = x
 | 
						|
	current_y = y
 | 
						|
	freehand_points += [(x, y)]
 | 
						|
 | 
						|
def rubberband_rectangle(x, y, down, up):
 | 
						|
	global current_x, current_y
 | 
						|
	hdc.text_color = LTGRAY
 | 
						|
	hdc.rop2 = upiwin.R2_XORPEN
 | 
						|
	if not down:
 | 
						|
		hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y))
 | 
						|
	current_x = x
 | 
						|
	current_y = y
 | 
						|
	if not up:
 | 
						|
		hdc.rectangle(min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y))
 | 
						|
 | 
						|
def rubberband_line(x, y, down, up):
 | 
						|
	global current_x, current_y
 | 
						|
	hdc.text_color = LTGRAY
 | 
						|
	hdc.rop2 = upiwin.R2_XORPEN
 | 
						|
	if not down:
 | 
						|
		hdc.move_to(origin_x, origin_y)
 | 
						|
		hdc.line_to(current_x, current_y)
 | 
						|
	current_x = x
 | 
						|
	current_y = y
 | 
						|
	if not up:
 | 
						|
		hdc.move_to(origin_x, origin_y)
 | 
						|
		hdc.line_to(current_x, current_y)
 | 
						|
 | 
						|
# --- Tool definitions ---
 | 
						|
 | 
						|
def save_freehand():
 | 
						|
	return { 'draw': draw_freehand, 'color': color_list[current_color], 'data': freehand_points }
 | 
						|
	
 | 
						|
def save_line():
 | 
						|
	return { 'draw': draw_line, 'color': color_list[current_color], 'data': [(origin_x, origin_y), (current_x, current_y)] }
 | 
						|
	
 | 
						|
def save_rectangle():
 | 
						|
	return { 'draw': draw_rectangle, 'color': color_list[current_color],
 | 
						|
			 'data': (min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) }
 | 
						|
 | 
						|
def save_filled_rectangle():
 | 
						|
	return { 'draw': draw_filled_rectangle, 'color': color_list[current_color],
 | 
						|
			 'data': (min(origin_x, current_x), min(origin_y, current_y), max(origin_x, current_x), max(origin_y, current_y)) }
 | 
						|
 | 
						|
tool_list = [
 | 
						|
	{ 'icon': bmp_freehand, 'feedback': freehand_draw, 'save': save_freehand, 'dodraw': False },
 | 
						|
	{ 'icon': bmp_line, 'feedback': rubberband_line, 'save': save_line, 'dodraw': True },
 | 
						|
	{ 'icon': bmp_rect, 'feedback': rubberband_rectangle, 'save': save_rectangle, 'dodraw': True },
 | 
						|
	{ 'icon': bmp_fillrect, 'feedback': rubberband_rectangle, 'save': save_filled_rectangle, 'dodraw': True }
 | 
						|
	]
 | 
						|
 | 
						|
current_tool = 0
 | 
						|
 | 
						|
def draw_current_tool():
 | 
						|
	hdc_bits.select_object(tool_list[current_tool]['icon'])
 | 
						|
	hdc.bitblt(tool_select_rect[0] + 6, tool_select_rect[1] + 6, tool_select_rect[0] + 54, tool_select_rect[1] + 54, hdc_bits, 0, 0, 0)
 | 
						|
	
 | 
						|
def select_next_tool():
 | 
						|
	global current_tool
 | 
						|
	current_tool += 1
 | 
						|
	if current_tool == len(tool_list):
 | 
						|
		current_tool = 0
 | 
						|
	draw_current_tool()
 | 
						|
 | 
						|
# --- Message handlers ---
 | 
						|
 | 
						|
def on_touchdown(x, y):
 | 
						|
	global origin_x, origin_y
 | 
						|
	if point_in_rect(drawing_rect, x, y):
 | 
						|
		origin_x = x
 | 
						|
		origin_y = y
 | 
						|
		tool_list[current_tool]['feedback'](x, y, True, False)
 | 
						|
		
 | 
						|
def on_touchmove(x, y):
 | 
						|
	if point_in_rect(drawing_rect, x, y):
 | 
						|
		tool_list[current_tool]['feedback'](x, y, False, False)
 | 
						|
		
 | 
						|
def on_touchup(x, y):
 | 
						|
	global objects_drawn
 | 
						|
	if point_in_rect(drawing_rect, x, y):
 | 
						|
		tool_list[current_tool]['feedback'](x, y, False, True)
 | 
						|
		object = tool_list[current_tool]['save']()
 | 
						|
		if tool_list[current_tool]['dodraw']:
 | 
						|
			draw_object(object)
 | 
						|
		objects_drawn += [object]
 | 
						|
 | 
						|
def on_touchclick(x, y):
 | 
						|
	if point_in_rect(tool_select_rect, x, y):
 | 
						|
		select_next_tool()
 | 
						|
	elif point_in_rect(color_select_rect, x, y):
 | 
						|
		select_next_color()
 | 
						|
	elif point_in_rect(undo_rect, x, y):
 | 
						|
		undo_last()
 | 
						|
	elif point_in_rect(clear_rect, x, y):
 | 
						|
		clear_all()
 | 
						|
 | 
						|
def on_button_click(button):
 | 
						|
	if button == 1:			# Button 1 = Set backlight level
 | 
						|
		select_next_backlight()
 | 
						|
	if button == 4:			# Button 4 = Exit app
 | 
						|
		upiwin.post_quit_message(0)
 | 
						|
 | 
						|
# --- Initialize and start message loop ---
 | 
						|
 | 
						|
do_backlight()
 | 
						|
 | 
						|
# Draw the basic layout.
 | 
						|
hdc.text_color = LTGRAY
 | 
						|
hdc.rop2 = upiwin.R2_COPYPEN
 | 
						|
hdc.rectangle(tool_select_rect[0], tool_select_rect[1], tool_select_rect[2], tool_select_rect[3])
 | 
						|
hdc.rectangle(color_select_rect[0], color_select_rect[1], color_select_rect[2], color_select_rect[3])
 | 
						|
hdc.rectangle(undo_rect[0], undo_rect[1], undo_rect[2], undo_rect[3])
 | 
						|
hdc.rectangle(clear_rect[0], clear_rect[1], clear_rect[2], clear_rect[3])
 | 
						|
 | 
						|
draw_current_tool()
 | 
						|
draw_current_color()
 | 
						|
 | 
						|
hdc_bits.select_object(bmp_undo)
 | 
						|
hdc.bitblt(undo_rect[0] + 6, undo_rect[1] + 6, undo_rect[0] + 54, undo_rect[1] + 54, hdc_bits, 0, 0, 0)
 | 
						|
hdc_bits.select_object(bmp_clear)
 | 
						|
hdc.bitblt(clear_rect[0] + 6, clear_rect[1] + 6, clear_rect[0] + 54, clear_rect[1] + 54, hdc_bits, 0, 0, 0)
 | 
						|
 | 
						|
# Main message loop
 | 
						|
msg = {}
 | 
						|
while upiwin.get_message(msg):
 | 
						|
	if msg['message'] == upiwin.WM_TOUCHDOWN:
 | 
						|
		on_touchdown(msg['attrs'][0], msg['attrs'][1])
 | 
						|
	if msg['message'] == upiwin.WM_TOUCHMOVE:
 | 
						|
		on_touchmove(msg['attrs'][0], msg['attrs'][1])
 | 
						|
	if msg['message'] == upiwin.WM_TOUCHUP:
 | 
						|
		on_touchup(msg['attrs'][0], msg['attrs'][1])
 | 
						|
	if msg['message'] == upiwin.WM_TOUCHCLICK:
 | 
						|
		on_touchclick(msg['attrs'][0], msg['attrs'][1])
 | 
						|
	elif msg['message'] == upiwin.WM_HWBUTTONCLICK:
 | 
						|
		on_button_click(msg['attrs'][0])
 |