ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

about.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "engines/metaengine.h"
00024 #include "base/plugins.h"
00025 #include "base/version.h"
00026 #include "common/events.h"
00027 #include "common/system.h"
00028 #include "common/translation.h"
00029 #include "common/util.h"
00030 #include "gui/about.h"
00031 #include "gui/gui-manager.h"
00032 #include "gui/ThemeEval.h"
00033 
00034 namespace GUI {
00035 
00036 enum {
00037     kScrollStartDelay = 1500,
00038     kScrollMillisPerPixel = 60
00039 };
00040 
00041 // Every Line should start with a letter followed by a digit. Currently those can be
00042 // (all subject to change)
00043 // Letter:
00044 //   C, L, R     -- set center/left/right alignment
00045 //   A           -- ASCII text to replace the next (latin1) line
00046 // Digit:
00047 //   0 - 2       -- set a custom color:
00048 //                  0 normal text
00049 //                  1 highlighted text
00050 //                  2 disabled text
00051 // TODO: Maybe add a tab/indent feature; that is, make it possible to specify
00052 // an amount by which that line shall be indented (the indent of course would have
00053 // to be considered while performing any word wrapping, too).
00054 //
00055 // TODO: Add different font sizes (for bigger headlines)
00056 // TODO: Allow color change in the middle of a line...
00057 
00058 static const char *copyright_text[] = {
00059 "",
00060 "C0""Copyright (C) 2003-2019 The ResidualVM Team",
00061 "C0""http://www.residualvm.org",
00062 "",
00063 "C0""ResidualVM is the legal property of its developers, whose names are too numerous to list here. Please refer to the AUTHORS file distributed with this binary.",
00064 "",
00065 };
00066 
00067 static const char *gpl_text[] = {
00068 "",
00069 "C0""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.",
00070 "C0""",
00071 "C0""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.",
00072 "",
00073 "C0""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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.",
00074 "",
00075 };
00076 
00077 #include "gui/credits.h"
00078 
00079 AboutDialog::AboutDialog()
00080     : Dialog(10, 20, 300, 174),
00081     _scrollPos(0), _scrollTime(0), _willClose(false) {
00082 
00083     reflowLayout();
00084 
00085     int i;
00086 
00087     for (i = 0; i < 1; i++)
00088         _lines.push_back("");
00089 
00090     Common::String version("C0""ResidualVM ");
00091     version += gScummVMVersion;
00092     _lines.push_back(version);
00093 
00094     Common::String date = Common::String::format(_("(built on %s)"), gScummVMBuildDate);
00095     _lines.push_back("C2" + date);
00096 
00097     for (i = 0; i < ARRAYSIZE(copyright_text); i++)
00098         addLine(copyright_text[i]);
00099 
00100     Common::String features("C1");
00101     features += _("Features compiled in:");
00102     addLine(features.c_str());
00103     Common::String featureList("C0");
00104     featureList += gScummVMFeatures;
00105     addLine(featureList.c_str());
00106 
00107     _lines.push_back("");
00108 
00109     Common::String engines("C1");
00110     engines += _("Available engines:");
00111     addLine(engines.c_str());
00112 
00113     const PluginList &plugins = EngineMan.getPlugins();
00114     PluginList::const_iterator iter = plugins.begin();
00115     for (; iter != plugins.end(); ++iter) {
00116         Common::String str;
00117         str = "C0";
00118         str += (*iter)->getName();
00119         addLine(str.c_str());
00120 
00121         str = "C2";
00122         str += (*iter)->get<MetaEngine>().getOriginalCopyright();
00123         addLine(str.c_str());
00124 
00125         //addLine("");
00126     }
00127 
00128     for (i = 0; i < ARRAYSIZE(gpl_text); i++)
00129         addLine(gpl_text[i]);
00130 
00131     _lines.push_back("");
00132 
00133     for (i = 0; i < ARRAYSIZE(credits); i++)
00134         addLine(credits[i]);
00135 }
00136 
00137 void AboutDialog::addLine(const char *str) {
00138     if (*str == 0) {
00139         _lines.push_back("");
00140     } else {
00141         Common::String format(str, 2);
00142         str += 2;
00143 
00144         static Common::String asciiStr;
00145         if (format[0] == 'A') {
00146             bool useAscii = false;
00147 #ifdef USE_TRANSLATION
00148             // We could use TransMan.getCurrentCharset() but rather than compare strings
00149             // it is easier to use TransMan.getCharsetMapping() (non null in case of non
00150             // ISO-8859-1 mapping)
00151             useAscii = (TransMan.getCharsetMapping() != NULL);
00152 #endif
00153             if (useAscii)
00154                 asciiStr = str;
00155             return;
00156         }
00157         StringArray wrappedLines;
00158         if (!asciiStr.empty()) {
00159             g_gui.getFont().wordWrapText(asciiStr, _w - 2 * _xOff, wrappedLines);
00160             asciiStr.clear();
00161         } else
00162             g_gui.getFont().wordWrapText(str, _w - 2 * _xOff, wrappedLines);
00163 
00164         for (StringArray::const_iterator i = wrappedLines.begin(); i != wrappedLines.end(); ++i) {
00165             _lines.push_back(format + *i);
00166         }
00167     }
00168 }
00169 
00170 
00171 void AboutDialog::open() {
00172     _scrollTime = g_system->getMillis() + kScrollStartDelay;
00173     _scrollPos = 0;
00174     _willClose = false;
00175 
00176     Dialog::open();
00177 }
00178 
00179 void AboutDialog::close() {
00180     Dialog::close();
00181 }
00182 
00183 void AboutDialog::drawDialog(DrawLayer layerToDraw) {
00184     Dialog::drawDialog(layerToDraw);
00185 
00186     setTextDrawableArea(Common::Rect(_x, _y, _x + _w, _y + _h));
00187 
00188     // Draw text
00189     // TODO: Add a "fade" effect for the top/bottom text lines
00190     // TODO: Maybe prerender all of the text into another surface,
00191     //       and then simply compose that over the screen surface
00192     //       in the right way. Should be even faster...
00193     const int firstLine = _scrollPos / _lineHeight;
00194     const int lastLine = MIN((_scrollPos + _h) / _lineHeight + 1, (uint32)_lines.size());
00195     int y = _y + _yOff - (_scrollPos % _lineHeight);
00196 
00197     for (int line = firstLine; line < lastLine; line++) {
00198         const char *str = _lines[line].c_str();
00199         Graphics::TextAlign align = Graphics::kTextAlignCenter;
00200         ThemeEngine::WidgetStateInfo state = ThemeEngine::kStateEnabled;
00201         if (*str) {
00202             switch (str[0]) {
00203             case 'C':
00204                 align = Graphics::kTextAlignCenter;
00205                 break;
00206             case 'L':
00207                 align = Graphics::kTextAlignLeft;
00208                 break;
00209             case 'R':
00210                 align = Graphics::kTextAlignRight;
00211                 break;
00212             default:
00213                 error("Unknown scroller opcode '%c'", str[0]);
00214                 break;
00215             }
00216             switch (str[1]) {
00217             case '0':
00218                 state = ThemeEngine::kStateEnabled;
00219                 break;
00220             case '1':
00221                 state = ThemeEngine::kStateHighlight;
00222                 break;
00223             case '2':
00224                 state = ThemeEngine::kStateDisabled;
00225                 break;
00226             case '3':
00227                 warning("Need state for color 3");
00228                 // color = g_gui._shadowcolor;
00229                 break;
00230             case '4':
00231                 warning("Need state for color 4");
00232                 // color = g_gui._bgcolor;
00233                 break;
00234             default:
00235                 error("Unknown color type '%c'", str[1]);
00236             }
00237             str += 2;
00238         }
00239         // Trim leading whitespaces if center mode is on
00240         if (align == Graphics::kTextAlignCenter)
00241             while (*str && *str == ' ')
00242                 str++;
00243 
00244         if (*str)
00245             g_gui.theme()->drawText(Common::Rect(_x + _xOff, y, _x + _w - _xOff, y + g_gui.theme()->getFontHeight()),
00246                                     str, state, align, ThemeEngine::kTextInversionNone, 0, false,
00247                                     ThemeEngine::kFontStyleBold, ThemeEngine::kFontColorNormal, true, _textDrawableArea);
00248         y += _lineHeight;
00249     }
00250 }
00251 
00252 void AboutDialog::handleTickle() {
00253     const uint32 t = g_system->getMillis();
00254     int scrollOffset = ((int)t - (int)_scrollTime) / kScrollMillisPerPixel;
00255     if (scrollOffset > 0) {
00256         int modifiers = g_system->getEventManager()->getModifierState();
00257 
00258         // Scroll faster when shift is pressed
00259         if (modifiers & Common::KBD_SHIFT)
00260             scrollOffset *= 4;
00261         // Reverse scrolling when alt is pressed
00262         if (modifiers & Common::KBD_ALT)
00263             scrollOffset *= -1;
00264         _scrollPos += scrollOffset;
00265         _scrollTime = t;
00266 
00267         if (_scrollPos < 0) {
00268             _scrollPos = 0;
00269         } else if ((uint32)_scrollPos > _lines.size() * _lineHeight) {
00270             _scrollPos = 0;
00271             _scrollTime += kScrollStartDelay;
00272         }
00273         drawDialog(kDrawLayerForeground);
00274     }
00275 }
00276 
00277 void AboutDialog::handleMouseUp(int x, int y, int button, int clickCount) {
00278     // Close upon any mouse click
00279     close();
00280 }
00281 
00282 void AboutDialog::handleKeyDown(Common::KeyState state) {
00283     if (state.ascii)
00284         _willClose = true;
00285 }
00286 
00287 void AboutDialog::handleKeyUp(Common::KeyState state) {
00288     if (state.ascii && _willClose)
00289         close();
00290 }
00291 
00292 void AboutDialog::reflowLayout() {
00293     Dialog::reflowLayout();
00294     int i;
00295     const int screenW = g_system->getOverlayWidth();
00296     const int screenH = g_system->getOverlayHeight();
00297 
00298     _xOff = g_gui.xmlEval()->getVar("Globals.About.XOffset", 5);
00299     _yOff = g_gui.xmlEval()->getVar("Globals.About.YOffset", 5);
00300     int outerBorder = g_gui.xmlEval()->getVar("Globals.About.OuterBorder");
00301 
00302     _w = screenW - 2 * outerBorder;
00303     _h = screenH - 2 * outerBorder;
00304 
00305     _lineHeight = g_gui.getFontHeight() + 3;
00306 
00307     // Heuristic to compute 'optimal' dialog width
00308     int maxW = _w - 2*_xOff;
00309     _w = 0;
00310     for (i = 0; i < ARRAYSIZE(credits); i++) {
00311         int tmp = g_gui.getStringWidth(credits[i]) + 5;
00312         if (_w < tmp && tmp <= maxW) {
00313             _w = tmp;
00314         }
00315     }
00316     _w += 2*_xOff;
00317 
00318     // Center the dialog
00319     _x = (screenW - _w) / 2;
00320     _y = (screenH - _h) / 2;
00321 }
00322 
00323 } // End of namespace GUI


Generated on Sat Mar 16 2019 05:01:17 for ResidualVM by doxygen 1.7.1
curved edge   curved edge