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

GUI-SDL2 – GUI написанный на Haskell. Часть 2. Layout-ы, текст с автопереносом

Запись от KolodeznyDiver размещена 26.06.2018 в 22:51

(Предыдущая тема)
Layout-ы – это виджеты предназначенные для группировки других виджетов.
hLayout располагает добавляемые к нему виджеты горизонтально в ряд, а vLayout вертикально в колонку. Используем сразу оба и создадим две колонки из нескольких виджетов label.
В конце package.yaml, через пустую строку допишем ещё одно приложение
Haskell
1
2
3
4
5
  2.Layouts:
    source-dirs:      2.Layouts
    main:             Main.hs
    dependencies:
    - text-show
И, как вы уже догадываетесь, создадим каталог 2.Layouts в корневом каталоге проекта, так же создадим там файл 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
{-# 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 Data.Monoid
import qualified TextShow as TS
import TextShow (showb)
 
main :: IO ()
main = runGUI defSkin  -- Запуск GUI с оформлением по умолчанию
 
        -- Список предзагруженных шрифтов : ключ, имя файла, размер шрифта, опции
        [GuiFontDef "label"       "PTN57F.ttf" 15 def -- label
        ] 
        def $ \gui -> do
    win <- newWindow gui "Layouts" SDL.defaultWindow
    hl <- win $+ hLayout def
    vlLeft <- hl $+ vLayout def
    vlRight <- hl $+ vLayout def
    forM_ ["Первый label в левой колонке"
          ,"Второй label"
          ,"Ещё один label"
          ] $ \txt -> 
                void $ vlLeft $+ label 
                        def{ labelText=txt
                           , labelSize= V2 150 30 
                           , labelWrapMode= TextWrap 100 Nothing
                           }
    forM_ [0 :: Int ..7] $ \n ->
                void $ vlRight $+ label 
                        def{ labelText= TS.toText $ 
                                "Здесь выводится очень длинный текст с номером " 
                                <> showb n
                           , labelSize=V2 350 30
                           }
import GUI.Widget.Layout.LinearLayout очевидно, подключает функции линейных лайаутов,
import SDL.Vect позволяет использовать обозначение координат и размеров принятые в пакете sdl2, которые взяты из пакета linear и перенятые в GUI-SDL2. Размер области 150 на 30 пикселей задаётся как V2 150 30. А точка с заданными координатами из соображений типобезопасности как P(V2 150 30).

Следующие три импорта
Haskell
1
2
3
import Data.Monoid
import qualified TextShow as TS
import TextShow (showb)
нужны для использования пакета text-show которым можно эффективно строить строки типа Text. Вообще то вы не обязаны использовать этот пакет, но имейте ввиду что большинство строк в GUI-SDL2 представлены именно как Text, а не как String, и пакет text-show активно используется в самом GUI-SDL2.
И так, мы создаём hLayout – лайаут с горизонтальным расположением элементов, а в нём два лайаута vLayout с вертикальным расположением элементов.
Haskell
1
2
3
    hl <- win $+ hLayout def
    vlLeft <- hl $+ vLayout def
    vlRight <- hl $+ vLayout def
def означают что мы оставляем параметры лайаутов по умолчанию.
В тексте после этого фрагмента мы создаём три виджета label в левой колонке и 8 в правой.
Обратите внимание на два фрагмента кода
Haskell
1
                 , labelWrapMode= TextWrap 100 Nothing
указывает что текст отображаемый виджетом можно переносить целыми словами на другие строки, при необходимости высоту виджета можно увеличить так что бы текст в нём занимал до 100 писелей в высоту, а межстрочный интервал использовать по умолчанию (Nothing), то есть он берётся из Skin.

Второй нюанс – формирование строки из строкового литерала и числа
Haskell
1
labelText= TS.toText $ "Здесь выводится очень длинный текст с номером " <> showb n
Пакет text-show использует вспомогательный тип Builder являющийся моноидом (<>) для построения строки из фрагментов. Функция showb аналогична show для String. Кроме того, в пакете text-show ещё много разных функций. А ещё есть пакеты его расширяющие типа text-show-instances, но я несколько отвлёкся.

Соберём и выполним новое приложение
Bash
1
stack build --exec 2.Layouts
Нажмите на изображение для увеличения
Название: layouts0.PNG
Просмотров: 55
Размер:	45.8 Кб
ID:	4891
Видно, что слева длинный текст превратился в двухстрочный. Справа длинный текст выводится в одну строку и граница между колонками смещена влево от середины.
Линейные лайауты размещают вложенные в них виджеты в соответствии с их размерами равномерно распределяя между ними оставшееся «лишнее» пространство.
Имеется возможность запросить остаток пространста для конкретного виджета. Для этого в его размере, по соответствующей координате, указывается отрицательное число.
Вот так (вместо первого forM_)
Haskell
1
2
3
4
5
6
7
8
9
    forM_ [("Первый label в левой колонке",V2 150 30)
          ,("Второй label", V2 (-1) (-1))
          ,("Ещё один label", V2 150 30)
          ] $ \(txt,sz) -> 
                void $ vlLeft $+ label 
                        def{ labelText=txt
                           , labelSize= sz -- V2 150 30 
                           , labelWrapMode= TextWrap 80 Nothing
                           }
Нажмите на изображение для увеличения
Название: layouts2.PNG
Просмотров: 55
Размер:	46.0 Кб
ID:	4892
Как видите, средний виджет в левом ряду получил максимум места раздвинув остальных.
А что будет если у нескольких виджетов указать отрицательные размеры?
Если у виджета а указать ширину (-1), а у виджета б ширину (-2), то место оставшееся от виджетов с положительными ширинами распределится как 1/3 для a и 2/3 для б.

В завершении посмотрим на параметры лайаутов.
Верните код к первому варианту но измените
Haskell
1
    vlLeft <- hl $+ vLayout def{layoutAlignment=AlignLeftCenter}
Нажмите на изображение для увеличения
Название: layouts1.PNG
Просмотров: 66
Размер:	45.6 Кб
ID:	4893
AlignLeftCenter означает выравнивание влево и по центру вертикально.
А что если выровнять вправо? Можно указать
Haskell
1
    vlLeft <- hl $+ vLayout def{layoutAlignment=AlignRightCenter}
Но тогда понадобится ещё добавить выравнивание и в самих label-ах левой колонки. (Сообразите куда вставить эту строку).
Haskell
1
                           , labelAlignment= AlignRightCenter
Нажмите на изображение для увеличения
Название: layouts4.PNG
Просмотров: 55
Размер:	60.6 Кб
ID:	4894

Так же, в параметрах лайаутов можно настроить размеры их полей (нулевые по умолчанию) и цвет фона.

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