Итак, это простой интерфейс для нашей курсовой работы.
- Скопируйте данный репозиторий себе на компьютер
- Скачайте с официального сайта 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, как вам захочется. Возможно заменить полностью будет проще.