Итак, это простой интерфейс для нашей курсовой работы.
- Скопируйте данный репозиторий себе на компьютер
- Скачайте с официального сайта SDL2 пакет
Development Librariesи распакуйте его содержимое в папку SDL2 на дискС:\ - Скачайте библиотеку SDL2_ttf
(Development Libraries) Visual C++ 32/64-bitи распакуйте ее в папку сSDL2 - Скачайте библиотеку SDL2_image
(Development Libraries) Visual C++ 32/64-bitи распакуйте ее в папку сSDL2 - Откройте проект в Visual Studio 2019
- Перейдите в
Проект-Свойства simple-interface-SDL2и проверьте вкладкуС/С++-ОбщиеполеДополнительные катологи включаемых файлов. В случае если там нет путей к библиотекам пропишите слудующее:C:\SDL2\SDL2_ttf-2.0.15\include;C:\SDL2\SDL2_image-2.0.4\include;C:\SDL2\include;, где замените в случае надобности версии скачанных вами библиотек. - Перейдите во вкладку
Компоновщик-Общее, где проверьте полеДополнительные каталоги библиотек, в случае отсутствия путей пропишите следующее:C:\SDL2\SDL2_ttf-2.0.15\lib\x86;C:\SDL2\SDL2_image-2.0.4\lib\x86;C:\SDL2\lib\x86; - Перейдите во вкладку
Компоновщик-Ввод, где проверьте полеДополнительные зависимости, в случае отсутствия пропишите следующее:SDL2.lib;SDL2main.lib;SDL2test.lib;SDL2_ttf.lib;SDL2_image.lib; - Перейдите во вкладку
Компоновщик-Системаи в полеПодсистемапоставьтеКонсоль - Запустите отладку проекта
- Вы получите ошибку, о том, что
SDL2.dllне найден - Скопируйте
*.dllиз папкиdllв папкуdebug, рядом с файлом*.exe - Запустите отладку проекта
- Если все предыдущие пункты выполнены, вы должны получить пустое окно
Первым делом, настраивается размер окна, перейдите в файл 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.
Теперь рассмотрим элементы которые можно добавить:
Простая надпись.
Для ее добавления синтаксис такой
// файл 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{
...
_имя_идентификатора_
};Для ее добавления синтаксис такой
// файл 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{
...
_имя_идентификатора_
};Для его добавления синтаксис такой
// файл 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{
...
_имя_идентификатора_
};Для его добавления синтаксис такой
// файл 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{
...
_имя_идентификатора_
};Для его добавления синтаксис такой
// файл 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{
...
_имя_идентификатора_
};Для его добавления синтаксис такой
// файл 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. Рекомендуется, когда вы добавляете кнопку, добавить в файл 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 с следующими полями:
- Показать
input - Скрыть
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 содержит в себе структуру содержащую всю цветовую палитру интерфейса, в ней можно свободно менять все, что захочется. В каждом классе прописан экземпляр данного класса, для доступа к полям.
В проекте уже есть все классы для моего варианта, вы можете заменить их полностью, или заменить только 3 класс с изменением 2, как вам захочется. Возможно заменить полностью будет проще.