i582 / simple-interface-SDL2

Just simple interface with SDL2 and C++17

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

simple-interface-SDL2

Итак, это простой интерфейс для нашей курсовой работы.

Установка

  1. Скопируйте данный репозиторий себе на компьютер
  2. Скачайте с официального сайта SDL2 пакет Development Libraries и распакуйте его содержимое в папку SDL2 на диск С:\
  3. Скачайте библиотеку SDL2_ttf (Development Libraries) Visual C++ 32/64-bit и распакуйте ее в папку с SDL2
  4. Скачайте библиотеку SDL2_image (Development Libraries) Visual C++ 32/64-bit и распакуйте ее в папку с SDL2
  5. Откройте проект в Visual Studio 2019
  6. Перейдите в Проект-Свойства simple-interface-SDL2 и проверьте вкладку С/С++-Общие поле Дополнительные катологи включаемых файлов. В случае если там нет путей к библиотекам пропишите слудующее: C:\SDL2\SDL2_ttf-2.0.15\include;C:\SDL2\SDL2_image-2.0.4\include;C:\SDL2\include;, где замените в случае надобности версии скачанных вами библиотек.
  7. Перейдите во вкладку Компоновщик-Общее, где проверьте поле Дополнительные каталоги библиотек, в случае отсутствия путей пропишите следующее: C:\SDL2\SDL2_ttf-2.0.15\lib\x86;C:\SDL2\SDL2_image-2.0.4\lib\x86;C:\SDL2\lib\x86;
  8. Перейдите во вкладку Компоновщик-Ввод, где проверьте поле Дополнительные зависимости, в случае отсутствия пропишите следующее: SDL2.lib;SDL2main.lib;SDL2test.lib;SDL2_ttf.lib;SDL2_image.lib;
  9. Перейдите во вкладку Компоновщик-Система и в поле Подсистема поставьте Консоль
  10. Запустите отладку проекта
  11. Вы получите ошибку, о том, что SDL2.dll не найден
  12. Скопируйте *.dll из папки dll в папку debug, рядом с файлом *.exe
  13. Запустите отладку проекта
  14. Если все предыдущие пункты выполнены, вы должны получить пустое окно

Настройка интерфейса

Первым делом, настраивается размер окна, перейдите в файл main.cpp и в строке

Interface newInterface(1200, 500);

поставьте нужный вам размер.

Далее для добавления элементов в интерфейс, необходимо перейти в файл Interface_Setup.cpp, в котором происходит добавления любых элементов.

Все элементы, добавляемые вами, хранятся в массивах, разных для каждого типа элемента.

1. Labels - все надписи
2. Buttons - все кнопки
3. Inputs - все поля ввода
4. TextFields - все поля вывода
5. ItemLists - все обычные списки
6. DropDownLists - все списки со значением в теле

Тот факт, что все элементы одного типа хранятся в массиве, говорит о том, что доступ к определенному элементу будет осуществлятся по индексу. Именно для этого для каждого элемента вводятся перечисления.

Например, расмотрим следующиее обращение к первой кнопке

Buttons.at(0)

в этом обращении не понятно, что это за кнопка. Используя же простое перечисление

enum BUTTON_IDENTIFICATORS{
    BUTTON_EXIT
};

обращение к кнопке превращается в такое:

Buttons.at(BUTTON_EXIT)

по которому сразу же можно сказать, что это за кнопка, и за что она отвечает.

При добавлении любого элемента обязательно добавлять новый идентификатор в перечисления в файле interface.h , определенное для каждого типа заранее, т.е. если вы добавляете кнопку, то вы должны добавить новый идентификатор в перечисление BUTTON_IDENTIFICATORS, а если input, то в перечисление INPUT_IDENTIFICATORS.

Теперь рассмотрим элементы которые можно добавить:

1. Надпись (Label)

Простая надпись.

Для ее добавления синтаксис такой

// файл Interface_Setup.cpp

Label* _имя_ = new Label(
  _координаты_в_SDL_Rect_, 
  _надпись_, 
  _путь_к_шрифту_, 
  _размер_шрифта_, 
  _тип_выравнивание(LEFT_ALIGN or CENTERED_ALIGN)
);

// здесь можно:
Отобразить: _имя_->Show() и соотвественно скрыть: _имя_->Hide(), а так же получить текущее значение is_show()

// добавление в общий список надписей
Labels.push_back(_имя_);

// файл interface.h
enum LABEL_IDENTIFICATORS{
    ...
    _имя_идентификатора_
};

2. Кнопка (Button)

Для ее добавления синтаксис такой

// файл Interface_Setup.cpp

Button* _имя_ = new Button(
  _координаты_в_SDL_Rect_,
  _надпись_,
  _путь_к_шрифту_, 
  _размер_шрифта_,
  _тип_выравнивание_текста(LEFT_ALIGN or CENTERED_ALIGN)
);

// здесь можно:
Отобразить: _имя_->Show() и соотвественно скрыть: _имя_->Hide(), а так же получить текущее значение is_show()
Заблокировать: _имя_->Block() и соотвественно разблокировать: _имя_->Unlock(), а так же получить текущее значение is_block()

// добавление в общий список кнопок
Buttons.push_back(_имя_);

// файл interface.h
enum BUTTON_IDENTIFICATORS{
    ...
    _имя_идентификатора_
};

3. Поле ввода (Input)

Для его добавления синтаксис такой

// файл Interface_Setup.cpp

Input* _имя_ = new Input(
  _координаты_в_SDL_Rect_,
  _путь_к_шрифту_, 
  _размер_шрифта_,
  _тип_выравнивание_текста(LEFT_ALIGN or CENTERED_ALIGN)
);

// здесь можно:
Отобразить: _имя_->Show() и соотвественно скрыть: _имя_->Hide(), а так же получить текущее значение is_show()
Заблокировать: _имя_->Block() и соотвественно разблокировать: _имя_->Unlock(), а так же получить текущее значение is_block()

// добавление в общий список полей ввода
Inputs.push_back(_имя_);

// файл interface.h
enum INPUT_IDENTIFICATORS{
    ...
    _имя_идентификатора_
};

4. Поле вывода (TextField)

Для его добавления синтаксис такой

// файл Interface_Setup.cpp

TextField* _имя_ = new TextField(
  _координаты_в_SDL_Rect_,
  _путь_к_шрифту_, 
  _размер_шрифта_,
  _тип_выравнивание_текста(LEFT_ALIGN or CENTERED_ALIGN)
);

// здесь можно:
Отобразить: _имя_->Show() и соотвественно скрыть: _имя_->Hide(), а так же получить текущее значение is_show()
Заблокировать: _имя_->Block() и соотвественно разблокировать: _имя_->Unlock(), а так же получить текущее значение is_block()
Добавить строку: _имя_->add(_строка__)

// добавление в общий список полей вывода
TextFields.push_back(_имя_);

// файл interface.h
enum TEXT_FIELD_IDENTIFICATORS{
    ...
    _имя_идентификатора_
};

5. Выпадающий список (ItemList)

Для его добавления синтаксис такой

// файл Interface_Setup.cpp

ItemList* _имя_ = new ItemList(
  _координаты_в_SDL_Rect_,
  _размеры_элемента_списка_в_SDL_Rect_,
  _тип_выпадающего_списка_(LEFT_SIDE or DOWN_SIDE),
  _путь_к_шрифту_, 
  _размер_шрифта_,
  _тип_выравнивание_текста(LEFT_ALIGN or CENTERED_ALIGN)
);

// здесь можно:
Отобразить: _имя_->Show() и соотвественно скрыть: _имя_->Hide(), а так же получить текущее значение is_show()
Заблокировать: _имя_->Block() и соотвественно разблокировать: _имя_->Unlock(), а так же получить текущее значение is_block()
Добавить элемент `_имя_->add(_текст_, _флаг_по_которому_определяется_что_это_такое);`

// добавление в общий список простых списков
ItemLists.push_back(_имя_);

// файл interface.h
enum ITEM_LIST_IDENTIFICATORS{
    ...
    _имя_идентификатора_
};

6. Выпадающий список со значением в теле (DropDownList)

Для его добавления синтаксис такой

// файл Interface_Setup.cpp

DropDownList* _имя_ = new DropDownList(
  _координаты_в_SDL_Rect_,
  _размеры_элемента_списка_в_SDL_Rect_,
  _тип_выпадающего_списка_(LEFT_SIDE or DOWN_SIDE),
  _путь_к_шрифту_, 
  _размер_шрифта_,
  _тип_выравнивание_текста(LEFT_ALIGN or CENTERED_ALIGN)
);

// здесь можно:
Отобразить: _имя_->Show() и соотвественно скрыть: _имя_->Hide(), а так же получить текущее значение is_show()
Заблокировать: _имя_->Block() и соотвественно разблокировать: _имя_->Unlock(), а так же получить текущее значение is_block()
Добавить элемент `_имя_->add(_текст_, _флаг_по_которому_определяется_что_это_такое);`

// добавление в общий список списков с значением в теле
DropDownLists.push_back(_имя_);

// файл interface.h
enum DROP_DOWN_LIST_IDENTIFICATORS{
    ...
    _имя_идентификатора_
};

Настройка событий для новых элементов

После того, как вы добавлили новый элемент, вы должны связать эти элементы с каким-то действием.

Кнопка и input

На стадии добавления кнопки, вы указываете тип этой кнопки, то есть что она будет делать, допустим, вы хотите сделать, чтобы эта кнопка была завершающей в какой-либо части вашего интерфейса, и по клику по ней, вы получали значение из input. Рекомендуется, когда вы добавляете кнопку, добавить в файл interface.h в enum BUTTON_TYPES тип вашей кнопки (например, BUTTON_OK_SET_VALUE), которое будет хранить фактическое расположение в массиве кнопок и по которому оно будет в дальнейшем использоваться. После того, как ваша кнопка добавлена и настроена, вы должны перейти в файл Interface_OnEvent_Function.cpp и в функции mouseButtonDown в цикле перебирающем все кнопки в switch добавить ваш флаг в качестве нового case, а внутри прописать необходимые для вас действия. Опять же допустим мы хотим получить значение из input. Для начала настроим сам input. На стадии его добавления, мы прописываем тип, как и кнопки, мы должны добавить новое значение, но теперь в enum INPUT_TYPES. После чего этот input будет доступен по Items->at(_ЗНАЧЕНИЕ_КОТОРОЕ_ВЫ_ДОБАВИЛИ_) . После этого, чтобы получить значение из данного input, вы должны прописать в ранее описанном case в файле Interface_OnEvent_Function.cpp в функции mouseButtonDown в цикле перебирающем все кнопки в switch следующее:

string text = Inputs->at(_ЗНАЧЕНИЕ_КОТОРОЕ_ВЫ_ДОБАВИЛИ_ДЛЯ_INPUT)->getValue();

таким образом в переменной text будет значение из input.

После этого, допустим, вы захотите заблокировать это input, тогда сразу после строк выше, добавьте

Inputs->at(_ЗНАЧЕНИЕ_КОТОРОЕ_ВЫ_ДОБАВИЛИ_ДЛЯ_INPUT_)->Block(true);
Inputs->at(_ЗНАЧЕНИЕ_КОТОРОЕ_ВЫ_ДОБАВИЛИ_ДЛЯ_INPUT_)->render();

! Важно, после того, как вы как-либо изменили элемент, нужно вызвать у него метод render

А для сокрытия элемента, вызовите метод Display(false) и не забудьте вызвать метод render

Выпадающие списки

Работа со списками похожа на работу с кнопками, с тем различием, что мы добавляем типы для каждого элемента. И каждый такой элемент опять же должен иметь свой идентификатор, но уже в enum ITEM_LIST_TYPES для itemList и enum DROP_ITEM_LIST_TYPES для DropDownList (перечисления должны иметь нулевой элемент, нулевой элемент не должен быть функциональным).

После добавления элементов в список, для настройки itemList перейдите в файл Interface_OnEvent_Function.cpp в функции mouseButtonUp в цикле перебирающем все itemList в switch по переменной flag добавьте новые case, как и при работе с кнопками. Именем для case будет добавленные вами идентификаторы в enum ITEM_LIST_TYPES. Допустим у вас есть itemList с следующими полями:

  1. Показать input
  2. Скрыть input

И уже настроенный input с предыдущего примера. Тогда, допустим, у 1 элемента списка будет название SHOW_INPUT, а у 2 — HIDE_INPUT. Добавим их в enum ITEM_LIST_TYPES. Теперь перейдем в файл Interface_OnEvent_Function.cpp в функции mouseButtonUp в цикле перебирающем все itemList в switch по переменной flag добавляем case с SHOW_INPUT и case с HIDE_INPUT.

Пропишем следующие:

case SHOW_INPUT{
  if(!Inputs->at(_ЗНАЧЕНИЕ_КОТОРОЕ_ВЫ_ДОБАВИЛИ_ДЛЯ_INPUT_)->Show()){
    Inputs->at(_ЗНАЧЕНИЕ_КОТОРОЕ_ВЫ_ДОБАВИЛИ_ДЛЯ_INPUT_)->Show(true);
    Inputs->at(_ЗНАЧЕНИЕ_КОТОРОЕ_ВЫ_ДОБАВИЛИ_ДЛЯ_INPUT_)->render();
  }
  break;
}

case HIDE_INPUT{
  if(Inputs->at(_ЗНАЧЕНИЕ_КОТОРОЕ_ВЫ_ДОБАВИЛИ_ДЛЯ_INPUT_)->Show()){
    Inputs->at(_ЗНАЧЕНИЕ_КОТОРОЕ_ВЫ_ДОБАВИЛИ_ДЛЯ_INPUT_)->Show(false);
    Inputs->at(_ЗНАЧЕНИЕ_КОТОРОЕ_ВЫ_ДОБАВИЛИ_ДЛЯ_INPUT_)->render();
  }
  break;
}

И теперь, если мы будем выбирать какой-либо пункт, то будет выполняться требуемое действие.

Работа с DropDownList проще, при выборе нужного нам пункта, значение помещается в внутреннюю переменную этого списка и чтобы ее получить нужно вызвать метод getValue() у нужного вам списка (который вы добавили в enum DROP_ITEM_LIST_TYPES), так

string value = DropDownLists->at(_ЗНАЧЕНИЕ_КОТОРОЕ_ВЫ_ДОБАВИЛИ_)->getValue();

Поле вывода

Как и с предыдущими элементами, при добавлении поля ввода, вы должны задать для него идентификатор в enum TEXT_FIELD_TYPES, для дальнейшего использования. Тогда обращение к нужному будет выглядеть так:

TextFields->at(_ЗНАЧЕНИЕ_КОТОРОЕ_ВЫ_ДОБАВИЛИ_)

Для добавления, как было сказано ранее используется метод add, принимающий string

TextFields->at(_ЗНАЧЕНИЕ_КОТОРОЕ_ВЫ_ДОБАВИЛИ_)->add("new line")

Пара слов о Color.h

Color.h содержит в себе структуру содержащую всю цветовую палитру интерфейса, в ней можно свободно менять все, что захочется. В каждом классе прописан экземпляр данного класса, для доступа к полям.

Пара слов о ваших классах строк

В проекте уже есть все классы для моего варианта, вы можете заменить их полностью, или заменить только 3 класс с изменением 2, как вам захочется. Возможно заменить полностью будет проще.

About

Just simple interface with SDL2 and C++17

License:MIT License


Languages

Language:C++ 96.6%Language:C 3.4%