Files
SDLRousku/NewDialogs/DlgMainMenu.cpp
2024-12-05 20:49:37 +02:00

288 lines
9.1 KiB
C++

#include <string>
#include <vector>
#include <iostream>
#include <sstream>
#include <utility>
#include <algorithm>
using namespace std;
#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
#include <SDL3_ttf/SDL_ttf.h>
#include <SDL3/SDL_storage.h>
#include "../SDLHelpers.h"
#include "Item.h"
#include "Button.h"
#include "Dialog.h"
#include "Frame.h"
#include "DlgMainMenu.h"
#include "../menu_png.h"
SDL_EnumerationResult enumStorage(void *userdata, const char *dirname, const char *fname) {
SDL_Log("dirname %s fname %s", dirname, fname);
SDL_Storage *storage = (SDL_Storage *) ((pair<void *, void *> *)userdata)->first;
vector<string> *list = (vector<string> *) ((pair<void *, void *> *)userdata)->second;
string path("skin/");
path += fname;
SDL_PathInfo pi;
SDL_GetStoragePathInfo(storage, path.c_str(), &pi);
if (pi.type == SDL_PATHTYPE_DIRECTORY) {
SDL_Log("is dir");
// add name to list if list does not yet have it
if (find(list->begin(), list->end(), fname) == list->end()) {
list->push_back(fname);
}
}
return SDL_ENUM_CONTINUE;
}
DlgMainMenu::DlgMainMenu() : Dialog() {
if (!loadBackground()) {
cerr << "Background open failed menu_png! " << SDL_GetError() << endl;
}
vector<string> list;
// adding embedded skins
list.push_back("Tavallinen");
list.push_back("Alppisusi");
list.push_back("Chibi");
SDL_Storage *storage = SDL_OpenTitleStorage(NULL, 0);
if (!storage) {
SDL_Log("Error opening title storage %s", SDL_GetError());
}
pair<void *, void *> userdata(storage, &list);
if (!SDL_EnumerateStorageDirectory(storage, "skin", &enumStorage, &userdata)) {
SDL_Log("Error enumerating dir %s", SDL_GetError());
}
always_on_top_checkbox = new Checkbox("Pysy päällimmäisenä", getColor(0, 0, 0), getRect(16, 24, 200, 12));
always_on_top_checkbox->setSelected(1);
always_on_top_checkbox->setButtonFunc(&settingsChangedCallback, (void *)this);
always_on_top_checkbox->setName("always_on_top");
addItem(always_on_top_checkbox);
enable_sound_checkbox = new Checkbox("Äänet päälle / pois päältä", getColor(0, 0, 0), getRect(16, 40, 200, 12));
enable_sound_checkbox->setSelected(1);
enable_sound_checkbox->setButtonFunc(&settingsChangedCallback, (void *)this);
enable_sound_checkbox->setName("enable_sound");
addItem(enable_sound_checkbox);
open_menu_on_start_checkbox = new Checkbox("Avaa valikko Rouskun käynnistyessä", getColor(0, 0, 0), getRect(16, 56, 200, 12));
open_menu_on_start_checkbox->setSelected(1);
open_menu_on_start_checkbox->setButtonFunc(&settingsChangedCallback, (void *)this);
open_menu_on_start_checkbox->setName("open_menu_on_start");
addItem(open_menu_on_start_checkbox);
run_away_from_mouse_checkbox = new Checkbox("Juokse hiirtä karkuun", getColor(0, 0, 0), getRect(16, 72, 200, 12));
run_away_from_mouse_checkbox->setSelected(0);
run_away_from_mouse_checkbox->setButtonFunc(&settingsChangedCallback, (void *)this);
run_away_from_mouse_checkbox->setName("run_away_from_mouse");
addItem(run_away_from_mouse_checkbox);
skin_list = new DropDownList(list, &dialogs, getRect(16, 104, 200, 25));
skin_list->setSelected(0);
skin_list->setValueChangedFunc(&settingsChangedCallback, (void *)this);
skin_list->setName("skin_list");
addItem(skin_list);
Item *item = new Button("Sulje valikko", getColor(0xB4, 0xC8, 0xB4), getRect(135, 320, 95, 27));
((Button *) item)->setButtonFunc(&contCallback, (void *)this);
addItem(item);
item = new Button("Sulje Rousku", getColor(0xC8, 0xB4, 0xB4), getRect(7, 320, 95, 27));
((Button *) item)->setButtonFunc(&quitCallback, (void *)this);
addItem(item);
readSettings();
setExit(false);
if (!open_menu_on_start_checkbox->isSelected()) {
setExit(true);
}
app_exit = false;
}
DlgMainMenu::~DlgMainMenu() {
deleteSurfaceAndBackground();
deleteItems();
}
void DlgMainMenu::draw() {
Dialog::draw();
// Just drawing preview surface on dialog. Create own Item for preview if needed at some point.
if (preview_sfe) {
SDL_Rect r = { 57, 128, preview_sfe->w, preview_sfe->h };
SDL_BlitSurface(preview_sfe, NULL, surface, &r);
}
// We just draw dialogs on this dialog's surface
for (unsigned int x = 0; x < dialogs.size(); x++) {
SDL_BlitSurface(dialogs[x]->getSurface(), NULL, surface, dialogs[x]->getPos());
//items[x]->drawDone();
}
}
bool DlgMainMenu::onMousePress(int x, int y) {
// we are handling other dialogs as integrated to this dialog so passing our events to them
for (unsigned int z = 0; z < dialogs.size(); z++) {
dialogs[z]->onMousePress(x - dialogs[z]->getPos()->x, y - dialogs[z]->getPos()->y);
if (dialogs[z]->isExit()) {
delete dialogs[z];
dialogs[z] = NULL;
dialogs.erase(dialogs.begin()+z);
z--;
}
}
return Dialog::onMousePress(x, y);
}
bool DlgMainMenu::onMouseRelease(int x, int y) {
// we are handling other dialogs as integrated to this dialog so passing our events to them
for (unsigned int z = 0; z < dialogs.size(); z++) {
dialogs[z]->onMouseRelease(x - dialogs[z]->getPos()->x, y - dialogs[z]->getPos()->y);
}
return Dialog::onMouseRelease(x, y);
}
void DlgMainMenu::readSettings() {
SDL_Storage *strg = SDL_OpenUserStorage("TeamSaunakauha", "Rousku", 0);
Uint64 file_size;
if (!SDL_GetStorageFileSize(strg, "mem.tsk", &file_size)) {
SDL_Log("could not get mem.tsk size %s", SDL_GetError());
return;
}
char buf[file_size];
if (!SDL_ReadStorageFile(strg, "mem.tsk", buf, file_size)) {
SDL_Log("mem.tsk read failed %s", SDL_GetError());
return;
}
SDL_CloseStorage(strg);
string sbuf(buf, file_size);
istringstream ssbuf(sbuf);
string line;
Uint8 lc = 0;
while (getline(ssbuf, line)) {
switch(lc++) {
case 0: always_on_top_checkbox->setSelected(line == "1"); break;
case 1: enable_sound_checkbox->setSelected(line == "1"); break;
case 2: open_menu_on_start_checkbox->setSelected(line == "1"); break;
case 3: run_away_from_mouse_checkbox->setSelected(line == "1"); break;
case 4: skin_list->select(line); break;
}
}
}
void DlgMainMenu::writeSettings() {
stringstream ssbuf;
ssbuf << (always_on_top_checkbox->isSelected() ? 1 : 0) << endl;
ssbuf << (enable_sound_checkbox->isSelected() ? 1 : 0) << endl;
ssbuf << (open_menu_on_start_checkbox->isSelected() ? 1 : 0) << endl;
ssbuf << (run_away_from_mouse_checkbox->isSelected() ? 1 : 0) << endl;
ssbuf << skin_list->getString() << endl;
SDL_Storage *strg = SDL_OpenUserStorage("TeamSaunakauha", "Rousku", 0);
if (!SDL_WriteStorageFile(strg, "mem.tsk", ssbuf.str().c_str(), ssbuf.str().length())) {
SDL_Log("mem.tsk write failed %s", SDL_GetError());
return;
}
SDL_CloseStorage(strg);
}
void DlgMainMenu::contCallback(void *p, Item *i) {
((DlgMainMenu *)p)->cont();
}
void DlgMainMenu::cont() {
setExit(true);
}
void DlgMainMenu::quitCallback(void *p, Item *i) {
((DlgMainMenu *)p)->quit();
}
void DlgMainMenu::quit() {
setAppExit(true);
}
void DlgMainMenu::settingsChangedCallback(void *p, Item *i) {
((DlgMainMenu *)p)->settingsChanged(i);
}
void DlgMainMenu::settingsChanged(Item *i) {
writeSettings();
if (i->getName().length()) {
settings_changed_list.push_back(i->getName());
}
}
void DlgMainMenu::setAppExit(bool app_exit) {
this->app_exit = app_exit;
}
bool DlgMainMenu::isAppExit() {
return app_exit;
}
bool DlgMainMenu::isAlwaysOnTop() {
return always_on_top_checkbox->isSelected();
}
bool DlgMainMenu::isEnableSound() {
return enable_sound_checkbox->isSelected();
}
bool DlgMainMenu::isRunAwayFromMouse() {
return run_away_from_mouse_checkbox->isSelected();
}
string DlgMainMenu::getSkin() {
return skin_list->getString();
}
string DlgMainMenu::getChangedSetting() {
if (settings_changed_list.size()) {
string name = settings_changed_list.back();
settings_changed_list.pop_back();
return name;
} else {
return "";
}
}
void DlgMainMenu::setPreviewSurface(SDL_Surface *preview_sfe) {
this->preview_sfe = preview_sfe;
}
bool DlgMainMenu::loadBackground() {
SDL_IOStream *io = SDL_IOFromConstMem(menu_png, menu_png_len);
if (io == NULL) {
SDL_Log("could not open io for menu_png: %s\n", SDL_GetError());
return false;
}
background = IMG_Load_IO(io, true);
if (background == NULL) {
SDL_Log("could not create pet surface: %s\n", SDL_GetError());
return false;
}
surface = SDL_CreateSurface(background->w, background->h, SDL_GetPixelFormatForMasks(32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000));
SDL_Rect d;
d.x = 0;
d.y = 0;
d.w = background->w;
d.h = background->h;
SDL_SetSurfaceClipRect(surface, &d);
pos.w = background->w;
pos.h = background->h;
return true;
}