2010-11-05 29 views
1

Je veux créer un programme de haskell dans lequel une forme est dessinée dans une fenêtre. Quand je clique dans la fenêtre, la couleur de la forme devrait changer.Haskell, Changer la couleur de dessin sur la souris cliquez sur

Je suis venu avec ceci:

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 

Il fonctionne un peu. Le problème est, que je pense qu'un événement de fenêtre est déclenché presque tout le temps, donc tout est dessiné tout le temps ce qui le rend lent. Comment puis-je faire en sorte que je ne change le dessin que lorsqu'un clic est enregistré?

+1

Pourriez-vous s'il vous plaît mentionner quel paquet vous utilisez pour la bibliothèque de fenêtrage? Gtk2hs? wxHaskell? autre? –

+1

Eh bien, dans le code, il ressemble à ceci: importer Graphics.HGL –

Répondre

0

Il est utile que j'appelle clearWindow avant de dessiner les nouveaux éléments. Je ne comprends pas vraiment pourquoi. Est-ce qu'il planifie un redessin de la fenêtre peut-être? Serait bon de savoir, mais en général le problème est résolu pour l'instant.

1

Tout d'abord, getWindowEvent va bloquer jusqu'à ce que l'événement suivant se produise, donc tout est dessiné uniquement sur l'événement. Si vous pensez qu'un événement de fenêtre est déclenché trop souvent, vous pouvez imprimer des événements dans la sortie standard pour déterminer quel événement est déclenché et l'ignorer (par exemple, ignorer le dessin de tous les événements sauf l'événement Button). BTW: vous n'avez pas IORef, vous pouvez simplement passer la couleur actuelle à travers la boucle.

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 

(Le code n'a pas été testé avec le compilateur, alors ...)

0

Merci pour la réponse. J'ai légèrement modifié le code selon ma compréhension de ce qu'il devrait faire.

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 

Les résultats sont un peu succincts. Parfois, la couleur change immédiatement et parfois cela prend beaucoup de temps. Je crois que cela pourrait être un problème de mise à jour, parce que quand je ferme une fenêtre, je vois un changement de couleur qui se produit juste avant que la fenêtre ne disparaisse. Des idées?

+0

Si je saute la partie "when (newColor/= color)" cela fonctionne mieux. Le seul problème est que la nouvelle couleur n'est visible qu'après avoir bougé la souris. Peut-être qu'il serait possible de déclencher un redessin manuel de la fenêtre? –