3737)
3838from ..display import DEFAULT_PADDING , MINIMAL_PADDING , FONT_HEIGHT , FONT_WIDTH
3939
40- FIXED_KEYS = 3 # 'More' key only appears when there are multiple keysets
40+ FIXED_KEYS = 3 # 'More' key only appears when there are multiple keysets.
41+
42+ KEYPAD_OFFSET = DEFAULT_PADDING + FONT_HEIGHT * 3
43+
44+
45+ class KeypadLayout :
46+ """Groups layout-related attributes for Keypad."""
47+
48+ def __init__ (self , ctx , max_keys_count ):
49+ self .width = math .floor (math .sqrt (max_keys_count ))
50+ self .height = math .ceil (max_keys_count / self .width )
51+ self .max_index = self .width * self .height
52+
53+ key_h_spacing = ctx .display .width () - DEFAULT_PADDING
54+ key_h_spacing //= self .width
55+ key_v_spacing = (
56+ ctx .display .height () - DEFAULT_PADDING - (DEFAULT_PADDING + FONT_HEIGHT * 3 )
57+ )
58+ key_v_spacing //= self .height
59+ self .key_h_spacing , self .key_v_spacing = key_h_spacing , key_v_spacing
60+
61+ self .y_keypad_map = [
62+ y * key_v_spacing + (DEFAULT_PADDING + FONT_HEIGHT * 3 )
63+ for y in range (self .height + 1 )
64+ ]
65+ self .x_keypad_map = [
66+ x * key_h_spacing + MINIMAL_PADDING for x in range (self .width + 1 )
67+ ]
68+ if ctx .input .touch is not None :
69+ ctx .input .touch .y_regions = self .y_keypad_map
70+ ctx .input .touch .x_regions = self .x_keypad_map
4171
4272
4373class Keypad :
44- """Controls keypad creation and management"""
74+ """Controls keypad creation and management. """
4575
4676 def __init__ (self , ctx , keysets , possible_keys_fn = None ):
4777 self .ctx = ctx
4878 self .keysets = keysets
4979 self .keyset_index = 0
50- self . max_keys_count = max ([ len ( keyset ) for keyset in keysets ])
51- self . max_keys_count += FIXED_KEYS + ( 1 if len (keysets ) > 1 else 0 )
52- self . key_h_spacing , self . key_v_spacing = self . map_keys_array (
53- self . width , self . height
80+ max_keys_count = (
81+ max ( len (keyset ) for keyset in keysets )
82+ + FIXED_KEYS
83+ + ( 1 if len ( keysets ) > 1 else 0 )
5484 )
85+ self .layout = KeypadLayout (ctx , max_keys_count )
5586 self .cur_key_index = 0
5687 self .moving_forward = True
5788 self .possible_keys_fn = possible_keys_fn
@@ -89,62 +120,17 @@ def go_index(self):
89120 """Returns the index of the "Go" key"""
90121 return self .esc_index + 1
91122
92- @property
93- def width (self ):
94- """Returns the needed width for the current keyset"""
95- return math .floor (math .sqrt (self .max_keys_count ))
96-
97- @property
98- def height (self ):
99- """Returns the needed height for the current keyset"""
100- return math .ceil ((self .max_keys_count ) / self .width )
101-
102- @property
103- def max_index (self ):
104- """Returns last possible key index"""
105- return self .width * self .height
106-
107123 @property
108124 def empty_keys (self ):
109125 """Returns dummy keys space needed to always position fixed keys at bottom right"""
110- return self .max_index - self .total_keys
126+ return self .layout . max_index - self .total_keys
111127
112128 def reset (self ):
113129 """Reset parameters when switching a multi-keypad"""
114- self .key_h_spacing , self .key_v_spacing = self .map_keys_array (
115- self .width , self .height
116- )
117130 self .cur_key_index = 0
118131 self .possible_keys = self .keys
119132 self .moving_forward = True
120133
121- def map_keys_array (self , width , height ):
122- """Maps an array of regions for keys to be placed in
123- Returns horizontal and vertical spacing of keys
124- """
125- self .y_keypad_map = []
126- self .x_keypad_map = []
127- key_h_spacing = self .ctx .display .width () - DEFAULT_PADDING
128- key_h_spacing //= width
129- key_v_spacing = (
130- self .ctx .display .height () - DEFAULT_PADDING - self .keypad_offset ()
131- )
132- key_v_spacing //= height
133- for y in range (height + 1 ):
134- region = y * key_v_spacing + self .keypad_offset ()
135- self .y_keypad_map .append (region )
136- for x in range (width + 1 ):
137- region = x * key_h_spacing + MINIMAL_PADDING
138- self .x_keypad_map .append (region )
139- if self .ctx .input .touch is not None :
140- self .ctx .input .touch .y_regions = self .y_keypad_map
141- self .ctx .input .touch .x_regions = self .x_keypad_map
142- return key_h_spacing , key_v_spacing
143-
144- def keypad_offset (self ):
145- """Returns keypad start position"""
146- return DEFAULT_PADDING + FONT_HEIGHT * 3
147-
148134 def compute_possible_keys (self , buffer ):
149135 """Computes the possible keys for the current keypad"""
150136 if self .possible_keys_fn is not None :
@@ -153,9 +139,9 @@ def compute_possible_keys(self, buffer):
153139 def draw_keys (self ):
154140 """Draws keypad on the screen"""
155141 key_index = 0
156- for y in self .y_keypad_map [:- 1 ]:
157- offset_y = y + (self .key_v_spacing - FONT_HEIGHT ) // 2
158- for x in self .x_keypad_map [:- 1 ]:
142+ for y in self .layout . y_keypad_map [:- 1 ]:
143+ offset_y = y + (self .layout . key_v_spacing - FONT_HEIGHT ) // 2
144+ for x in self .layout . x_keypad_map [:- 1 ]:
159145 key = None
160146 custom_color = None
161147 if key_index < len (self .keys ):
@@ -172,10 +158,12 @@ def draw_keys(self):
172158 elif key_index == self .more_index and len (self .keysets ) > 1 :
173159 key = "ABC"
174160 custom_color = theme .toggle_color
161+
175162 if key is not None :
176163 offset_x = x
177- key_offset_x = (self .key_h_spacing - lcd .string_width_px (key )) // 2
178- key_offset_x += offset_x
164+ key_offset_x = (
165+ self .layout .key_h_spacing - lcd .string_width_px (key )
166+ ) // 2 + offset_x
179167 if (
180168 key_index < len (self .keys )
181169 and self .keys [key_index ] not in self .possible_keys
@@ -189,8 +177,8 @@ def draw_keys(self):
189177 self .ctx .display .outline (
190178 offset_x + 1 ,
191179 y + 1 ,
192- self .key_h_spacing - 2 ,
193- self .key_v_spacing - 2 ,
180+ self .layout . key_h_spacing - 2 ,
181+ self .layout . key_v_spacing - 2 ,
194182 theme .frame_color ,
195183 )
196184 if custom_color :
@@ -207,15 +195,15 @@ def draw_keys(self):
207195 self .ctx .display .outline (
208196 offset_x + 1 ,
209197 y + 1 ,
210- self .key_h_spacing - 2 ,
211- self .key_v_spacing - 2 ,
198+ self .layout . key_h_spacing - 2 ,
199+ self .layout . key_v_spacing - 2 ,
212200 )
213201 else :
214202 self .ctx .display .outline (
215203 offset_x - 2 ,
216204 y ,
217- self .key_h_spacing + 1 ,
218- self .key_v_spacing - 1 ,
205+ self .layout . key_h_spacing + 1 ,
206+ self .layout . key_v_spacing - 1 ,
219207 )
220208 key_index += 1
221209
@@ -233,7 +221,7 @@ def draw_keyset_index(self):
233221 color = theme .fg_color if i == self .keyset_index else theme .frame_color
234222 self .ctx .display .fill_rectangle (
235223 x_offset + (bar_length + bar_padding ) * i ,
236- self .y_keypad_map [- 1 ] + 2 ,
224+ self .layout . y_keypad_map [- 1 ] + 2 ,
237225 bar_length ,
238226 bar_height ,
239227 color ,
@@ -246,15 +234,15 @@ def get_valid_index(self):
246234 and self .keys [self .cur_key_index ] not in self .possible_keys
247235 ):
248236 if self .moving_forward :
249- self .cur_key_index = (self .cur_key_index + 1 ) % self .max_index
237+ self .cur_key_index = (self .cur_key_index + 1 ) % self .layout . max_index
250238 # Jump over empty keys
251239 if 0 <= (self .cur_key_index - len (self .keys )) < self .empty_keys :
252240 self .cur_key_index += self .empty_keys
253241 else :
254242 if self .cur_key_index :
255243 self .cur_key_index -= 1
256244 else :
257- self .cur_key_index = self .max_index - 1
245+ self .cur_key_index = self .layout . max_index - 1
258246 return self .cur_key_index
259247
260248 def touch_to_physical (self ):
@@ -264,7 +252,7 @@ def touch_to_physical(self):
264252 if self .cur_key_index < len (self .keys ):
265253 if self .keys [self .cur_key_index ] in self .possible_keys :
266254 actual_button = BUTTON_ENTER
267- elif self .cur_key_index < self .max_index :
255+ elif self .cur_key_index < self .layout . max_index :
268256 actual_button = BUTTON_ENTER
269257 else :
270258 self .cur_key_index = 0
@@ -298,16 +286,16 @@ def navigate(self, btn):
298286 def _clean_keypad_area (self ):
299287 self .ctx .display .fill_rectangle (
300288 0 ,
301- self . keypad_offset () ,
289+ KEYPAD_OFFSET ,
302290 self .ctx .display .width (),
303- self .ctx .display .height () - self . keypad_offset () ,
291+ self .ctx .display .height () - KEYPAD_OFFSET ,
304292 theme .bg_color ,
305293 )
306294
307295 def _next_key (self ):
308296 """Increments cursor when page button is pressed"""
309297 self .moving_forward = True
310- self .cur_key_index = (self .cur_key_index + 1 ) % self .max_index
298+ self .cur_key_index = (self .cur_key_index + 1 ) % self .layout . max_index
311299 if self .cur_key_index == len (self .keys ):
312300 self .cur_key_index += self .empty_keys
313301
@@ -317,7 +305,7 @@ def _previous_key(self):
317305 if self .cur_key_index == len (self .keys ) + self .empty_keys :
318306 self .cur_key_index = len (self .keys ) - 1
319307 else :
320- self .cur_key_index = (self .cur_key_index - 1 ) % self .max_index
308+ self .cur_key_index = (self .cur_key_index - 1 ) % self .layout . max_index
321309
322310 def next_keyset (self ):
323311 """Change keys for the next keyset"""
0 commit comments