Package horizons :: Package gui :: Package tabs :: Module tabwidget
[hide private]
[frames] | no frames]

Source Code for Module horizons.gui.tabs.tabwidget

  1  # ################################################### 
  2  # Copyright (C) 2008-2017 The Unknown Horizons Team 
  3  # team@unknown-horizons.org 
  4  # This file is part of Unknown Horizons. 
  5  # 
  6  # Unknown Horizons 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  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the 
 18  # Free Software Foundation, Inc., 
 19  # 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
 20  # ################################################### 
 21   
 22  import logging 
 23  import traceback 
 24  import weakref 
 25   
 26  from fife.extensions.pychan.widgets import Container, Icon 
 27   
 28  from horizons.gui.util import load_uh_widget 
 29  from horizons.gui.widgets.imagebutton import ImageButton 
 30  from horizons.util.changelistener import metaChangeListenerDecorator 
 31  from horizons.util.python.callback import Callback 
32 33 34 @metaChangeListenerDecorator('remove') 35 -class TabWidget:
36 """The TabWidget class handles widgets which consist of many 37 different tabs(subpanels, switchable via buttons(TabButtons). 38 """ 39 log = logging.getLogger("gui.tabs.tabwidget") 40
41 - def __init__(self, ingame_gui, tabs=None, name=None, active_tab=None):
42 """ 43 @param ingame_gui: IngameGui instance 44 @param tabs: tab instances to show 45 @param name: optional name for the tabwidget 46 @param active_tab: int id of tab, 0 <= active_tab < len(tabs) 47 """ 48 super().__init__() #TODO: check if this call is needed 49 self.name = name 50 self.ingame_gui = ingame_gui 51 self._tabs = [] if not tabs else tabs 52 self.current_tab = self._tabs[0] # Start with the first tab 53 self.current_tab.ensure_loaded() # loading current_tab widget 54 self.widget = load_uh_widget("tab_base.xml") 55 self.widget.position_technique = 'right-239:top+209' 56 self.content = self.widget.findChild(name='content') 57 self._init_tab_buttons() 58 # select a tab to show (first one is default) 59 if active_tab is not None: 60 self.show_tab(active_tab)
61
62 - def _init_tab_buttons(self):
63 """Add enough tabbuttons for all widgets.""" 64 def on_tab_removal(tabwidget): 65 # called when a tab is being removed (via weakref since tabs shouldn't have references to the parent tabwidget) 66 # If one tab is removed, the whole tabwidget will die.. 67 # This is easy usually the desired behavior. 68 if tabwidget(): 69 tabwidget().on_remove()
70 71 # Load buttons 72 for index, tab in enumerate(self._tabs): 73 # don't add a reference to the 74 tab.add_remove_listener(Callback(on_tab_removal, weakref.ref(self))) 75 container = Container(name="container_{}".format(index)) 76 background = Icon(name="bg_{}".format(index)) 77 button = ImageButton(name=str(index), size=(50, 50)) 78 if self.current_tab is tab: 79 background.image = tab.button_background_image_active 80 button.path = tab.path_active 81 else: 82 background.image = tab.button_background_image 83 button.path = tab.path 84 button.capture(Callback(self.show_tab, index)) 85 if hasattr(tab, 'helptext') and tab.helptext: 86 button.helptext = tab.helptext 87 container.size = (50, 52) 88 container.addChild(background) 89 container.addChild(button) 90 self.content.addChild(container) 91 self.widget.size = (54, 55 * len(self._tabs)) 92 self.widget.adaptLayout() 93 94 self._apply_layout_hack()
95
96 - def show_tab(self, number):
97 """Used as callback function for the TabButtons. 98 @param number: tab number that is to be shown. 99 """ 100 if number >= len(self._tabs): 101 # this usually indicates a non-critical error, therefore we can handle it without crashing 102 traceback.print_stack() 103 self.log.warning("Invalid tab number %s, available tabs: %s", number, self._tabs) 104 return 105 if self.current_tab.is_visible(): 106 self.current_tab.hide() 107 new_tab = self._tabs[number] 108 old_bg = self.content.findChild(name="bg_{}".format(self._tabs.index(self.current_tab))) 109 old_bg.image = self.current_tab.button_background_image 110 name = str(self._tabs.index(self.current_tab)) 111 old_button = self.content.findChild(name=name) 112 old_button.path = self.current_tab.path 113 114 new_bg = self.content.findChild(name="bg_{}".format(number)) 115 new_bg.image = self.current_tab.button_background_image_active 116 new_button = self.content.findChild(name=str(number)) 117 new_button.path = new_tab.path_active 118 self.current_tab = new_tab 119 # important to display the tabs correctly in front 120 self.widget.hide() 121 self.show() 122 123 self._apply_layout_hack()
124
125 - def _apply_layout_hack(self):
126 # pychan layouting depends on time, it's usually in a better mood later. 127 # this introduces some flickering, but fixes #916 128 from horizons.extscheduler import ExtScheduler 129 def do_apply_hack(): 130 # just query widget when executing, since if lazy loading is used, the widget 131 # does not exist yet in the outer function 132 self.current_tab.widget.adaptLayout()
133 ExtScheduler().add_new_object(do_apply_hack, self, run_in=0) 134
135 - def _draw_widget(self):
136 """Draws the widget, but does not show it automatically""" 137 self.current_tab.position = (self.widget.position[0] + self.widget.size[0] - 11, 138 self.widget.position[1] - 52) 139 self.current_tab.refresh()
140
141 - def show(self):
142 """Show the current widget""" 143 # show before drawing so that position_technique properly sets 144 # button positions (which we want to draw our tabs relative to) 145 self.widget.show() 146 self._draw_widget() 147 self.current_tab.show() 148 self.ingame_gui.minimap_to_front()
149
150 - def hide(self, caller=None):
151 """Hides current tab and this widget""" 152 self.current_tab.hide() 153 self.widget.hide()
154