comparison tools/editor/scripts/gui/dockarea.py @ 378:64738befdf3b

bringing in the changes from the build_system_rework branch in preparation for the 0.3.0 release. This commit will require the Jan2010 devkit. Clients will also need to be modified to the new way to import fife.
author vtchill@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 11 Jan 2010 23:34:52 +0000
parents
children 2d01d25222bd
comparison
equal deleted inserted replaced
377:fe6fb0e0ed23 378:64738befdf3b
1 # -*- coding: utf-8 -*-
2
3 # ####################################################################
4 # Copyright (C) 2005-2009 by the FIFE team
5 # http://www.fifengine.de
6 # This file is part of FIFE.
7 #
8 # FIFE is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
12 #
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # Lesser General Public License for more details.
17 #
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the
20 # Free Software Foundation, Inc.,
21 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 # ####################################################################
23
24 from fife.extensions import pychan
25 from fife.extensions.pychan import widgets
26 import scripts.editor
27 from fife import fife
28 from panel import Panel
29 from faketabwidget import FakeTabWidget
30 from resizablebase import ResizableBase
31
32 class DockArea(widgets.VBox, ResizableBase):
33 def __init__(self, side, resizable=True, *args, **kwargs):
34 widgets.VBox.__init__(self, margins=(0,0,0,0), *args, **kwargs)
35 ResizableBase.__init__(self, *args, **kwargs)
36
37 self.cursor_id = 0
38 self.cursor_type = 0
39
40 self.vexpand=0
41 self.hexpand=0
42
43 self.side = side
44 self.resizable_top = (side == "bottom")
45 self.resizable_left = (side == "right")
46 self.resizable_right = (side == "left")
47 self.resizable_bottom = (side == "top")
48
49 self.gui = None
50
51 self.buildGui()
52 self.tabwidgets = []
53 self.panels = []
54
55 def getDockLocation(self, x, y):
56 placeAfter = None
57 placeBefore = None
58 placeIn = None
59
60 if x >= 0 and y >= 0:
61 # See if widget was dropped on a tabwidget
62 for tabwidget in self.tabwidgets:
63 absX, absY = tabwidget.getAbsolutePos()
64
65 if absX <= x and absY <= y \
66 and absX+tabwidget.width >= x and absY+tabwidget.height >= y:
67 # Check if the user tried to place it in front, or after this widget
68 if self.side == "left" or self.side == "right":
69 if y < absY+10:
70 placeBefore = tabwidget
71 elif y > absY+tabwidget.height-10:
72 placeAfter = tabwidget
73 else:
74 if x < absX+10:
75 placeBefore = tabwidget
76 elif x > absX+tabwidget.width-10:
77 placeAfter = tabwidget
78 if placeAfter is None and placeBefore is None:
79 placeIn = tabwidget
80 break
81
82 return (placeIn, placeBefore, placeAfter)
83
84 def dockChild(self, child, x, y):
85 for panel in self.panels:
86 if panel[0] == child:
87 return
88
89 child.dockarea = self
90 child.setDocked(True)
91
92 placeIn, placeBefore, placeAfter = self.getDockLocation(x, y)
93
94 if placeIn is None:
95 tabwidget = FakeTabWidget(resizable=True)
96 tabwidget.hexpand=1
97 tabwidget.vexpand=1
98
99 if self.side == "left" or self.side == "right":
100 tabwidget.resizable_bottom = True
101 else:
102 tabwidget.resizable_right = True
103 self.tabwidgets.append(tabwidget)
104
105 if placeBefore:
106 self.gui.insertChildBefore(tabwidget, placeBefore)
107 elif placeAfter:
108 self.gui.insertChild(tabwidget, self.gui.children.index(placeAfter)+1)
109 else:
110 self.gui.addChild(tabwidget)
111 else:
112 tabwidget = placeIn
113
114 tab = tabwidget.addTab(child, child.title)
115 self.panels.append( (child, tabwidget) )
116
117 def undock(event):
118 if event.getButton() != 2: # Right click
119 return
120
121 self.undockChild(child)
122
123 tab[2].capture(undock, "mouseClicked")
124 self.adaptLayout()
125
126 def undockChild(self, child, childIsCaller=False):
127 tabwidget = None
128 for panel in self.panels:
129 if panel[0] == child:
130 tabwidget = panel[1]
131 self.panels.remove(panel)
132 break
133 else:
134 return
135
136 tabwidget.removeTab(child)
137 if childIsCaller is False:
138 child.setDocked(False)
139
140 if len(tabwidget.tabs) <= 0:
141 self.gui.removeChild(tabwidget)
142 self.tabwidgets.remove(tabwidget)
143
144 # This stops a guichan exception when a widget with modul focus gets focused.
145 # It is not pretty, but crashes aren't pretty either
146 tabwidget.__del__()
147 del tabwidget
148
149 self.adaptLayout()
150
151 def buildGui(self):
152 if self.gui:
153 self.removeChild(self.gui)
154
155 if self.side == "left" or self.side == "right":
156 self.gui = widgets.VBox()
157 else:
158 self.gui = widgets.HBox()
159
160 self.gui.vexpand = 1
161 self.gui.hexpand = 1
162
163 self.addChild(self.gui)
164
165 def mouseReleased(self, event):
166 if self._resize:
167 if self._rLeft or self._rRight:
168 # Resize children
169 for child in self.gui.findChildren(parent=self.gui):
170 child.min_size = (self.width, child.min_size[1])
171 child.max_size = (self.width, child.max_size[1])
172
173 if self._rTop or self._rBottom:
174 # Resize children
175 for child in self.gui.findChildren(parent=self.gui):
176 child.min_size = (child.min_size[0], self.height)
177 child.max_size = (child.max_size[0], self.height)
178
179 self.gui.max_size = (self.width, self.height)
180
181 ResizableBase.mouseReleased(self, event)
182 self.min_size = (0,0) # Override changes done in ResizableBase
183