Haskell, Change drawing color on mouse click
I want to make a haskell program where some shape is drawn in a window. When I click inside the window the color of the shape should change.
I have come up with this:
testDemo points =
runGraphics $
do
w <- openWindow "Test" (480, 550)
colorRef <- newIORef Green
let
loop0 = do
color <- readIORef colorRef
e <- getWindowEvent w
case e of
Button {pt=pt, isDown=isDown}
| isDown && color == Green -> writeIORef colorRef Red
| isDown && color == Red -> writeIORef colorRef Green
_ -> return ()
color <- readIORef colorRef
drawInWindow w (withColor color (polyline points))
loop0
color <- readIORef colorRef
drawInWindow w (withColor color (polyline points))
l开发者_高级运维oop0
It kinda works. The problem is, that I think that a window event is triggered almost all the time, so everything is drawn all the time which makes it slow. How could I make it so, that I only change the drawing when a click is registered?
First of all, getWindowEvent
will block until the next event occurs, so everything is drawn only on event. If you think that a window event is triggered too often, then you can print events to the stdout to figure out what event is triggered and just ignore it (e.g. skip drawing on all the events except Button event).
BTW: you don't IORef, you can just pass the current color through the loop.
testDemo points =
runGraphics $
do
w <- openWindow "Test" (480, 550)
let
loop0 color = do
e <- getWindowEvent w
let newColor = case e of
Button {pt=pt, isDown=isDown}
| isDown && color == Green -> Red
| isDown && color == Red -> Green
_ -> color
when (newColor != color) (drawInWindow w (withColor color (polyline points)))
loop0 color
let color = Red
drawInWindow w (withColor color (polyline points))
loop0 color
(The code is not tested with the compiler, so...)
Thanks for the answer. I modified the code slightly according to my understanding of what it should do.
testDemo points =
runGraphics $
do
w <- openWindow "Test" (480, 550)
let
loop0 color = do
e <- getWindowEvent w
let newColor = case e of
Button {pt=pt, isDown=isDown}
| isDown && color == Green -> Red
| isDown && color == Red -> Green
_ -> color
when (newColor /= color) (drawInWindow w (withColor newColor (polyline points)))
loop0 newColor
let color = Green
drawInWindow w (withColor color (polyline points))
loop0 color
The results are a bit sketchy though. Sometimes the color changes immediately and sometimes it takes a very long time. I believe it could be some update issue, because when I close a window I see an issued color-change happen just before the window is gone. Any ideas?
It helps if I call clearWindow before I draw the new stuff. I don't really understand why. Does it schedule a redraw of the window maybe? Would be nice to know, but in general the problem is solved for now.
精彩评论