Coverage for Popup.py: 0%

172 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-09-28 16:41 +0000

1#!/usr/bin/env python 

2# -*- coding: utf-8 -*- 

3"""Popup.py 

4 

5Popup windows for the HUD. 

6""" 

7from __future__ import division 

8# Copyright 2011-2012, Ray E. Barker 

9#  

10# This program is free software; you can redistribute it and/or modify 

11# it under the terms of the GNU General Public License as published by 

12# the Free Software Foundation; either version 3 of the License, or 

13# (at your option) any later version. 

14#  

15# This program is distributed in the hope that it will be useful, 

16# but WITHOUT ANY WARRANTY; without even the implied warranty of 

17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

18# GNU General Public License for more details. 

19#  

20# You should have received a copy of the GNU General Public License 

21# along with this program; if not, write to the Free Software 

22# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 

23 

24######################################################################## 

25 

26# to do 

27 

28# Standard Library modules 

29 

30from past.utils import old_div 

31import logging 

32# logging has been set up in fpdb.py or HUD_main.py, use their settings: 

33log = logging.getLogger("hud") 

34 

35import ctypes 

36 

37try: 

38 from AppKit import NSView, NSWindowAbove 

39except ImportError: 

40 NSView = None 

41 

42from PyQt5.QtGui import QCursor 

43from PyQt5.QtCore import Qt 

44from PyQt5.QtWidgets import QGridLayout, QLabel, QVBoxLayout, QWidget 

45 

46# FreePokerTools modules 

47import Stats 

48 

49class Popup(QWidget): 

50 

51 def __init__(self, seat = None, stat_dict = None, win = None, pop = None, hand_instance = None, config = None, parent_popup = None): 

52 super(Popup, self).__init__(parent_popup or win, Qt.Window | Qt.FramelessWindowHint | Qt.WindowDoesNotAcceptFocus) 

53 self.seat = seat 

54 self.stat_dict = stat_dict 

55 self.win = win 

56 self.pop = pop 

57 self.hand_instance = hand_instance 

58 self.config = config 

59 self.parent_popup = parent_popup #parent's instance only used if this popup is a child of another popup 

60 self.submenu_count = 0 #used to keep track of active submenus - only one at once allowed 

61 

62 self.create() 

63 self.show() 

64 #child popups are positioned at the mouse pointer and must be killed if 

65 # the parent is killed 

66 parent = parent_popup or win 

67 if config.os_family == 'Mac' and NSView is not None: 

68 selfwinid = self.effectiveWinId() 

69 selfcvp = ctypes.c_void_p(int(selfwinid)) 

70 selfview = NSView(c_void_p=selfcvp) 

71 parentwinid = parent.effectiveWinId() 

72 parentcvp = ctypes.c_void_p(int(parentwinid)) 

73 parentview = NSView(c_void_p=parentcvp) 

74 parentview.window().addChildWindow_ordered_(selfview.window(), NSWindowAbove) 

75 else: 

76 self.windowHandle().setTransientParent(self.parent().windowHandle()) 

77 parent.destroyed.connect(self.destroy) 

78 self.move(QCursor.pos()) 

79 

80# Every popup window needs one of these 

81 def mousePressEvent(self, event): 

82 """Handle button clicks on the popup window.""" 

83# Any button click gets rid of popup. 

84 self.destroy_pop() 

85 

86 def create(self): 

87 

88 #popup_count is used by Aux_hud to prevent multiple active popups per player 

89 #do not increment count if this popup is a child of another popup 

90 if self.parent_popup: 

91 self.parent_popup.submenu_count += 1 

92 else: 

93 self.win.popup_count += 1 

94 

95 

96 

97 def destroy_pop(self): 

98 

99 if self.parent_popup: 

100 self.parent_popup.submenu_count -= 1 

101 else: 

102 self.win.popup_count -= 1 

103 self.destroy() 

104 

105class default(Popup): 

106 

107 def create(self): 

108 super(default, self).create() 

109 player_id = None 

110 for id in list(self.stat_dict.keys()): 

111 if self.seat == self.stat_dict[id]['seat']: 

112 player_id = id 

113 if player_id is None: 

114 self.destroy_pop() 

115 

116 self.lab = QLabel() 

117 self.setLayout(QVBoxLayout()) 

118 self.layout().addWidget(self.lab) 

119 

120 text,tip_text = "","" 

121 for stat in self.pop.pu_stats: 

122 number = Stats.do_stat( 

123 self.stat_dict, player = int(player_id),stat = stat, hand_instance = self.hand_instance) 

124 if number: 

125 text += number[3] + "\n" 

126 tip_text += number[5] + " " + number[4] + "\n" 

127 else: 

128 text += "xxx" + "\n" 

129 tip_text += "xxx" + " " + "xxx" + "\n" 

130 

131 #trim final \n 

132 tip_text = tip_text[:-1] 

133 text = text[:-1] 

134 

135 self.lab.setText(text) 

136 Stats.do_tip(self.lab, tip_text) 

137 

138class Submenu(Popup): 

139#fixme refactor this class, too much repeat code 

140 def create(self): 

141 super(Submenu, self).create() 

142 

143 player_id = None 

144 for id in list(self.stat_dict.keys()): 

145 if self.seat == self.stat_dict[id]['seat']: 

146 player_id = id 

147 if player_id is None: 

148 self.destroy_pop() 

149 

150 number_of_items = len(self.pop.pu_stats) 

151 if number_of_items < 1: 

152 self.destroy_pop() 

153 

154 self.grid = QGridLayout() 

155 self.grid.setContentsMargins(0, 0, 0, 0) 

156 self.grid.setSpacing(0) 

157 self.setLayout(self.grid) 

158 

159 grid_line = {} 

160 row = 1 

161 

162 for stat,submenu_to_run in self.pop.pu_stats_submenu: 

163 

164 grid_line[row]={} 

165 grid_line[row]['lab'] = QLabel() 

166 

167 number = Stats.do_stat( 

168 self.stat_dict, player = int(player_id),stat = stat, hand_instance = self.hand_instance) 

169 if number: 

170 grid_line[row]['text'] = number[3] 

171 grid_line[row]['lab'].setText(number[3]) 

172 Stats.do_tip(grid_line[row]['lab'], number[5] + " " + number[4]) 

173 else: 

174 grid_line[row]['text'] = stat 

175 grid_line[row]['lab'].setText(stat) 

176 

177 if row == 1: 

178 #put an "x" close label onto the popup, invert bg/fg 

179 # the window can also be closed by clicking on any non-menu label 

180 # but this "x" is added incase the menu is entirely non-menu labels 

181 

182 xlab = QLabel("x") 

183 xlab.setStyleSheet("background:%s;color:%s;" % (self.win.aw.fgcolor, self.win.aw.bgcolor)) 

184 grid_line[row]['x'] = xlab 

185 self.grid.addWidget(grid_line[row]['x'], row-1, 2) 

186 

187 if submenu_to_run: 

188 lab = QLabel(">") 

189 grid_line[row]['arrow_object'] = lab 

190 lab.submenu = submenu_to_run 

191 grid_line[row]['lab'].submenu = submenu_to_run 

192 if row == 1: 

193 self.grid.addWidget(grid_line[row]['arrow_object'], row-1, 1) 

194 else: 

195 self.grid.addWidget(grid_line[row]['arrow_object'], row-1, 1, 1, 2) 

196 

197 self.grid.addWidget(grid_line[row]['lab'], row-1, 0) 

198 

199 row += 1 

200 

201 def mousePressEvent(self, event): 

202 widget = self.childAt(event.pos()) 

203 submenu = "_destroy" 

204 if hasattr(widget, 'submenu'): 

205 submenu = widget.submenu 

206 if submenu == "_destroy": 

207 self.destroy_pop() 

208 return 

209 if self.submenu_count < 1: # only 1 popup allowed to be open at this level 

210 popup_factory(self.seat,self.stat_dict, self.win, self.config.popup_windows[submenu], self.hand_instance, self.config, self) 

211 

212class Multicol(Popup): 

213#like a default, but will flow into columns of 16 items 

214#use "blank" items if the default flowing affects readability 

215 

216 def create(self): 

217 super(Multicol, self).create() 

218 

219 player_id = None 

220 for id in list(self.stat_dict.keys()): 

221 if self.seat == self.stat_dict[id]['seat']: 

222 player_id = id 

223 if player_id is None: 

224 self.destroy_pop() 

225 

226 number_of_items = len(self.pop.pu_stats) 

227 if number_of_items < 1: 

228 self.destroy_pop() 

229 

230 number_of_cols = old_div(number_of_items, 16) 

231 if number_of_cols % 16: 

232 number_of_cols += 1 

233 

234 number_per_col = old_div(number_of_items, float(number_of_cols)) 

235 

236 #if number_per_col != round((number_of_items / float(number_of_cols)),0): 

237 # number_per_col += 1 

238 #number_per_col = int(number_per_col) 

239 number_per_col = 16 

240 

241 self.grid = QGridLayout() 

242 self.setLayout(self.grid) 

243 self.grid.setHorizontalSpacing(5) 

244 

245 col_index,row_index = 0,0 

246 text, tip_text = {},{} 

247 for i in range(number_of_cols): 

248 text[i], tip_text[i] = "", "" 

249 

250 for stat in self.pop.pu_stats: 

251 

252 number = Stats.do_stat( 

253 self.stat_dict, player = int(player_id),stat = stat, hand_instance = self.hand_instance) 

254 if number: 

255 text[col_index] += number[3] + "\n" 

256 tip_text[col_index] += number[5] + " " + number[4] + "\n" 

257 else: 

258 text[col_index] += stat + "\n" 

259 tip_text[col_index] += stat + "\n" 

260 

261 row_index += 1 

262 if row_index >= number_per_col: 

263 col_index += 1 

264 row_index = 0 

265 

266 if row_index > 0: 

267 for i in range(number_per_col - row_index): 

268 # pad final column with blank lines 

269 text[col_index] += "\n" 

270 

271 for i in text: 

272 contentlab = QLabel(text[i][:-1]) 

273 Stats.do_tip(contentlab, tip_text[i][:-1]) 

274 self.grid.addWidget(contentlab, 0, int(i)) 

275 

276 

277def popup_factory(seat = None, stat_dict = None, win = None, pop = None, hand_instance = None, config = None, parent_popup = None): 

278 # a factory function to discover the base type of the popup 

279 # and to return a class instance of the correct popup 

280 # getattr looksup the class reference in this module 

281 

282 class_to_return = getattr(__import__(__name__), pop.pu_class) 

283 popup_instance = class_to_return(seat, stat_dict, win, pop, hand_instance, config, parent_popup) 

284 

285 return popup_instance