- wxFormBuilderの使い方を学ぶには
wxRubyのこと (RubyでGUI)はwxRubyのサイトです。wxFormBuilderを使用して、「Hello World」「ラーメンタイマー」「時計」「双六ゲーム」「Twitterクライアント」を作り、XRCファイルも公開していますので、wxFormBuilderの学習には最適。「wxFormBuilderの使い方」http://hackage.haskell.org/packages/archive/wxcore/0.12.1.7/doc/html/Graphics-UI-WXCore-WxcClassesMZ.html#g:94から丁寧に記述されています。ここから読み始めると良いでしょう。
最初から wxFormBuilder は使いこなせないので、公開されている XRC をwxFormBuilderに読み込ませ、部品の右・中央・左、上・中央・下、EXPANDなどのボタンを押して、何が変わるのか確認してみました。
- ラーメンタイマーを作る1をHaskellでやってみました。
- タイマーは 多数のボールがバウンドする BouncingBalls.hs で使っていましたのでそれを参考にします。Graphics.UI.WXCore.WxcClassesMZにTimer関係の関数があるようなのですが使い方がよくわかりません・・・Orz
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <resource xmlns="http://www.wxwindows.org/wxxrc" version="2.3.0.1"> <object class="wxFrame" name="RamenFrame" subclass="RF1"> <style>wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL</style> <size>500,300</size> <title>Ramen Timer</title> <aui_managed>0</aui_managed> <object class="wxPanel" name="panel"> <style>wxTAB_TRAVERSAL</style> <object class="wxBoxSizer"> <orient>wxVERTICAL</orient> <object class="sizeritem"> <option>1</option> <flag>wxEXPAND</flag> <border>5</border> <object class="wxFlexGridSizer"> <rows>1</rows> <cols>1</cols> <vgap>0</vgap> <hgap>0</hgap> <!-- サイズを変更しても中央になる --> <growablecols>0</growablecols> <growablerows>0</growablerows> <object class="sizeritem"> <option>1</option> <flag>wxALIGN_CENTER|wxALL</flag> <border>5</border> <object class="wxStaticText" name="staticText"> <font> <size>55</size> <family>default</family> <style>normal</style> <weight>normal</weight> <underlined>0</underlined> </font> <label>00:00</label> <wrap>0</wrap> </object> </object> </object> </object> <object class="sizeritem"> <option>0</option> <flag>wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND</flag> <border>5</border> <object class="wxButton" name="button0"> <label>START!</label> <default>0</default> </object> </object> </object> </object> </object> </resource>
module Main where import Graphics.UI.WX (start) import Graphics.UI.WX.Classes (Textual(text)) import Graphics.UI.WX.Types (objectNull) import Graphics.UI.WX.Events (on, command) import Graphics.UI.WX.Attributes (Prop((:=)), set) import Graphics.UI.WX.Timer (timer) import Graphics.UI.WXCore.WxcDefs (wxXRC_USE_LOCALE) import Graphics.UI.WXCore.WxcClassTypes (Timer) import Graphics.UI.WXCore.WxcClassesMZ (xmlResourceCreateFromFile, xmlResourceLoadFrame, xmlResourceGetPanel, xmlResourceGetStaticText, xmlResourceGetButton, windowShow, timerStart) import Data.IORef (IORef, newIORef, readIORef, writeIORef) import Text.Printf (printf) import Control.Monad (when) data Ramen = Ramen{counter::Int, valid::Bool} deriving (Show) main :: IO () main = start $ do newCnt <- newIORef (Ramen 0 False) res <- xmlResourceCreateFromFile "ramen.xrc" wxXRC_USE_LOCALE form <- xmlResourceLoadFrame res objectNull "RamenFrame" panel <- xmlResourceGetPanel form "panel" txt <- xmlResourceGetStaticText panel "staticText" button <- xmlResourceGetButton panel "button0" tm <- timer panel [on command := nextTimer txt newCnt] set button [on command := pushButton newCnt tm] windowShow form nextTimer :: Textual w => w -> IORef Ramen -> IO () nextTimer txt ramenCNT = do (Ramen sec flag) <- readIORef ramenCNT when (flag && (sec >= 0 )) (set txt [text := printf "%02d:%02d" (sec `div` 60) (sec `rem` 60)] >> writeIORef ramenCNT (Ramen (sec-1) flag)) pushButton :: IORef Ramen -> Timer a -> IO () pushButton ioCnt tm = do b <- timerStart tm 1000 False writeIORef ioCnt (Ramen 180 True)
- xrc ファイルのTABをスペース4個に変換するワンライナー。
readFile "./name.xrc" >>= \f ->writeFile "./new.xrc" $ unlines $ map (foldl (\acc c -> acc++if c =='\t' then " " else [c]) "") $ lines f
readFile "./file" >>= \f ->putStrLn $ Data.List.foldl' (\a c -> a++if c =='\t' then " " else [c]) "") f