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

GUI-SDL2 – GUI написанный на Haskell. Часть 1. Каталог ресурсов, шрифты и виджет label

Запись от KolodeznyDiver размещена 22.06.2018 в 18:28

Как я написал ранее, библиотека SDL2, над которой сделан GUI-SDL2 не поддерживает вывод текста. Для этого существует сопутствующая библиотека SDL_ttf. Это даёт максимальную отвязку от ОС, но требует указания места расположения шрифтов используемых приложением. Разумеется, работая под Windows, можно определить где хранятся шрифты в этой ОС (так же и для Linux) и указать их полный путь в приложении. Но механизмы отрисовки шрифтов встроенные в эти ОС не используются – используется механизм растеризации библиотеки SDL_ttf ( которая, в свою очередь использует библиотеку FreeType).

Кроме того, шрифты, сами по себе, имеют свои лицензии на использование. Вы то можете выбрать любые ttf шрифты, какие хотите, но в портабельном (я надеюсь) пакете GUI-SDL2, вложены, с целью демонстрации, шрифты со свободной лицензией взятые с http://www.paratype.ru/public/.

Приложение GUI-SDL2 ищет каталог с именем GUI.Resources в каталоге исполняемого файла, в каталоге проекта, а так же в каталогах для данных приложений зависящих от ОС (читайте GUI-SDL2/library/GUI/BaseLayer/Resource.hs, комментарий в начале файла со строки «Поиск ресурсов :»).

В этом каталоге находятся и шрифты, наряду с графическими файлами – элементами интерфейса, любыми графическими файлами приложения, таблицами для реализации многоязыкового интерфейса (i18n) и прочем, о чём я предполагаю рассказать в дальнейшем.

И так, вы посмотрели внутрь GUI.Resources и увидели что пара шрифтов у нас уже есть. Подключим их.

В GUI-SDL2 предполагается что множество элементов интерфейса будет отображаться одинаковыми шрифтами с одинаковым размером и другими параметрами отображения. (Естественно, множество других элементов будут отображаться своими шрифтами).

Такие шрифты задаются списком в одном из аргуметов функции runGUI. Помните, в прошлый раз у неё был аргумент со значением []?

Сейчас мы заполим этот список, но, для начала, создадим новое приложение для сегодняшнего занятия.

В конце файла package.yaml, через пустую строку запишем
Haskell
1
2
3
  1.label:
    source-dirs:      1.label
    main:             Main.hs
Создадим в корне проекта каталог 1.label, а в нём файл Main.hs с минимальным содержимым позволяющем ввести виджет label – фрагмент текста внутри окна.
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{-# LANGUAGE OverloadedStrings #-}
module Main where
 
import Control.Monad
import Data.Default
import qualified SDL
import GUI
import GUI.Skin.DefaultSkin
import GUI.Widget.Label
 
main :: IO ()
main = runGUI defSkin  -- Запуск GUI с оформлением по умолчанию
 
        -- Список предзагруженных шрифтов : ключ, имя файла, размер шрифта, опции
        [GuiFontDef ""            "PTM55F.ttf" 14 def -- по молч., если не найден указанный ключ
        ,GuiFontDef "label"       "PTN57F.ttf" 15 def -- label
        ] def $ \gui -> do
    win <- newWindow gui "Hello world" SDL.defaultWindow
    void $ win $+ label def{ labelText="Привет, мир!" }
Шрифты в GUI-SDL2 выбираются по текстовым ключам. Например, виджет label, по умолчанию, использует шрифт с ключом "label".
В отличии от кода прошлого занятия здесь добавлен новый импорт
Haskell
1
import GUI.Widget.Label
- для каждого виджета есть, минимум один, свой модуль.
В отличии от прошлого кода мы будем использовать значение возвращаемое функцией newWindow для того, что бы добавить в окно виджет, что и делается с помощью
Haskell
1
       void $ win $+ label def{ labelText="Привет, мир!" }
Выражение label def{ labelText="Привет, мир!" } создаст текстовую метку с минимальной настройкой – задаётся только сам текст. Функция ($+) добавляет виджет в контейнер.
Haskell
1
Контейнер $+ создаваемый_виджет
В данном случае контейнером является окно, а виджет - label. Некоторые виджеты так же могут быть контейнерами для других виджетов.
void $ означает что мы не будем использовать результат выражения.
И, так, запускаем
Bash
1
stack build --exec 1.label
И получаем
Нажмите на изображение для увеличения
Название: 1.helloworld0.PNG
Просмотров: 272
Размер:	26.9 Кб
ID:	4888
Да, результат не впечатляет. Текст мелкий, нарисован сбоку. К тому же имеется чёрная рамка внутри окна.
Попробуем улучшить. Во первых добавим в таблицу большой шрифт, да ещё и жирный, наклонный и с подчёркиванием.
Haskell
1
,GuiFontDef "hello world" "PTN57F.ttf" 28 def{fontStyle = Just [FNT.Bold, FNT.Italic, FNT.Underline]}
Во вторых, в настройке label укажем этот шрифт, цвет текста выберем зелёный и выравнивание на середину (и по горизонтали и по вертикали)
Haskell
1
2
3
4
5
    void $ win $+ label def{ labelText="Привет, мир!"
                           , labelFontKey = "hello world"
                           , labelColor = Just $ rgb 0 100 0
                           , labelAlignment=AlignCenter
                           }
А откуда взялась чёрная рамка?
Дело в том, что все виджеты имеют поля-отступы (margin), которые ими не отрисовываются. Виджет label вставленный в окно, отрисовал себя цветом заданным в «скине» по умолчанию (defSkin), но поля остались не отрисованными. Что бы чёрная рамка из полей-отступов исчезла, проще всего указать для виджета нулевые поля
Haskell
1
      ,labelFormItemDef = def{formItemMargin=Just WidgetMarginNone}
Почему так громоздко? Дело в том что в каждой записи инициализации виджетов (а тип этой записи у каждого виджета свой) имеется поле с типом FormItemWidgetDef. Оно задаёт параметры присущие каждому виджету. Один из таких параметров formItemMargin, значение которого по умолчанию – Nothing. В этом случае размеры полей берутся из «скина». Сейчас мы задаём их принудительно.
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
{-# 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 qualified SDL.Font as FNT
 
main :: IO ()
main = runGUI defSkin  -- Запуск GUI с оформлением по умолчанию
 
        -- Список предзагруженных шрифтов : ключ, имя файла, размер шрифта, опции
        [GuiFontDef ""            "PTM55F.ttf" 14 def -- по молч., если не найден указанный ключ
        ,GuiFontDef "label"       "PTN57F.ttf" 15 def -- label
        ,GuiFontDef "hello world" "PTN57F.ttf" 28 def{fontStyle = Just [FNT.Bold, FNT.Italic, FNT.Underline]}
        ] def $ \gui -> do
    win <- newWindow gui "Hello world" SDL.defaultWindow
    void $ win $+ label def{ labelText="Привет, мир!"
                           , labelFontKey = "hello world"
                           , labelColor = Just $ rgb 0 100 0
                           , labelAlignment=AlignCenter
                           , labelFormItemDef = def{formItemMargin=Just    WidgetMarginNone}
                           }

Понадобилось добавить ещё импорт
Haskell
1
import qualified SDL.Font as FNT
с параметрами шрифта, а т.к. это модуль из пакета sdl2-ttf, то придётся добавить его в зависимости приложения.
Открываем файл package.yaml, и в самом конце, под «main: Main.hs» записываем
Haskell
1
2
    dependencies:
    - sdl2-ttf
(хотя можно добавить sdl2-ttf к dependencies указанным выше, тогда зависимость будет для всех приложений пакета).
повторяем
Bash
1
stack build --exec 1.label
И получаем
Нажмите на изображение для увеличения
Название: 1.helloworld.PNG
Просмотров: 273
Размер:	26.7 Кб
ID:	4889
Да, так лучше.

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