gcsx_progress.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* GCSx
  2. ** PROGRESS.CPP
  3. **
  4. ** Non-interactive progress meter popup window
  5. */
  6. /*****************************************************************************
  7. ** Copyright (C) 2003-2006 Janson
  8. **
  9. ** This program is free software; you can redistribute it and/or modify
  10. ** it under the terms of the GNU General Public License as published by
  11. ** the Free Software Foundation; either version 2 of the License, or
  12. ** (at your option) any later version.
  13. **
  14. ** This program is distributed in the hope that it will be useful,
  15. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. ** GNU General Public License for more details.
  18. **
  19. ** You should have received a copy of the GNU General Public License
  20. ** along with this program; if not, write to the Free Software
  21. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
  22. *****************************************************************************/
  23. #include "all.h"
  24. ProgressMeter::ProgressMeter(long long myTotal) : Window() { start_func
  25. // Keep it simple- total must be > 0
  26. if (myTotal < 1) myTotal = 1;
  27. total = myTotal;
  28. position = 0;
  29. myFrame = NULL;
  30. resize(screenWidth / 2, PROGRESS_METER_HEIGHT);
  31. openTimer = SDL_GetTicks();
  32. progressDone = 0;
  33. lastUpdate = SDL_GetTicks();
  34. }
  35. ProgressMeter::~ProgressMeter() { start_func
  36. }
  37. int ProgressMeter::tempFocus() const { start_func
  38. return 1;
  39. }
  40. void ProgressMeter::openMeter() { start_func
  41. // Prevent duplication
  42. if (myFrame) {
  43. desktop->bringToTop(myFrame);
  44. return;
  45. }
  46. // We remember the frame pointer even though it'll delete itself
  47. myFrame = new FrameWindow(blankString, FrameWindow::RESIZING_OFF, FrameWindow::FRAMETYPE_BEVEL_BK, this, FrameWindow::TITLEBAR_OFF);
  48. // Center
  49. int xPos = (screenWidth - myFrame->getWidth()) / 2;
  50. if (xPos < 0) xPos = 0;
  51. int yPos = (screenHeight - myFrame->getHeight()) / 2;
  52. if (yPos < 0) yPos = 0;
  53. myFrame->show(xPos, yPos, FrameWindow::SHOW_CURRENT, FrameWindow::SHOW_CURRENT);
  54. updateDisplay();
  55. }
  56. void ProgressMeter::updateDisplay() { start_func
  57. setDirty(1);
  58. Uint32 ticks = SDL_GetTicks();
  59. if (ticks > lastUpdate) {
  60. lastUpdate = ticks + 3;
  61. SDL_PumpEvents();
  62. desktop->updateScreen();
  63. }
  64. }
  65. void ProgressMeter::updateProgress(long long myPosition) { start_func
  66. if (myPosition < 0) myPosition = 0;
  67. if (myPosition > total) myPosition = total;
  68. position = myPosition;
  69. if (myFrame == NULL) {
  70. Uint32 ticks = SDL_GetTicks();
  71. // (catch wraparound)
  72. if (ticks < openTimer) openTimer = SDL_GetTicks();
  73. else if (ticks - openTimer > DELAY_AUTO_OPEN) {
  74. openMeter();
  75. }
  76. }
  77. else {
  78. updateDisplay();
  79. }
  80. }
  81. void ProgressMeter::doneProgress(int cleanEvents) { start_func
  82. if (myFrame) {
  83. // Shouldn't clear focus/etc events... just SDL events like clicks/keys
  84. if (cleanEvents) desktop->initEventCleanup();
  85. closeTimer = SDL_GetTicks();
  86. progressDone = 1;
  87. }
  88. else delete this;
  89. }
  90. int ProgressMeter::event(int hasFocus, const SDL_Event* event) { start_func
  91. assert(event);
  92. switch (event->type) {
  93. case SDL_SPECIAL:
  94. if ((event->user.code & SDL_IDLE) && (progressDone)) {
  95. Uint32 ticks = SDL_GetTicks();
  96. // (catch wraparound)
  97. if (ticks < closeTimer) closeTimer = SDL_GetTicks();
  98. else if (ticks - closeTimer > DELAY_AUTO_CLOSE) {
  99. myFrame->closeWindow();
  100. }
  101. return 1;
  102. }
  103. break;
  104. }
  105. return 0;
  106. }
  107. void ProgressMeter::display(SDL_Surface* destSurface, Rect& toDisplay, const Rect& clipArea, int xOffset, int yOffset) { start_func
  108. assert(destSurface);
  109. if (visible) {
  110. // If drawing, redraw all
  111. if ((dirty) || (toDisplay.w)) {
  112. getRect(toDisplay);
  113. toDisplay.x += xOffset;
  114. toDisplay.y += yOffset;
  115. dirty = totalDirty = 0;
  116. // Don't clip- for gradient purposes
  117. // intersectRects(toDisplay, clipArea);
  118. }
  119. xOffset += x;
  120. yOffset += y;
  121. // Anything to draw?
  122. if (toDisplay.w) {
  123. // Outermost
  124. SDL_SetClipRect(destSurface, &clipArea);
  125. SDL_FillRect(destSurface, &toDisplay, guiPacked[COLOR_BKFILL]);
  126. // Fill
  127. int w = (long long)(width - PROGRESS_METER_BORDER * 2) * position / total;
  128. if (w) drawGradient(xOffset + PROGRESS_METER_BORDER, yOffset + PROGRESS_METER_BORDER,
  129. w, height - PROGRESS_METER_BORDER * 2,
  130. guiRGB[COLOR_SELECTION1], guiRGB[COLOR_SELECTION2],
  131. destSurface);
  132. // Text
  133. int percent = position * (long long)100 / total;
  134. string text = intToStr(percent);
  135. text += "%";
  136. int size = fontWidth(text, FONT_STANDARD);
  137. drawText(text, guiRGB[COLOR_TEXTBOX], xOffset + (width - size) / 2,
  138. yOffset + (height - fontHeight(FONT_STANDARD)) / 2, destSurface, FONT_STANDARD);
  139. }
  140. }
  141. }
  142. Window::WindowType ProgressMeter::windowType() const { start_func
  143. return WINDOW_CLIENT;
  144. }
  145. Window::WindowSort ProgressMeter::windowSort() const { start_func
  146. return WINDOWSORT_POPUP;
  147. }
  148. int ProgressMeter::wantsToBeDeleted() const { start_func
  149. return 1;
  150. }