#include #include using namespace std; #include #include #include "../SDLHelpers.h" #include "DropDownList.h" #include "DlgDropDownList.h" DropDownList::DropDownList(vector list, vector *dialogs, SDL_Rect pos) : Item(pos) { this->list = list; this->dialogs = dialogs; selected = 0; pressed = false; listbox_item_size = 20; value_changed_func = NULL; setSurface(SDL_CreateSurface(getPos()->w, getPos()->h, SDL_GetPixelFormatForMasks(32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000))); drawDropDownList(); } DropDownList::~DropDownList() { SDL_DestroySurface(getSurface()); } void DropDownList::drawDropDownList() { listbox_height = list.size() * listbox_item_size; SDL_Surface *surface = getSurface(); int w = getPos()->w; int h = getPos()->h; Uint32 *p = (Uint32 *) surface->pixels; SDL_Color color; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { if (y == 0 || y == h-1 || x == 0 || x == w-1 || x == w-18) { color.r = 0; color.g = 0; color.b = 0; } else { color.r = 255; color.g = 255; color.b = 255; } *p = SDL_MapRGB(SDL_GetPixelFormatDetails(surface->format), NULL, color.r, color.g, color.b); p++; } } //drawing arrow p = (Uint32 *) surface->pixels; int posx = w - 13; int posy = h / 2 - 2; for (int y = 0; y < 4; y++) { for (int x = 0; x < 8 - y * 2; x++) { p[(posy + y) * w + (posx + x + y)] = SDL_MapRGB(SDL_GetPixelFormatDetails(surface->format), NULL, color.r, color.g, color.b); } } SDL_Color text_color = {0, 0, 0}; vector fonts; fonts.push_back("ariblk.ttf"); fonts.push_back("FreeSans.ttf"); fonts.push_back("DejaVuSans.ttf"); fonts.push_back("arial.ttf"); TTF_Font *font = openFont(fonts, 14); SDL_Surface *text_surface; if (!font) cout << "TTF_OpenFont is broken!" << endl; if(!(text_surface = TTF_RenderText_Blended(font, list[selected].c_str(), list[selected].length(), text_color))) cout << SDL_GetError() << endl; SDL_Rect pos; pos.x = 8; pos.y = surface->h / 2 - text_surface->h / 2; SDL_BlitSurface(text_surface, NULL, surface, &pos); SDL_DestroySurface(text_surface); TTF_CloseFont(font); } bool DropDownList::onMousePress(int x, int y) { bool is_in_x = x > getPos()->x && x < getPos()->x + getPos()->w; bool is_in_y = y > getPos()->y && y < getPos()->y + getPos()->h; if (is_in_x && is_in_y) { //setSurface(buttonDown); pressed = true; return true; } return false; } void DropDownList::onMouseRelease(int x, int y) { bool is_in_x = x > getPos()->x && x < getPos()->x + getPos()->w; bool is_in_y = y > getPos()->y && y < getPos()->y + getPos()->h; if (is_in_x && is_in_y && pressed) { int height; bool add_scrollbar; if (listbox_height < 200) { height = listbox_height; add_scrollbar = false; } else { height = 200; add_scrollbar = true; } dialogs->push_back(new DlgDropDownList(this, getRect(getPos()->x, getPos()->y + getPos()->h, getPos()->w, height), add_scrollbar)); } //setSurface(buttonUp); pressed = false; } vector DropDownList::getList() { return list; } void DropDownList::setSelected(int selected) { this->selected = selected; if (value_changed_func) { (*value_changed_func)(p, this); } drawDropDownList(); } void DropDownList::setValueChangedFunc(void (*value_changed_func)(void *p, Item *i), void *p) { this->value_changed_func = value_changed_func; this->p = p; } string DropDownList::getString() { return list[selected]; } void DropDownList::reset() { list.clear(); } void DropDownList::add(string s) { list.push_back(s); } bool DropDownList::select(string s) { for (int x = 0; x < list.size(); x++) { if (list[x].compare(s) == 0) { setSelected(x); return true; } } return false; } int DropDownList::getListboxItemSize() { return listbox_item_size; } int DropDownList::getListboxHeight() { return listbox_height; }