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

外挂编程

开发平台:

Windows_Unix

  1. #########################################################################
  2. #  OpenKore - WxWidgets Interface
  3. #
  4. #  Copyright (c) 2005,2007 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. #  $Revision$
  17. #  $Id$
  18. #
  19. #########################################################################
  20. ##
  21. # MODULE DESCRIPTION: Notebook control which supports undocking of its children
  22. #
  23. # This is a special notebook control. It hides the tab when there's only one child.
  24. # All children in this notebook control will have a title bar, and can be detached
  25. # into a dialog.
  26. #
  27. # This control is designed to only contain one instance for each type of child
  28. # controls. For example, in OpenKore you can only have one Advanced Configuration
  29. # panel.
  30. package Interface::Wx::DockNotebook;
  31. use strict;
  32. use Wx ':everything';
  33. use Wx::Event qw(EVT_NOTEBOOK_PAGE_CHANGING EVT_TIMER);
  34. use base qw(Wx::Panel);
  35. use Interface::Wx::DockNotebook::Page;
  36. ##############################
  37. ### CATEGORY: Constructor
  38. ##############################
  39. ##
  40. # Interface::Wx::DockNotebook->new(parent, id)
  41. # parent: The parent window. Must not be undef.
  42. # id: The window identifier.
  43. # Returns: a new Interface::Wx::DockNotebook control.
  44. #
  45. # Creates a new Interface::Wx::DockNotebook control.
  46. # You can add pages by using $docknotebook->newPage()
  47. sub new {
  48. my ($class, $parent, $id) = @_;
  49. my $self = $class->SUPER::new($parent, $id);
  50. my $sizer = $self->{sizer} = new Wx::BoxSizer(wxVERTICAL);
  51. $self->{dialogs} = [];
  52. $self->SetSizer($sizer);
  53. EVT_NOTEBOOK_PAGE_CHANGING($self, $id, &onPageChanging);
  54. return $self;
  55. }
  56. ##############################
  57. ### CATEGORY: Methods
  58. ##############################
  59. ##
  60. # $docknotebook->newPage(show_buttons, title, [select = 1])
  61. # show_buttons: Whether this page should have detach/close buttons.
  62. # title: a title for this tab.
  63. # Returns: a Interface::Wx::DockNotebook::Page control.
  64. #
  65. # Adds a new page to the notebook.
  66. #
  67. # See also: Interface::Wx::DockNotebook::Page->set()
  68. #
  69. # Example:
  70. # my $page;
  71. #
  72. # $page = $docknotebook->newPage(1, "Tab 1");
  73. # $page->set(new Wx::Button($page, -1, "Click Me!"));
  74. #
  75. # $page = $docknotebook->newPage(1, "Tab 2");
  76. # $page->set(new Wx::Button($page, -1, "Hello World"));
  77. sub newPage {
  78. my ($self, $show_buttons, $title, $select) = @_;
  79. my $page;
  80. $select = 1 if (!defined $select);
  81. if (!$self->{page} && !$self->{notebook}) {
  82. # This is the first child
  83. $page = new Interface::Wx::DockNotebook::Page($self, $show_buttons, $title);
  84. $self->{sizer}->Add($page, 1, wxGROW);
  85. $self->{page} = $page;
  86. } else {
  87. # We have multiple children.
  88. if (!$self->{notebook}) {
  89. # Create a notebook if we haven't done so already
  90. $self->{notebook} = new Wx::Notebook($self, -1);
  91. $self->{sizer}->Add($self->{notebook}, 1, wxGROW);
  92. # Reparent the first page
  93. $self->{sizer}->Detach($self->{page});
  94. $self->{page}->Reparent($self->{notebook});
  95. $self->{notebook}->AddPage($self->{page}, $self->{page}{title});
  96. $self->Layout;
  97. }
  98. # Finally, add the new page
  99. $page = new Interface::Wx::DockNotebook::Page($self->{notebook}, $show_buttons, $title);
  100. $self->{notebook}->AddPage($page, $title, $select);
  101. delete $self->{page};
  102. }
  103. return $page;
  104. }
  105. ##
  106. # $docknotebook->closePage(page)
  107. # page: Either an Interface::Wx::DockNotebook::Page object, or the title of a page.
  108. #
  109. # Close a page. If the page has been detached to a dialog, then the dialog will be closed.
  110. sub closePage {
  111. my ($self, $page) = @_;
  112. my $notebook = $self->{notebook};
  113. if (!ref($page)) {
  114. $page = $self->hasPage($page);
  115. return if (!$page);
  116. if ($page->{dialog}) {
  117. $page->{dialog}->Close;
  118. return;
  119. }
  120. }
  121. if ($notebook) {
  122. my $n = $notebook->GetPageCount;
  123. for (my $i = 0; $i < $n; $i++) {
  124. if ($notebook->GetPage($i) == $page) {
  125. $notebook->DeletePage($i);
  126. last;
  127. }
  128. }
  129. if ($n == 2) {
  130. # The notebook only has 1 item left; we want to
  131. # reparent the page and then get rid of the notebook
  132. # I cannot reparent the page itself due to a bug in WxWidgets,
  133. # so create a new page and reparent the old page's child
  134. $page = $notebook->GetPage(0);
  135. my $page2 = new Interface::Wx::DockNotebook::Page($self, $page->{show_buttons}, $page->{title});
  136. $page->{child}->Reparent($page2);
  137. $page2->set($page->{child});
  138. $self->{sizer}->Add($page2, 1, wxGROW);
  139. $notebook->DeletePage(0);
  140. $self->{sizer}->Detach($notebook);
  141. $notebook->Destroy;
  142. delete $self->{notebook};
  143. $self->Layout;
  144. $self->{page} = $page2;
  145. }
  146. } else {
  147. $self->{sizer}->Detach($page);
  148. $page->Destroy;
  149. delete $self->{page};
  150. $self->Layout;
  151. }
  152. }
  153. ##
  154. # $docknotebook->hasPage(title)
  155. # Returns: the Interface::Wx::DockNotebook::Page object which has the same title, or undef or nothing found.
  156. #
  157. # Check whether the notebook contains a page with title $title.
  158. sub hasPage {
  159. my ($self, $title) = @_;
  160. my $notebook = $self->{notebook};
  161. foreach (@{$self->{dialogs}}) {
  162. next if (!$_);
  163. if ($_->{title} eq $title) {
  164. return $_;
  165. }
  166. }
  167. if (!$notebook) {
  168. if ($self->{page} && $self->{page}{title} eq $title) {
  169. return $self->{page};
  170. } else {
  171. return;
  172. }
  173. }
  174. my $n = $notebook->GetPageCount;
  175. for (my $i = 0; $i < $n; $i++) {
  176. if ($notebook->GetPage($i)->{title} eq $title) {
  177. return $notebook->GetPage($i);
  178. }
  179. }
  180. return;
  181. }
  182. ##
  183. # $docknotebook->hasPage(title)
  184. # Returns: 1 on success, 0 on failure.
  185. #
  186. # Make sure the page with title $title is visible. If the page has been
  187. # detached to a dialog, then that dialog will be raised.
  188. sub switchPage {
  189. my ($self, $title) = @_;
  190. my $notebook = $self->{notebook};
  191. foreach (@{$self->{dialogs}}) {
  192. next if (!$_);
  193. if ($_->{title} eq $title) {
  194. $_->{dialog}->Raise;
  195. return 1;
  196. }
  197. }
  198. if (!$notebook) {
  199. if ($self->{page} && $self->{page}{title} eq $title) {
  200. return 1;
  201. } else {
  202. return 0;
  203. }
  204. }
  205. my $n = $notebook->GetPageCount;
  206. for (my $i = 0; $i < $n; $i++) {
  207. if ($notebook->GetPage($i)->{title} eq $title) {
  208. $notebook->SetSelection($i);
  209. return 1;
  210. }
  211. }
  212. return 0;
  213. }
  214. sub nextPage {
  215. my ($self) = @_;
  216. return unless ($self->{notebook});
  217. my $i = $self->{notebook}->GetSelection;
  218. $self->{notebook}->SetSelection($i + 1) if ($i < $self->{notebook}->GetPageCount);
  219. }
  220. sub prevPage {
  221. my ($self) = @_;
  222. return unless ($self->{notebook});
  223. my $i = $self->{notebook}->GetSelection;
  224. $self->{notebook}->SetSelection($i - 1) if ($i > 0);
  225. }
  226. ####################
  227. # Private
  228. ####################
  229. sub onPageChanging {
  230. my ($self, $event) = @_;
  231. my $focus = Wx::Window::FindFocus;
  232. my $sub;
  233. if (!$focus) {
  234. my $page = $self->{notebook}->GetPage($event->GetSelection);
  235. $sub = sub {
  236. $page->{child}->SetFocus;
  237. } if ($page && $page->{child});
  238. } elsif ($focus->isa('Interface::Wx::Input')) {
  239. $sub = sub {
  240. my ($from, $to) = $focus->GetSelection;
  241. $focus->SetFocus;
  242. $focus->SetSelection($from, $to);
  243. };
  244. } else {
  245. $event->Skip;
  246. return;
  247. }
  248. if ($sub) {
  249. my $timer = new Wx::Timer($self, 1300);
  250. EVT_TIMER($self, 1300, $sub);
  251. $timer->Start(10, 1);
  252. }
  253. }
  254. 1;