开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜