Interface.pm
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:7k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. #########################################################################
  2. #  OpenKore - User interface system
  3. #
  4. #  Copyright (c) 2004 OpenKore development team 
  5. #
  6. #  This program is free software; you can redistribute it and/or modify
  7. #  it under the terms of the GNU General Public License as published by
  8. #  the Free Software Foundation; either version 2 of the License, or
  9. #  (at your option) any later version.
  10. #
  11. #  This program is distributed in the hope that it will be useful,
  12. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. #  GNU General Public License for more details.
  15. #########################################################################
  16. ##
  17. # MODULE DESCRIPTION: User interface system.
  18. #
  19. # In OpenKore, the user interface code is seperated from the core code.
  20. # Each user interface is implemented in a class. The Interface class is an
  21. # abstract base class for all OpenKore user interface classes.
  22. package Interface;
  23. use strict;
  24. use warnings;
  25. no warnings 'redefine';
  26. use Time::HiRes qw(usleep);
  27. use encoding 'utf8';
  28. use Modules 'register';
  29. use Globals qw(%config $quit);
  30. use Translation qw(T TF);
  31. use Utils::Exceptions;
  32. ##
  33. # Interface->loadInterface(String name)
  34. # name: The class name of the interface to load, excluding the 'Interface::' prefix.
  35. # Returns: The newly created interface object.
  36. #
  37. # Create a new interface of the specified class.
  38. #
  39. # Throws ModuleLoadException if the interface's Perl module cannot be loaded.
  40. # Throws ClassCreateException if the interface class cannot be created.
  41. sub loadInterface {
  42. my ($self, $name) = @_;
  43. my $module = "Interface::$name";
  44. eval "use $module;";
  45. if ($@) {
  46. ModuleLoadException->throw(error => "Cannot load interface $module. Error:n$@",
  47. module => $module);
  48. }
  49. my $constructor = UNIVERSAL::can($module, 'new');
  50. if (!$constructor) {
  51. ClassCreateException->throw(error => "Class $module has no constructor.", class => $module);
  52. }
  53. my $interface = $constructor->($module);
  54. Modules::register($module);
  55. return $interface;
  56. }
  57. ##
  58. # void $interface->mainLoop()
  59. #
  60. # Enter the interface's main loop.
  61. sub mainLoop {
  62. my $self = shift;
  63. while (!$quit) {
  64. usleep($config{sleepTime} || 10000);
  65. $self->iterate();
  66. main::mainLoop();
  67. }
  68. }
  69. ##
  70. # void $interface->iterate()
  71. #
  72. # Process messages in the user interface message queue.
  73. # In other words: make sure the user interface updates itself.
  74. # (redraw controls when necessary, etc.)
  75. sub iterate {
  76. }
  77. ##
  78. # String $interface->getInput(float timeout)
  79. # timeout: Number of second to wait until keyboard data is available. 
  80. #          Negative numbers will wait forever, 0 will not wait at all.
  81. # Returns: The keyboard data (excluding newline), or undef if there's no
  82. #          keyboard data available.
  83. #
  84. # Reads keyboard data.
  85. ##
  86. # String $interface->query(String message, options...)
  87. # message: A message to display when asking for input.
  88. # Returns: The user input, or undef if the user cancelled.
  89. # Requires: defined($message)
  90. #
  91. # Ask the user to enter a one-line input text.
  92. # The following options are allowed:
  93. # `l
  94. # - cancelable - Whether the user is allowed to enter nothing. If this is set to true,
  95. #       then the user will be asked the same thing over and over until he
  96. #       replies with a non-empty input. The default is true.
  97. # - title - A title to display in the query dialog. The default is "Query".
  98. # - isPassword - Whether this query is a password query. The default is false.
  99. # `l`
  100. sub query {
  101. my $self = shift;
  102. my $message = shift;
  103. my %args = @_;
  104. $args{title} = "Query" if (!defined $args{title});
  105. $args{cancelable} = 1 if (!exists $args{cancelable});
  106. my $title = "------------ $args{title} ------------";
  107. my $footer = '-' x length($title);
  108. $message =~ s/n+$//s;
  109. $message = "$titlen$messagen$footern";
  110. while (1) {
  111. $self->writeOutput("message", $message, "input");
  112. $self->writeOutput("message", T("Enter your answer: "), "input");
  113. my $mode = $args{isPassword} ? -9 : -1;
  114. my $result = $self->getInput($mode);
  115. if (!defined($result) || $result eq '') {
  116. if ($args{cancelable}) {
  117. return undef;
  118. }
  119. } else {
  120. return $result;
  121. }
  122. }
  123. }
  124. ##
  125. # int $interface->showMenu(String message, Array<String>* choices, options...)
  126. # message: The message to display while asking the user to make a choice.
  127. # choices: The possible choices.
  128. # Returns: The index of the chosen item, or -1 if the user cancelled.
  129. # Requires:
  130. #     defined($message)
  131. #     defined($choices)
  132. #     for all $k in @{$choices}: defined($k)
  133. # Ensures: -1 <= result < @{$choices}
  134. #
  135. # Ask the user to choose an item from a menu of choices.
  136. #
  137. # The following options are allowed:
  138. # `l
  139. # - title - The title to display when presenting the choices to the user.
  140. #           The default is 'Menu'.
  141. # - cancelable - Whether the user is allowed to not choose.
  142. #                The default is true.
  143. # `l`
  144. sub showMenu {
  145. my $self = shift;
  146. my $message = shift;
  147. my $choices = shift;
  148. my %args = @_;
  149. $args{title} = "Menu" if (!defined $args{title});
  150. $args{cancelable} = 1 if (!exists $args{cancelable});
  151. # Create a nicely formatted choice list.
  152. my $maxNumberLength = length(@{$choices} + 1);
  153. my $format = "%-" . $maxNumberLength . "s   %-sn";
  154. my $output = sprintf($format, "#", T("Choice"));
  155. my $i = 0;
  156. foreach my $item (@{$choices}) {
  157. $output .= sprintf($format, $i, $item);
  158. $i++;
  159. }
  160. $message = "${output}------------------------n$message";
  161. while (1) {
  162. my $choice = $self->query($message,
  163. cancelable => $args{cancelable},
  164. title => $args{title});
  165. if (!defined($choice)) {
  166. return -1;
  167. } elsif ($choice !~ /^d+$/ || $choice < 0 || $choice >= @{$choices}) {
  168. $self->writeOutput("error", TF("'%s' is not a valid choice number.n", $choice), "default");
  169. } else {
  170. return $choice;
  171. }
  172. }
  173. }
  174. ##
  175. # void $interface->writeOutput(String type, String message, String domain)
  176. # Requires: defined($type) && defined($message) && defined($domain)
  177. # Writes a message to the interface's console.
  178. # This method should not be used directly, use Log::message() instead.
  179. sub writeOutput {
  180. # Do nothing; this is a dummy parent class
  181. }
  182. ##
  183. # void $interface->beep()
  184. # Emit a beep on the available audio device.
  185. sub beep {
  186. # Do nothing; this is a dummy parent class
  187. }
  188. ##
  189. # String $interface->title([String title])
  190. #
  191. # If $title is given, set the interface's window's title to $title.
  192. # If not given, returns the current window title.
  193. sub title {
  194. # Do nothing; this is a dummy parent class
  195. }
  196. ##
  197. # void $interface->errorDialog(String message, [boolean fatal = true])
  198. # message: The error message to display.
  199. # fatal: Indicate that this is a fatal error (meaning that the application will
  200. #        exit after this dialog is closed). If set, the console interfaces
  201. #        will warn the user that the app is about to exit.
  202. # Requires: defined($message)
  203. #
  204. # Display an error dialog. This function blocks until the user has closed the
  205. # dialog.
  206. #
  207. # Consider using Log::error() if your message is not a fatal error, because
  208. # Log::error() does not require any user interaction.
  209. sub errorDialog {
  210. my $self = shift;
  211. my $message = shift;
  212. my $fatal = shift;
  213. $fatal = 1 unless defined $fatal;
  214. $self->writeOutput("error", "$messagen", "error");
  215. if ($fatal) {
  216. $self->writeOutput("message", Translation::T("Press ENTER to exit this program.n"), "console")
  217. } else {
  218. $self->writeOutput("message", Translation::T("Press ENTER to continue...n"), "console")
  219. }
  220. $self->getInput(-1);
  221. }
  222. 1;