Coverage for Popup.py: 0%
172 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-27 18:50 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-27 18:50 +0000
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3"""Popup.py
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
24########################################################################
26# to do
28# Standard Library modules
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")
35import ctypes
37try:
38 from AppKit import NSView, NSWindowAbove
39except ImportError:
40 NSView = None
42from PyQt5.QtGui import QCursor
43from PyQt5.QtCore import Qt
44from PyQt5.QtWidgets import QGridLayout, QLabel, QVBoxLayout, QWidget
46# FreePokerTools modules
47import Stats
49class Popup(QWidget):
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
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())
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()
86 def create(self):
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
97 def destroy_pop(self):
99 if self.parent_popup:
100 self.parent_popup.submenu_count -= 1
101 else:
102 self.win.popup_count -= 1
103 self.destroy()
105class default(Popup):
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()
116 self.lab = QLabel()
117 self.setLayout(QVBoxLayout())
118 self.layout().addWidget(self.lab)
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"
131 #trim final \n
132 tip_text = tip_text[:-1]
133 text = text[:-1]
135 self.lab.setText(text)
136 Stats.do_tip(self.lab, tip_text)
138class Submenu(Popup):
139#fixme refactor this class, too much repeat code
140 def create(self):
141 super(Submenu, self).create()
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()
150 number_of_items = len(self.pop.pu_stats)
151 if number_of_items < 1:
152 self.destroy_pop()
154 self.grid = QGridLayout()
155 self.grid.setContentsMargins(0, 0, 0, 0)
156 self.grid.setSpacing(0)
157 self.setLayout(self.grid)
159 grid_line = {}
160 row = 1
162 for stat,submenu_to_run in self.pop.pu_stats_submenu:
164 grid_line[row]={}
165 grid_line[row]['lab'] = QLabel()
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)
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
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)
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)
197 self.grid.addWidget(grid_line[row]['lab'], row-1, 0)
199 row += 1
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)
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
216 def create(self):
217 super(Multicol, self).create()
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()
226 number_of_items = len(self.pop.pu_stats)
227 if number_of_items < 1:
228 self.destroy_pop()
230 number_of_cols = old_div(number_of_items, 16)
231 if number_of_cols % 16:
232 number_of_cols += 1
234 number_per_col = old_div(number_of_items, float(number_of_cols))
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
241 self.grid = QGridLayout()
242 self.setLayout(self.grid)
243 self.grid.setHorizontalSpacing(5)
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] = "", ""
250 for stat in self.pop.pu_stats:
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"
261 row_index += 1
262 if row_index >= number_per_col:
263 col_index += 1
264 row_index = 0
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"
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))
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
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)
285 return popup_instance