Haskell, меняй цвет рисунка по клику мыши - PullRequest
1 голос
/ 05 ноября 2010

Я хочу создать программу на Haskell, в которой какая-то фигура рисуется в окне.Когда я щелкаю внутри окна, цвет формы должен измениться.

Я пришел к этому:

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))
        loop0

Это вроде работает.Проблема в том, что я думаю, что событие окна запускается почти все время, поэтому все рисуется все время, что делает его медленным.Как я могу сделать так, чтобы я менял чертеж только после регистрации клика?

Ответы [ 3 ]

1 голос
/ 05 ноября 2010

Прежде всего, getWindowEvent будет блокироваться, пока не произойдет следующее событие, поэтому все отрисовывается только по событию. Если вы считаете, что событие окна запускается слишком часто, вы можете напечатать события на стандартный вывод, чтобы выяснить, какое событие вызвано, и просто проигнорировать его (например, пропустить рисование для всех событий, кроме события Button).

Кстати: вы не IORef, вы можете просто пропустить текущий цвет через цикл.

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

(Код не проверяется с помощью компилятора, поэтому ...)

0 голосов
/ 09 ноября 2010

Будет полезно, если я вызову clearWindow до того, как начну рисовать новый материал.Я не очень понимаю, почему.Это может запланировать перерисовку окна?Было бы неплохо узнать, но в целом проблема пока решена.

0 голосов
/ 05 ноября 2010

Спасибо за ответ.Я немного изменил код в соответствии с моим пониманием того, что он должен делать.

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

Хотя результаты немного поверхностны.Иногда цвет меняется сразу, а иногда это занимает очень много времени.Я полагаю, что это может быть какая-то проблема с обновлением, потому что когда я закрываю окно, я вижу, что изменение цвета происходит непосредственно перед тем, как окно исчезнет.Есть идеи?

...