Restarting from scratch using a code with wxpython
This commit is contained in:
parent
90bd1bb089
commit
5fcdad61ee
208
main.c
208
main.c
@ -1,208 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <SDL.h>
|
|
||||||
|
|
||||||
#define WIDTH_CONTROL 100
|
|
||||||
|
|
||||||
#ifndef min
|
|
||||||
#define min(a, b) ((a < b) ? a : b)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void setPixel(SDL_Surface *affichage, int x, int y, Uint16 coul)
|
|
||||||
{
|
|
||||||
*((Uint16**)(affichage->pixels) + x + y * affichage->w) = coul;
|
|
||||||
}
|
|
||||||
|
|
||||||
void echangerEntiers(int* x, int* y)
|
|
||||||
{
|
|
||||||
int t = *x;
|
|
||||||
*x = *y;
|
|
||||||
*y = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawLine(SDL_Surface *affichage, int x1, int y1, int x2, int y2, Uint32 coul) //Draw line using Bresenham algorithm
|
|
||||||
{
|
|
||||||
int d, dx, dy, aincr, bincr, xincr, yincr, x, y;
|
|
||||||
|
|
||||||
if(x1 == x2 || y1 == y2) //If horizontal or vertical, use the SDL library optimized function
|
|
||||||
{
|
|
||||||
SDL_Rect r;
|
|
||||||
|
|
||||||
r.x = min(x1, x2);
|
|
||||||
r.y = min(y1, y2);
|
|
||||||
r.w = (x1 == x2) ? 1 : abs(x1 - x2);
|
|
||||||
r.h = (y1 == y2) ? 1 : abs(y1 - y2);
|
|
||||||
|
|
||||||
SDL_FillRect(affichage, &r, coul);
|
|
||||||
}
|
|
||||||
else if (abs(x2 - x1) < abs(y2 - y1)) //Go through vertical axis
|
|
||||||
{
|
|
||||||
if (y1 > y2)
|
|
||||||
{
|
|
||||||
echangerEntiers(&x1, &x2);
|
|
||||||
echangerEntiers(&y1, &y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
xincr = x2 > x1 ? 1 : -1;
|
|
||||||
dy = y2 - y1;
|
|
||||||
dx = abs(x2 - x1);
|
|
||||||
d = 2 * dx - dy;
|
|
||||||
aincr = 2 * (dx - dy);
|
|
||||||
bincr = 2 * dx;
|
|
||||||
x = x1;
|
|
||||||
y = y1;
|
|
||||||
|
|
||||||
setPixel(affichage, x, y, coul);
|
|
||||||
|
|
||||||
for (y = y1+1; y <= y2; ++y)
|
|
||||||
{
|
|
||||||
if (d >= 0)
|
|
||||||
{
|
|
||||||
x += xincr;
|
|
||||||
d += aincr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
d += bincr;
|
|
||||||
|
|
||||||
setPixel(affichage, x, y, coul);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else //Go through horizontal axis
|
|
||||||
{
|
|
||||||
|
|
||||||
if (x1 > x2)
|
|
||||||
{
|
|
||||||
echangerEntiers(&x1, &x2);
|
|
||||||
echangerEntiers(&y1, &y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
yincr = y2 > y1 ? 1 : -1;
|
|
||||||
dx = x2 - x1;
|
|
||||||
dy = abs(y2 - y1);
|
|
||||||
d = 2 * dy - dx;
|
|
||||||
aincr = 2 * (dy - dx);
|
|
||||||
bincr = 2 * dy;
|
|
||||||
x = x1;
|
|
||||||
y = y1;
|
|
||||||
|
|
||||||
setPixel(affichage, x, y, coul);
|
|
||||||
|
|
||||||
for (x = x1+1; x <= x2; ++x)
|
|
||||||
{
|
|
||||||
if (d >= 0)
|
|
||||||
{
|
|
||||||
y+= yincr;
|
|
||||||
d += aincr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
d += bincr;
|
|
||||||
setPixel(affichage, x, y, coul);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int continuer = 1;
|
|
||||||
int x_old = -1, y_old = -1;
|
|
||||||
int left = 0;
|
|
||||||
SDL_Event event;
|
|
||||||
SDL_Surface *ecran = NULL, *controles = NULL;
|
|
||||||
|
|
||||||
if(-1 == SDL_Init(SDL_INIT_VIDEO))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Erreur de chargement de la SDL : %s\n", SDL_GetError());
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
const SDL_VideoInfo* video_info = SDL_GetVideoInfo();
|
|
||||||
int width = video_info->current_w;
|
|
||||||
int height = video_info->current_h;
|
|
||||||
int bpp = 16; //video_info ->vfmt->BitsPerPixel;
|
|
||||||
|
|
||||||
SDL_Rect position_controles = {width - WIDTH_CONTROL, 0};
|
|
||||||
|
|
||||||
ecran = SDL_SetVideoMode(width, height, bpp, SDL_HWSURFACE | SDL_FULLSCREEN); //Raspi has only a 16 bpp framebuffer
|
|
||||||
controles = SDL_CreateRGBSurface(SDL_HWSURFACE, WIDTH_CONTROL, height, bpp, 0, 0, 0, 0);
|
|
||||||
|
|
||||||
if(NULL == ecran || NULL == controles || NULL == ecran)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Erreur d'ouverture de la SDL : %s\n", SDL_GetError());
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
|
|
||||||
SDL_FillRect(controles, NULL, SDL_MapRGB(controles->format, 100, 100, 100));
|
|
||||||
SDL_BlitSurface(controles, NULL, ecran, &position_controles);
|
|
||||||
|
|
||||||
SDL_Flip(ecran);
|
|
||||||
|
|
||||||
while(continuer)
|
|
||||||
{
|
|
||||||
SDL_WaitEvent(&event);
|
|
||||||
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
|
||||||
if(event.button.x < width - WIDTH_CONTROL)
|
|
||||||
{
|
|
||||||
if(SDL_BUTTON_LEFT == event.button.button)
|
|
||||||
{
|
|
||||||
left = 1;
|
|
||||||
x_old = event.button.x;
|
|
||||||
y_old = event.button.y;
|
|
||||||
}
|
|
||||||
else if(SDL_BUTTON_RIGHT == event.button.button)
|
|
||||||
{
|
|
||||||
left = 0;
|
|
||||||
x_old = event.button.x;
|
|
||||||
y_old = event.button.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_MOUSEMOTION:
|
|
||||||
if(event.motion.x < width - WIDTH_CONTROL)
|
|
||||||
{
|
|
||||||
if(x_old > 0 && y_old > 0)
|
|
||||||
{
|
|
||||||
if(left)
|
|
||||||
DrawLine(ecran, x_old, y_old, event.motion.x, event.motion.y, SDL_MapRGB(ecran->format, 0, 0, 0));
|
|
||||||
else
|
|
||||||
DrawLine(ecran, x_old, y_old, event.motion.x, event.motion.y, SDL_MapRGB(ecran->format, 255, 255, 255));
|
|
||||||
|
|
||||||
SDL_Flip(ecran);
|
|
||||||
x_old = event.motion.x;
|
|
||||||
y_old = event.motion.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(x_old > 0 && y_old > 0)
|
|
||||||
{
|
|
||||||
x_old = width - WIDTH_CONTROL;
|
|
||||||
y_old = event.motion.y;;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_MOUSEBUTTONUP:
|
|
||||||
if(SDL_BUTTON_LEFT == event.button.button || SDL_BUTTON_RIGHT == event.button.button)
|
|
||||||
{
|
|
||||||
x_old = -1;
|
|
||||||
y_old = -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_KEYDOWN:
|
|
||||||
continuer = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SDL_QUIT:
|
|
||||||
continuer = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_FreeSurface(controles);
|
|
||||||
SDL_Quit();
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
4
makefile
4
makefile
@ -1,4 +0,0 @@
|
|||||||
all : main
|
|
||||||
|
|
||||||
main : main.c
|
|
||||||
gcc -o main main.c `sdl-config --cflags --libs`
|
|
187
piboard.py
Executable file
187
piboard.py
Executable file
@ -0,0 +1,187 @@
|
|||||||
|
#!/usr/bin/env python2
|
||||||
|
# -*- coding: utf8 -*-
|
||||||
|
|
||||||
|
# Written by: QuantumPhysics
|
||||||
|
# http://compsci.ca/v3/viewtopic.php?t=32343
|
||||||
|
# Date Written: 10/06/12
|
||||||
|
|
||||||
|
import wx
|
||||||
|
|
||||||
|
class PaintWindow(wx.Window):
|
||||||
|
# array of colors available to draw
|
||||||
|
colours = ['Black', 'Yellow', 'Red', 'Green', 'Blue', 'Purple',
|
||||||
|
'Brown', 'Aquamarine', 'Forest Green', 'Light Blue', 'Goldenrod',
|
||||||
|
'Cyan', 'Orange', 'Navy', 'Light Grey', 'ClearScreen']
|
||||||
|
# color quantity
|
||||||
|
thicknesses = [1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128]
|
||||||
|
|
||||||
|
def __init__(self, parent):
|
||||||
|
# creates paint window
|
||||||
|
super(PaintWindow, self).__init__(parent,
|
||||||
|
style=wx.NO_FULL_REPAINT_ON_RESIZE)
|
||||||
|
self.initDrawing()
|
||||||
|
self.makeMenu()
|
||||||
|
# binds key_down and up events
|
||||||
|
self.bindEvents()
|
||||||
|
self.initBuffer()
|
||||||
|
|
||||||
|
def initDrawing(self):
|
||||||
|
self.SetBackgroundColour('WHITE')
|
||||||
|
self.currentThickness = self.thicknesses[0]
|
||||||
|
self.currentColour = self.colours[0]
|
||||||
|
self.lines = []
|
||||||
|
self.previousPosition = (0, 0)
|
||||||
|
|
||||||
|
def bindEvents(self):
|
||||||
|
for event, handler in [
|
||||||
|
# creates bind event for left button down
|
||||||
|
(wx.EVT_LEFT_DOWN, self.onLeftDown),
|
||||||
|
# creates bind event once left button is released
|
||||||
|
(wx.EVT_LEFT_UP, self.onLeftUp),
|
||||||
|
# creates bind event for drawing (moving cursor)
|
||||||
|
(wx.EVT_MOTION, self.onMotion),
|
||||||
|
# creates bind event for right button up
|
||||||
|
(wx.EVT_RIGHT_UP, self.onRightUp),
|
||||||
|
(wx.EVT_SIZE, self.onSize),
|
||||||
|
(wx.EVT_IDLE, self.onIdle),
|
||||||
|
(wx.EVT_PAINT, self.onPaint),
|
||||||
|
# creates event to close window after 'x' is selected
|
||||||
|
(wx.EVT_WINDOW_DESTROY, self.cleanup)]:
|
||||||
|
self.Bind(event, handler)
|
||||||
|
|
||||||
|
def initBuffer(self):
|
||||||
|
# gets size of window
|
||||||
|
size = self.GetClientSize()
|
||||||
|
# sets window to empty canvas .bmp x-width, y-height
|
||||||
|
self.buffer = wx.EmptyBitmap(size.width, size.height)
|
||||||
|
dc = wx.BufferedDC(None, self.buffer)
|
||||||
|
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
|
||||||
|
dc.Clear()
|
||||||
|
self.drawLines(dc, *self.lines)
|
||||||
|
self.reInitBuffer = False
|
||||||
|
|
||||||
|
def makeMenu(self):
|
||||||
|
# creates menu on right click
|
||||||
|
self.menu = wx.Menu()
|
||||||
|
# sets selection for items (colors) in the runtime window on right click
|
||||||
|
self.idToColourMap = self.addCheckableMenuItems(self.menu,
|
||||||
|
self.colours)
|
||||||
|
# updates screen once a new color is selected
|
||||||
|
self.bindMenuEvents(menuHandler=self.onMenuSetColour,
|
||||||
|
updateUIHandler=self.onCheckMenuColours,
|
||||||
|
ids=self.idToColourMap.keys())
|
||||||
|
self.menu.Break()
|
||||||
|
self.idToThicknessMap = self.addCheckableMenuItems(self.menu,
|
||||||
|
self.thicknesses)
|
||||||
|
self.bindMenuEvents(menuHandler=self.onMenuSetThickness,
|
||||||
|
updateUIHandler=self.onCheckMenuThickness,
|
||||||
|
ids=self.idToThicknessMap.keys())
|
||||||
|
|
||||||
|
# adds a static surpressor to conditions
|
||||||
|
@staticmethod
|
||||||
|
def addCheckableMenuItems(menu, items):
|
||||||
|
|
||||||
|
idToItemMapping = {}
|
||||||
|
for item in items:
|
||||||
|
menuId = wx.NewId()
|
||||||
|
idToItemMapping[menuId] = item
|
||||||
|
menu.Append(menuId, str(item), kind=wx.ITEM_CHECK)
|
||||||
|
return idToItemMapping
|
||||||
|
|
||||||
|
def bindMenuEvents(self, menuHandler, updateUIHandler, ids):
|
||||||
|
|
||||||
|
sortedIds = sorted(ids)
|
||||||
|
firstId, lastId = sortedIds[0], sortedIds[-1]
|
||||||
|
for event, handler in \
|
||||||
|
[(wx.EVT_MENU_RANGE, menuHandler),
|
||||||
|
(wx.EVT_UPDATE_UI_RANGE, updateUIHandler)]:
|
||||||
|
self.Bind(event, handler, id=firstId, id2=lastId)
|
||||||
|
|
||||||
|
def onLeftDown(self, event):
|
||||||
|
# draw line
|
||||||
|
self.currentLine = []
|
||||||
|
self.previousPosition = event.GetPositionTuple()
|
||||||
|
self.CaptureMouse()
|
||||||
|
|
||||||
|
def onLeftUp(self, event):
|
||||||
|
# close motion, stop drawing, wait for event
|
||||||
|
if self.HasCapture():
|
||||||
|
self.lines.append((self.currentColour, self.currentThickness,
|
||||||
|
self.currentLine))
|
||||||
|
self.currentLine = []
|
||||||
|
self.ReleaseMouse()
|
||||||
|
|
||||||
|
def onRightUp(self, event):
|
||||||
|
# if right button is clicked then make wx.menu to select colors
|
||||||
|
self.PopupMenu(self.menu)
|
||||||
|
|
||||||
|
def onMotion(self, event):
|
||||||
|
|
||||||
|
if event.Dragging() and event.LeftIsDown():
|
||||||
|
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
|
||||||
|
currentPosition = event.GetPositionTuple()
|
||||||
|
lineSegment = self.previousPosition + currentPosition
|
||||||
|
self.drawLines(dc, (self.currentColour, self.currentThickness,
|
||||||
|
[lineSegment]))
|
||||||
|
self.currentLine.append(lineSegment)
|
||||||
|
self.previousPosition = currentPosition
|
||||||
|
|
||||||
|
def onSize(self, event):
|
||||||
|
|
||||||
|
self.reInitBuffer = True
|
||||||
|
|
||||||
|
def onIdle(self, event):
|
||||||
|
|
||||||
|
if self.reInitBuffer:
|
||||||
|
self.initBuffer()
|
||||||
|
self.Refresh(False)
|
||||||
|
|
||||||
|
def onPaint(self, event):
|
||||||
|
|
||||||
|
|
||||||
|
dc = wx.BufferedPaintDC(self, self.buffer)
|
||||||
|
|
||||||
|
def cleanup(self, event):
|
||||||
|
if hasattr(self, "menu"):
|
||||||
|
self.menu.Destroy()
|
||||||
|
del self.menu
|
||||||
|
|
||||||
|
def onCheckMenuColours(self, event):
|
||||||
|
colour = self.idToColourMap[event.GetId()]
|
||||||
|
event.Check(colour == self.currentColour)
|
||||||
|
|
||||||
|
def onCheckMenuThickness(self, event):
|
||||||
|
thickness = self.idToThicknessMap[event.GetId()]
|
||||||
|
event.Check(thickness == self.currentThickness)
|
||||||
|
|
||||||
|
def onMenuSetColour(self, event):
|
||||||
|
self.currentColour = self.idToColourMap[event.GetId()]
|
||||||
|
|
||||||
|
def onMenuSetThickness(self, event):
|
||||||
|
self.currentThickness = self.idToThicknessMap[event.GetId()]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def drawLines(dc, *lines):
|
||||||
|
dc.BeginDrawing()
|
||||||
|
for colour, thickness, lineSegments in lines:
|
||||||
|
pen = wx.Pen(wx.NamedColour(colour), thickness, wx.SOLID)
|
||||||
|
dc.SetPen(pen)
|
||||||
|
for lineSegment in lineSegments:
|
||||||
|
dc.DrawLine(*lineSegment)
|
||||||
|
dc.EndDrawing()
|
||||||
|
|
||||||
|
|
||||||
|
class PaintFrame(wx.Frame):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
size = wx.GetDisplaySize()
|
||||||
|
super(PaintFrame, self).__init__(parent, title="Black PiBoard",
|
||||||
|
size=size,
|
||||||
|
style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
|
||||||
|
doodle = PaintWindow(self)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app = wx.App()
|
||||||
|
frame = PaintFrame()
|
||||||
|
frame.ShowFullScreen(True, wx.FULLSCREEN_ALL)
|
||||||
|
app.MainLoop()
|
Loading…
Reference in New Issue
Block a user