/* Copyright (C) 2006 Parallel Realities This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "widgets.h" void drawSelectedListItem(float x, float y, float w, float h, bool isSelectedWidget) { glPushMatrix(); { glEnable(GL_BLEND); glDisable(GL_TEXTURE_2D); glTranslatef(x, y, 0); glBegin(GL_QUADS); { if (isSelectedWidget) { glColor3f(0, 0, 0.25); glVertex2d(0, 0); glColor3f(0, 0, 0.25); glVertex2d(w, 0); glColor3f(0, 0, 0.75); glVertex2d(w, h); glColor3f(0, 0, 0.75); glVertex2d(0, h); } else { glColor3f(0.15, 0.15, 0.15); glVertex2d(0, 0); glColor3f(0.15, 0.15, 0.15); glVertex2d(w, 0); glColor3f(0.25, 0.25, 0.25); glVertex2d(w, h); glColor3f(0.25, 0.25, 0.25); glVertex2d(0, h); } } glEnd(); } glPopMatrix(); } void drawListView(ListView *listView) { int xLoc, yLoc, index; listView->visibleItems = 0; xLoc = listView->x + listView->width; yLoc = listView->y + 2; index = 0; GLColor blue, green; blue.set(0.0, 0.0, 0.45, 1.0); green.set(0.0, 0.45, 0, 1.0); if (listView->getNumberOfPages() > 1) { graphics->drawString(listView->x + listView->width, listView->y - 20, TXT_RIGHT, GLColor::white, true, "Page %d / %d", listView->getCurrentPage(), listView->getNumberOfPages()); } if (!listView->transparent) { graphics->drawRect(listView->x, listView->y, listView->width, listView->height, GLColor::black, GLColor::white, false); } else { graphics->fade(0.75, listView->x, listView->y, listView->width, listView->height); if (listView->border) { graphics->outlineRect(listView->x, listView->y, listView->width, listView->height, GLColor::white); } } for (ListViewItem *item = (ListViewItem*)listView->getList()->getFirstElement() ; item != NULL ; item = (ListViewItem*)item->next) { if (index < listView->startIndex) { index++; continue; } if (!listView->transparent) { graphics->drawRect(listView->x + 2, yLoc, item->texture->iw - 4, item->texture->ih, GLColor::black, false); } glColor3f(1.0, 1.0, 1.0); glEnable(GL_BLEND); graphics->blit(item->texture, listView->x + 2, yLoc, false); if (index == listView->getSelectedIndex()) { drawSelectedListItem(listView->x + 2, yLoc, item->texture->iw - 4, item->texture->ih, (uiManager->focusedWidget == listView)); } item->x = listView->x + 2; item->y = yLoc; yLoc += (item->texture->ih + 2); if (yLoc + item->texture->ih + 2 > listView->height + listView->y) { break; } index++; } listView->endIndex = index; Math::limit(&listView->endIndex, 0, listView->getItemCount() - 1); } void drawCheckBox(CheckBox *checkBox) { if (checkBox->checked) { graphics->blit(uiManager->checked, checkBox->x, checkBox->y, false); } else { graphics->blit(uiManager->unchecked, checkBox->x, checkBox->y, false); } } void drawSlider(Slider *slider) { float percentage = slider->value; percentage /= slider->max; percentage *= (slider->width - 48); percentage = (int)percentage; GLColor c; c.set(0.0, 0.25, 0.0, 1.0); float b = 50; b /= slider->height; b *= 0.01; for (int i = 0 ; i < slider->height ; i++) { graphics->drawRect(slider->x + 24, slider->y + i, (int)percentage, 1, c, false); c.color[1] += b; } if ((slider->value != 0) && (slider->value != slider->max)) { graphics->drawRect(slider->x + 25 + (int)percentage - 1, slider->y, 1, slider->height, GLColor::green, false); } graphics->outlineRect(slider->x + 24, slider->y, slider->width - 48, slider->height, GLColor::white); glEnable(GL_BLEND); (percentage == 0) ? glColor4f(1.0, 1.0, 1.0, 0.25) : glColor3f(1.0, 1.0, 1.0); graphics->blit(uiManager->minus, slider->x, slider->y - 1, false); (slider->value == slider->max) ? glColor4f(1.0, 1.0, 1.0, 0.25) : glColor3f(1.0, 1.0, 1.0); graphics->blit(uiManager->plus, (slider->x + slider->width - 16), slider->y - 1, false); slider->update(); } void drawComboBox(ComboBox *comboBox) { graphics->setFont(FONT_NORMAL); graphics->drawString((comboBox->x + comboBox->width / 2), comboBox->y, TXT_CENTERED, GLColor::white, true, "%s", comboBox->currentItemText.getText()); (comboBox->selectedItem != 0) ? glColor3f(1.0, 1.0, 1.0) : glColor4f(1.0, 1.0, 1.0, 0.25); graphics->blit(uiManager->minus, comboBox->x, comboBox->y - 1, false); (comboBox->selectedItem != comboBox->itemList.getSize() - 1) ? glColor3f(1.0, 1.0, 1.0) : glColor4f(1.0, 1.0, 1.0, 0.25); graphics->blit(uiManager->plus, (comboBox->x + comboBox->width - 16), comboBox->y - 1, false); } void drawInputWidget(InputWidget *inputWidget) { static bool useOr; static String renderString; static String keyString, joyString, mouseString; useOr = false; if (inputWidget->redraw) { renderString = "N/A"; keyString = ""; joyString = ""; mouseString = ""; inputWidget->redraw = false; if (inputWidget->value[INPUT_KEY] != -1) { String keyName = SDL_GetKeyName((SDLKey)inputWidget->value[INPUT_KEY]); if (keyName != "unknown key") { keyName.captialise(); keyString = keyName.getText(); useOr = true; } } if (inputWidget->value[INPUT_JOY] != -1) { if (useOr) { joyString.setText(_(" or Joy %d"), inputWidget->value[INPUT_JOY]); } else { joyString.setText(_("Joy %d"), inputWidget->value[INPUT_JOY]); } useOr = true; } if (inputWidget->value[INPUT_MOUSE] != -1) { if (useOr) { mouseString.setText(_(" or Mouse %s"), mouse->translateMouseButton(inputWidget->value[INPUT_MOUSE])); } else { mouseString.setText(_("Mouse %s"), mouse->translateMouseButton(inputWidget->value[INPUT_MOUSE])); } useOr = true; } if ((keyString != "") || (joyString != "") || (mouseString != "")) { renderString.setText("%s%s%s", keyString.getText(), joyString.getText(), mouseString.getText()); } if (inputWidget->normalImage != NULL) { delete inputWidget->normalImage; } inputWidget->normalImage = graphics->getGLString("%s", renderString.getText()); glEnable(GL_BLEND); inputWidget->currentImage = inputWidget->normalImage; inputWidget->width = inputWidget->normalImage->iw; inputWidget->height = inputWidget->normalImage->ih; } if (!inputWidget->awaitingInput) { glColor3f(0.0, 1.0, 0.0); graphics->blit(inputWidget->currentImage, inputWidget->x, inputWidget->y - 5, false); } else { glColor3f(0.5, 0.5, 0.5); graphics->blit(uiManager->awaitingButton, inputWidget->x, inputWidget->y - 5, false); } } void createWidgetColors(BaseWidget *widget, Properties *props) { int red, green, blue; props->getInt("width", 0); sscanf(props->getString("fontColor", "255 255 255"), "%d %d %d", &red, &green, &blue); widget->fontColorRed = red; widget->fontColorGreen = green; widget->fontColorBlue = blue; sscanf(props->getString("backgroundColor", "180 180 180"), "%d %d %d", &red, &green, &blue); widget->backgroundColorRed = red; widget->backgroundColorGreen = green; widget->backgroundColorBlue = blue; } BaseWidget *createPanelWidget(Properties *props) { //debug(("createPanelWidget()\n")); Panel *panel = (Panel*)uiManager->spawnWidget(PANEL); panel->setProperties(props); return panel; } BaseWidget *createButtonWidget(Properties *props) { //debug(("createButtonWidget()\n")); Button *button = (Button*)uiManager->spawnWidget(BUTTON); button->setProperties(props); createWidgetColors(button, props); int color, disabledRed, disabledGreen, disabledBlue; color = graphics->getColor(button->backgroundColorRed, button->backgroundColorGreen, button->backgroundColorBlue); disabledRed = button->backgroundColorRed / 2; disabledGreen = button->backgroundColorGreen / 2; disabledBlue = button->backgroundColorBlue / 2; Math::limit(&disabledRed, 0, 255); Math::limit(&disabledGreen, 0, 255); Math::limit(&disabledBlue, 0, 255); graphics->setFontColor(0xff, 0xff, 0xaa, 0x00, 0x00, 0x00); graphics->setFont(button->fontSize); SDL_Surface *labelImage = graphics->getString(true, "%s", button->label.getText()); graphics->setFontColor(0x88, 0x88, 0x88, 0x00, 0x00, 0x00); graphics->setFont(button->fontSize); SDL_Surface *disabledLabelImage = graphics->getString(true, "%s", button->label.getText()); int colSpan = props->getInt("colSpan", 1); colSpan = max(colSpan, 1); Grid *grid = uiManager->getGrid(props->getString("grid", "unknown")); int width = (grid->getCellWidth() * colSpan) - (grid->cellSpacing * 2); int height = labelImage->h + 5; SDL_Surface *normalImage, *clickedImage, *disabledImage; // create the unclicked image for the button normalImage = graphics->createSurface(width, height); graphics->drawGradient(normalImage, button->backgroundColorRed, button->backgroundColorGreen, button->backgroundColorBlue, 0, 0, 0); graphics->blit(labelImage, width / 2, height / 2, normalImage, true); graphics->createRaisedBorder(normalImage, graphics->white, graphics->darkGrey); // create the clicked image for the button clickedImage = graphics->createSurface(width, height); graphics->drawGradient(clickedImage, button->backgroundColorRed, button->backgroundColorGreen, button->backgroundColorBlue, 0, 0, 0); graphics->blit(labelImage, (width / 2) + 1, (height / 2) + 1, clickedImage, true); graphics->createLoweredBorder(clickedImage, graphics->white, graphics->darkGrey); // create the disabled image for the button disabledImage = graphics->createSurface(width, height); graphics->drawGradient(disabledImage, disabledRed, disabledGreen, disabledBlue, 0, 0, 0); graphics->blit(disabledLabelImage, width / 2, height / 2, disabledImage, true); button->normalImage = graphics->createTexture(normalImage); button->clickedImage = graphics->createTexture(clickedImage); button->disabledImage = graphics->createTexture(disabledImage); String s; s.setText("normalImage-%s-%s", button->getName(), button->getGroupName()); textureManager->addTexture(s.getText(), button->normalImage); s.setText("clickedImage-%s-%s", button->getName(), button->getGroupName()); textureManager->addTexture(s.getText(), button->clickedImage); s.setText("disabledImage-%s-%s", button->getName(), button->getGroupName()); textureManager->addTexture(s.getText(), button->disabledImage); button->currentImage = button->normalImage; button->width = button->currentImage->iw; button->height = button->currentImage->ih; SDL_FreeSurface(labelImage); SDL_FreeSurface(disabledLabelImage); return button; } BaseWidget *createCheckBoxWidget(Properties *props) { CheckBox *checkBox = (CheckBox*)uiManager->spawnWidget(CHECKBOX); checkBox->setProperties(props); checkBox->width = 16; checkBox->height = 16; return checkBox; } BaseWidget *createListViewWidget(Properties *props) { //debug(("createListViewWidget()\n")); ListView *listView = (ListView*)uiManager->spawnWidget(LISTVIEW); listView->setProperties(props); createWidgetColors(listView, props); //drawListView(listView); listView->currentImage = listView->normalImage; return listView; } BaseWidget *createSliderWidget(Properties *props) { //debug(("createSliderWidget()\n")); Slider *slider = (Slider*)uiManager->spawnWidget(SLIDER); slider->setProperties(props); createWidgetColors(slider, props); Grid *grid = uiManager->getGrid(props->getString("grid", "unknown")); int colSpan = props->getInt("colSpan", 1); int rowSpan = props->getInt("rowSpan", 1); slider->width = (grid->getCellWidth() * colSpan) - (grid->cellSpacing * 2); slider->height = (grid->getCellHeight() * rowSpan) - (grid->cellSpacing * 2); return slider; } BaseWidget *createComboBoxWidget(Properties *props) { //debug(("createComboBoxWidget()\n")); ComboBox *comboBox = (ComboBox*)uiManager->spawnWidget(COMBOBOX); comboBox->setProperties(props); createWidgetColors(comboBox, props); Grid *grid = uiManager->getGrid(props->getString("grid", "unknown")); int colSpan = props->getInt("colSpan", 1); int rowSpan = props->getInt("rowSpan", 1); comboBox->width = (grid->getCellWidth() * colSpan) - (grid->cellSpacing * 2); comboBox->height = (grid->getCellHeight() * rowSpan) - (grid->cellSpacing * 2); return comboBox; } BaseWidget *createLabelWidget(Properties *props) { //debug(("createLabelWidget()\n")); Label *label = (Label*)uiManager->spawnWidget(LABEL); label->setProperties(props); createWidgetColors(label, props); graphics->setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00); label->currentImage = graphics->getGLString("%s", label->text.getText()); return label; } BaseWidget *createInputWidget(Properties *props) { //debug(("createLabelWidget()\n")); int type = engine->getValueOfDefine(props->getString("widgetType", "INPUT_KEY")); InputWidget *inputWidget = (InputWidget*)uiManager->spawnWidget(type); inputWidget->setProperties(props); createWidgetColors(inputWidget, props); return inputWidget; } void loadWidgets(char *file) { debug(("loadWidgets()\n")); List *widgetList = loadProperties(file, true); BaseWidget *widget; Grid *grid; int widgetType = -1; for (Properties *props = (Properties*)widgetList->getFirstElement() ; props != NULL ; props = (Properties*)props->next) { if (props->name == "Grid") { grid = uiManager->spawnGrid(); grid->setProperties(props); continue; debug(("Created Grid '%s'\n", grid->name.getText())); } if (props->name != "Widget") { printf("WARNING: Properties not named 'Widget'. Skipping.\n"); continue; } widget = NULL; widgetType = engine->getValueOfDefine(props->getString("widgetType", "-1")); switch (widgetType) { case BUTTON: widget = createButtonWidget(props); break; case PANEL: widget = createPanelWidget(props); break; case SLIDER: widget = createSliderWidget(props); break; case LABEL: widget = createLabelWidget(props); break; case LISTVIEW: widget = createListViewWidget(props); break; case CHECKBOX: widget = createCheckBoxWidget(props); break; case COMBOBOX: widget = createComboBoxWidget(props); break; case INPUT: widget = createInputWidget(props); break; default: printf("ERROR: loadWidgets() - Widget of type '%s' unknown!\n", props->getString("name", "unnamed")); exit(1); break; } widget->updatePosition(); } } void drawWidgets() { Panel *panel; GLColor color; graphics->setMode(MODE_2D); for (BaseWidget *widget = (BaseWidget*)uiManager->getWidgetList()->getFirstElement() ; widget != NULL ; widget = (BaseWidget*) widget->next) { if (!widget->isVisible()) { continue; } if ((uiManager->modalGroup != "") && (uiManager->modalGroup != widget->getGroupName())) { continue; } if (widget->currentImage == NULL) { widget->currentImage = widget->normalImage; } if (widget->getWidgetType() == PANEL) { panel = (Panel*)widget; graphics->fade(0.75, panel->x, panel->y, panel->width, panel->height); graphics->outlineRect(panel->x, panel->y, panel->width, panel->height, GLColor::white); } else { if (widget->getWidgetType() == BUTTON) { graphics->drawRect(widget->x, widget->y, widget->width, widget->height, GLColor::black, false); glColor4f(1.0, 1.0, 1.0, 1.0); if (!mouse->isBusy()) { if ((widget->getWidgetType() == BUTTON) && (widget->isEnabled())) { if (Collision::collision(mouse->x, mouse->y, 1, 1, widget->x, widget->y, widget->width, widget->height)) { glColor4f(1.0, 0.0, 1.0, 1.0); } } } } else { glColor4f(1.0, 1.0, 1.0, 1.0); } } switch (widget->getWidgetType()) { case -1: printf("ERROR: %s has type -1!\n", widget->getName()); exit(1); break; case LISTVIEW: drawListView((ListView*)widget); break; case CHECKBOX: drawCheckBox((CheckBox*)widget); break; case SLIDER: drawSlider((Slider*)widget); break; case COMBOBOX: drawComboBox((ComboBox*)widget); break; case LABEL: glEnable(GL_BLEND); graphics->blit(widget->currentImage, widget->x, widget->y - 5, false); break; case INPUT: drawInputWidget((InputWidget*)widget); break; default: glEnable(GL_BLEND); graphics->blit(widget->currentImage, widget->x, widget->y, false); break; } } moveMouseCursor(); }