-- ghc --make Main.hs -o confirm.exe module Main where -- ライブラリを学習するためになるべく丁寧に依存先を書きました。 import Graphics.UI.WX (start) import Graphics.UI.WX.Events (on, command, closing) import Graphics.UI.WX.Types (fontFixed, _fontSize, _fontFace,sz) import Graphics.UI.WX.Attributes (Prop(..), get, set) import Graphics.UI.WX.Classes (Textual, appendText, visible, clientSize, enabled, font, fontFace,selection, text, close, closeable,minimizeable ) import Graphics.UI.WX.Layout (container, widget, minsize, layout, row, hfill, column, floatRight, Widget, Layout, margin) import Graphics.UI.WX.Controls (Wrap(..), staticText, textCtrl, button, wrap, panel) import Graphics.UI.WX.Frame (frame) import Graphics.UI.WX.Dialogs (confirmDialog) import Graphics.UI.WXCore.Frame (frameCenter) import Graphics.UI.WXCore.WxcClassTypes (Window) import Graphics.UI.WXCore.WxcClassesMZ (wxcAppExit) import Control.Monad (when) import Graphics.UI.WXCore (textCtrlClear) import Data.DateTime (fromClockTime) import System.Time (getClockTime) -- 本体は前回と同じ時刻を表示するプログラムです。 main :: IO () main = start gui gui :: IO () gui = do -- 最初、visible を Falseにしてセンタリングしてから True にすると -- 無駄な描写が表示されないですっきりします。 form <- frame [text := "Message test", visible := False] p <- panel form [] textlog <- textCtrl p [enabled := True, wrap := WrapNone, font := fontFixed{ _fontSize=11,_fontFace = "Monospace"} ] ok <- button p [text := "実行", on command := doCommand textlog] clr <- button p [text := "クリア", on command := textCtrlClear textlog, clientSize := sz 50 24] quit <- button p [text := "終了" , on command := close form,clientSize := sz 50 24] set ok [clientSize := sz 50 24 ] set form [layout := container p $ column 0 [floatRight (margin 10 $ row 5 [widget ok, widget clr, widget quit]) , hfill $ minsize (sz 350 250) $ widget textlog ] , clientSize := sz 350 300] frameCenter form -- closing イベントのときの動作を登録。 -- フォームを可視化します。 set form [on closing := confirmExit form, visible := True] return () -- 確認ダイアログ。 confirmExit :: Window a -> IO () confirmExit form = do yes <- confirmDialog form "終了確認" "終了しますか?" True -- when は yes が True のとき次の wxcAppExit を評価し、 -- それ以外は何もしないという不思議なモナド。 -- 反対の unless というものもある。 when yes wxcAppExit return () doCommand :: (Textual w) => w -> IO () doCommand log = do writeDate log 10 writeText log "done.\n" writeDate :: (Num t,Textual w) => w -> t -> IO () writeDate log 0 = return () writeDate log n = do ctime <- getClockTime writeText log $ show (fromClockTime ctime) ++ "\n" writeDate log (n-1) writeText :: (Textual w) => w -> String -> IO () writeText log str = do appendText log str
elbrujohalcon / wxhnotepadを参考にしました。
-- unless は Bool と Monad を引数にして Monad を返す。 > :t unless unless :: (Monad m) => Bool -> m () -> m () > let t = unless True $ print 1 > let f = unless False $ print 1 -- t も f も IO () > :t t --=> t :: IO () > :t f --=> f :: IO () -- t は何もしないアクションで f は 1 を表示するアクション > t > f 1
追記:when yes wxcAppExit は以下と同等と気が付いてやってみたらOKでした・・・Orz
if yes then wxcAppExit else return ()