(Предыдущая тема)
Для ввода и редактирования однострочного текста служит виджет editBox.
Как обычно, в конце package.yaml, через пустую строку, допишем ещё одно приложение
| Haskell | 1
2
3
4
5
6
7
| 4.editBox:
source-dirs: 4.editBox
main: Main.hs
ghc-options:
- -rtsopts
- -threaded
- -with-rtsopts=-N |
|
Заметили что пришлось добавить ещё опции компилятора?
Дело в том, что для мигания символом каретки editBox запускает трэд. Необходимо указать через компилятор исполняющей системе haskell что требуется использовать треды операционной системы, иначе символ каретки будет мигать неравномерно и редко.
То есть, практически для любого GUI-SDL2 приложения следует указывать такие опции компилятора.
И так, создадим каталог 4.editBox в корневом каталоге проекта, и в нём новый файл Main.hs
| Haskell | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
| {-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad
import Data.Default
import qualified SDL
import GUI
import GUI.Skin.DefaultSkin
import GUI.Widget.Label
import GUI.Widget.Layout.LinearLayout
import SDL.Vect
import GUI.Widget.EditBox
main :: IO ()
main = runGUI defSkin -- Запуск GUI с оформлением по умолчанию
-- Список предзагруженных шрифтов : ключ, имя файла, размер шрифта, опции
[GuiFontDef "label" "PTN57F.ttf" 15 def
,GuiFontDef "edit" "PTN57F.ttf" 14 def
]
def $ \gui -> do
win <- newWindow gui "editBox" SDL.defaultWindow{SDL.windowInitialSize = V2 400 80}
vL <- win $+ vLayout def
lbStatus <- vL $+ label def{ labelSize=V2 (-1) 20
, labelAlignment=AlignCenter
, labelText="Сюда будут выводится сообщения"}
hL <- vL $+ hLayout def
edLeft <- hL $+ editBox def { editBoxText="Занятие"
, editBoxMaxChar=20
}
edRight <- hL $+ editBox def{ editBoxText="4"
, editBoxMaxChar=20
}
setFocus edLeft
-- Реакции на события
onChanged edLeft $ \ t -> do -- При изменении текста в левом поле
setText lbStatus t
setTextColor lbStatus $ rgb 0 0 255
onEnd edLeft $ \ t -> do -- При потери фокуса левым полем (переход к другому виджету)
setText lbStatus t
setTextColor lbStatus $ rgb 255 0 0
onChanged edRight $ \ t -> do -- При изменении текста в правом поле
setText lbStatus t
setTextColor lbStatus $ rgb 0 200 0
onEnd edRight $ \ t -> do -- При потери фокуса правым полем (переход к другому виджету)
setText lbStatus t
setTextColor lbStatus $ rgb 127 127 0 |
|
Понадобилось добавить описание шрифта с ключом "edit". Это имя зарезервировано для полей ввода.
Выполняем
| Bash | 1
| stack build --exec 4.editBox |
|

Можем убедится что при любом изменении текста он копируется в lbStatus, а цвет lbStatus показывает, какой из обработчиков событий какого editBox-а отработал.
Переход между полями редактирования, кроме Tab, возможно ещё и по Enter.
Виджет editBox поддерживает общепринятые операции выделения фрагмента текста, его копирования и вставки.
А теперь давайте введём ограничение на ввод текста. Допустим, нам нужно что бы во вводимом поле было не более одного пробельного символа.
Для этого нужно установить для editBox-а верификатор. Допишите в конце исходного кода.
| Haskell | 1
2
| setVerifier edLeft $ \ t ->
return $ (T.length $ T.filter isSpace t) < 2 |
|
(Для наглядности я не выполнил этта-редукцию)
Функция верификации возвращает True если текст-кандидат на замещение текущего текста подходит.
В противном случае, изменение не принимается.
Существует более легковесный верификатор.
Для правого editBox-а добавьте в его параметры инициализации
| Haskell | 1
| , editBoxCharFilter = isDigit |
|
И вводить станет возможно только цифры.
И верификатор и editBoxCharFilter можно использовать одновременно.
Для данных изменений нам понадобится добавить пару импортов
| Haskell | 1
2
| import Data.Char
import qualified Data.Text as T |
|
А так же дописать зависимость в конце описания нашего приложения в package.yaml
| Haskell | 1
2
3
4
5
6
7
8
9
| 4.editBox:
source-dirs: 4.editBox
main: Main.hs
ghc-options:
- -rtsopts
- -threaded
- -with-rtsopts=-N
dependencies:
- text |
|
- добавляется зависимость от пакета text.
Повторите
| Bash | 1
| stack build --exec 4.editBox |
|
И проверьте как работают введённые ограничения.
Продолжение следует.
|