haskell-giでHelloWorld以後

[haskell-giでHelloWorld](https://qiita.com/ringo-apo/items/e2f66b507db64e162237)ができたので、基本的なラベル、テキストボックス、ボタンを使った簡単なプログラムを作ってみます。

テキストボックスに数値を入れて、ボタンを押すと＋１した結果をラベルに出力します。

stackでプロジェクトを作成します。

```
stack new my-project
cd my-project
```

「stack.yaml」ファイルに「extra-deps」を設定します。

```
extra-deps:
- gtk2hs-buildtools-0.13.8.0
- glib-0.13.8.1
- cairo-0.13.8.1
- pango-0.13.8.1
- gi-gtk-3.0.37
- gi-gdk-3.0.24
- gi-gdkpixbuf-2.0.26
- gi-gmodule-2.0.1
- gi-atk-2.0.23
- gi-cairo-1.0.25
- gi-gio-2.0.28
- gi-gobject-2.0.26
- gi-harfbuzz-0.0.4
- gi-pango-1.0.24
- haskell-gi-0.25.0
- haskell-gi-base-0.25.0
- gi-glib-2.0.25
- reactive-banana-1.2.1.0
```

「package.yaml」ファイルに「dependencies」を設定します。

```
dependencies:
- base >= 4.7 && < 5
- gi-gtk
- haskell-gi-base
- text
- gi-gio
- bytestring
```

「app/Main.hs」ファイルに下記コードを上書きします。

```hs
{-# LANGUAGE OverloadedStrings, OverloadedLabels #-}

{- cabal:
build-depends: base, haskell-gi-base, gi-gtk == 3.0.*
-}

{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}

{- Hello World example of GTK+ documentation. For information please refer to README -}

module Main where

-- import qualified Data.Text as T
import Data.Text 

import qualified GI.Gio as Gio
import qualified GI.Gtk as Gtk
import Data.GI.Base
import Data.Text.Encoding 
--import qualified Data.ByteString 


activateApp :: Gtk.Application -> IO ()
activateApp app = do
  win1 <- new Gtk.ApplicationWindow [ #application := app
                                    , #title := "BasicSample"
                                    , #defaultHeight := 200
                                    , #defaultWidth := 200
                                    ]

  box1 <- new Gtk.Box [ #orientation := Gtk.OrientationVertical ]
  #add win1 box1

  entry1 <- new Gtk.Entry[ #text := "0" ]
  #add box1 entry1

  label1 <- new Gtk.Label [#label := "1" ]
  #add box1 label1

  
  button1 <- new Gtk.Button [ #label := "Increment"]

  on button1 #clicked ( do
                            buffer <- Gtk.entryGetBuffer entry1
                            bufferText <- Gtk.entryBufferGetText buffer
                            let bufferString = Data.Text.unpack bufferText 
                            let bufferInt = (read bufferString :: Int) + 1
                            let label1String = show (bufferInt)
                            let label1Text = Data.Text.pack label1String
                            set label1 [ #sensitive := False, #label := label1Text ]
                      )
  --on btn #clicked $ Gtk.widgetDestroy w
  #add box1 button1
  
  #showAll win1
  return ()

main :: IO ()
main = do
  app <- new Gtk.Application [ #applicationId := "haskell-gi.examples.hello-world"
                             , #flags := [ Gio.ApplicationFlagsFlagsNone ]
                             ]
  on app #activate $ activateApp app
  Gio.applicationRun app Nothing
  return ()
```

少し解説します。

```hs
  box1 <- new Gtk.Box [ #orientation := Gtk.OrientationVertical ]
  #add win1 box1
```

上記より上のコードで設定したウィンドゥ（win1）にbox1というBoxを追加しています。
box1に追加される部品が縦（垂直）に並ぶよう「Gtk.OrientationVertical」を設定しています。
ここの部分を「Gtk.OrientationHorizontal」とすると横（水平）に部品が並びます。

```hs
  entry1 <- new Gtk.Entry[ #text := "0" ]
  #add box1 entry1
```

単行のテキストボックスです。
初期値で"0"が表示されるようにしています。

```hs
  label1 <- new Gtk.Label [#label := "1" ]
  #add box1 label1
```

ラベルを設置しています。
初期値で"1"が表示されるようにしています。

```hs
  button1 <- new Gtk.Button [ #label := "Increment"]

  on button1 #clicked ( do
                            buffer <- Gtk.entryGetBuffer entry1
                            bufferText <- Gtk.entryBufferGetText buffer
                            let bufferString = Data.Text.unpack bufferText 
                            let bufferInt = (read bufferString :: Int) + 1
                            let label1String = show (bufferInt)
                            let label1Text = Data.Text.pack label1String
                            set label1 [ #sensitive := False, #label := label1Text ]
                      )
  --on btn #clicked $ Gtk.widgetDestroy w
  #add box1 button1
```

ボタンを設置しています。
ボタンがクリックされたとき、テキストボックスのデータを取り出し、Text型に変換し、更にString型に変換し、更に数値化したデータをインクリメントして、再びString型に変換し、再びText型に変換し、ラベルに設定しています。

コンパイルして実行します。

```
stack build
stack exec my-project-exe
```

下記のように実行されます。（テキストボックスに「5」を入力してボタン押下後）

![20210527.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87133/07d6f75c-0a78-81f6-944b-25aeda24935c.png)

[すべてのソースコード](https://github.com/ringo-apo/haskell-gi_basic)

以上