# 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])