Форум программистов, компьютерный форум, киберфорум
Наши страницы
KolodeznyDiver
Войти
Регистрация
Восстановить пароль
Оценить эту запись

GUI-SDL2 – GUI написанный на Haskell. Часть 4. Поле ввода текста

Запись от KolodeznyDiver размещена 02.07.2018 в 08:55
Обновил(-а) KolodeznyDiver 02.07.2018 в 09:19

(Предыдущая тема)

Для ввода и редактирования однострочного текста служит виджет 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
Нажмите на изображение для увеличения
Название: editBox.PNG
Просмотров: 52
Размер:	15.3 Кб
ID:	4906

Можем убедится что при любом изменении текста он копируется в 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
И проверьте как работают введённые ограничения.

Продолжение следует.
Размещено в Без категории
Просмотров 126 Комментарии 0
Всего комментариев 0
Комментарии
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru