Skip to content

Commit a91e0d6

Browse files
author
Zerline
committed
New version, but still the same.
1 parent b9720f1 commit a91e0d6

File tree

2 files changed

+83
-30
lines changed

2 files changed

+83
-30
lines changed

examples/FlippingDominos.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"metadata": {},
6767
"outputs": [],
6868
"source": [
69-
"w = FlippingDominosWidget(g)\n",
69+
"w = FlippingDominosWidget(g, css_classes=['b0', 'b1', 'b2', 'b3', 'b4'])\n",
7070
"w"
7171
]
7272
},

examples/dominos/flipping_dominos.py

Lines changed: 82 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
from sage_widget_adapters.graphs.graph_grid_view_adapter import GraphGridViewAdapter
66
from sage_combinat_widgets.grid_view_widget import GridViewWidget, ButtonCell, BlankButton, styled_button_cell
77
from ipywidgets import Layout
8-
from traitlets import dlink, HasTraits, Bool
8+
from traitlets import dlink, HasTraits, Bool, observe, All
99
from contextlib import contextmanager
10+
from sage_combinat_widgets.grid_view_editor import extract_coordinates
1011

1112
smallblyt = Layout(width='12px',height='12px', margin='0', padding='0')
1213

@@ -26,7 +27,7 @@ def set_cell(self, obj, pos, val, dirty={}):
2627
if dirty: # if i'm a neighbor, then flip and return a new obj ; else return an error
2728
# Consider the relevant matching(s)
2829
for p in dirty:
29-
if not dirty[p]: # check this position is pressed
30+
if not dirty[p]: # check this position was pressed
3031
continue
3132
d2 = obj.domino_for_position(p)
3233
if d2 == d1 or not d2 in d1.neighbors():
@@ -98,8 +99,8 @@ def _busy_updating(self):
9899
self.updating = False
99100

100101
def _update(self, change):
101-
if self.updating:
102-
return
102+
#if self.updating or self.target[0].donottrack:
103+
# return
103104
with self._busy_updating():
104105
if self.logic == 'and':
105106
if self.intermediate_value == False: # aucun bouton pressé avant
@@ -155,23 +156,25 @@ def __init__(self, parent, b1, b2):
155156
self.link = None
156157
self.direction = None
157158
self.orientation = None
158-
self.compute(None)
159+
self.compute()
160+
self.donottrack = False
159161

160162
def __repr__(self):
161163
if self.value:
162164
return repr(self.first) + ' -> ' + repr(self.second) + " PRESSED"
163165
return repr(self.first) + ' -> ' + repr(self.second)
164166

165-
def compute(self, css_classes=None):
167+
def compute(self, css_classes=['b0', 'b1', 'b2', 'b3', 'b4']):
166168
"""Compute buttons relative positions.
167169
Create double directional link from both buttons"""
168170
self.geometry.compute()
171+
#print(self.geometry.__dict__)
169172
if css_classes:
170173
for cl in css_classes:
171174
self.first.remove_class(cl)
172175
self.second.remove_class(cl)
173-
self.first.add_class(css_classes[self.geometry.index_for_display-1])
174-
self.second.add_class(css_classes[self.geometry.index_for_display-1])
176+
self.first.add_class(css_classes[self.geometry.index_for_display])
177+
self.second.add_class(css_classes[self.geometry.index_for_display])
175178
if self.geometry.orientation == 1:
176179
self.key = self.first.position
177180
else:
@@ -199,19 +202,19 @@ def is_pressed(self):
199202
"""Is the domino pressed?"""
200203
return self.value
201204

202-
def set_value(self, value):
203-
"""Set domino value
204-
As we have a directional link,
205-
the domino value will also be set.
206-
"""
207-
self.link.unlink()
208-
self.first.value = value
209-
self.second.value = value
210-
self.link = ddlink(((self.first, 'value'), (self.second, 'value')), (self, 'value'), logic='and', set_at_init=False) # Fresh ddlink
205+
# def set_value(self, value):
206+
# """Set domino value
207+
# As we have a directional link,
208+
# the domino value will also be set.
209+
# """
210+
# self.link.unlink()
211+
# self.first.value = value
212+
# self.second.value = value
213+
# self.link = ddlink(((self.first, 'value'), (self.second, 'value')), (self, 'value'), logic='and', set_at_init=False) # Fresh ddlink
211214

212215
def reset(self):
213216
"""Full domino reset"""
214-
self.set_value(False)
217+
#self.set_value(False)
215218
self.link.unlink()
216219

217220
def flip(self, other):
@@ -237,11 +240,12 @@ def cell_widget_class_index(pos):
237240
class FlippingDominosWidget(GridViewWidget):
238241
"""A widget with dominos"""
239242

240-
def __init__(self, g):
243+
def __init__(self, g, css_classes=['b0', 'b1', 'b2', 'b3', 'b4']):
241244
r"""
242245
Init a flipping dominos widget
243246
with flipping aztec diamond graph `g`
244247
"""
248+
self.css_classes = css_classes
245249
super(FlippingDominosWidget, self).__init__(g, adapter = FlippingDominosAdapter(),
246250
cell_layout = smallblyt,
247251
cell_widget_classes=[styled_button_cell(),
@@ -252,19 +256,11 @@ def __init__(self, g):
252256
],
253257
cell_widget_class_index=make_cell_widget_class_index(g),
254258
blank_widget_class = BlankButton)
255-
self.css_classes = ['b1', 'b2', 'b3', 'b4']
256-
257259
def draw(self):
258260
self.dominos = {}
259261
super(FlippingDominosWidget, self).draw()
260262
self.apply_matching(self.value.matching)
261263

262-
def update(self):
263-
self.apply_matching(self.value.matching)
264-
for k,d in self.dominos.items():
265-
d.compute(self.css_classes)
266-
d.set_value(False) # unpress buttons
267-
268264
def match(self, b1, b2):
269265
"""Match buttons b1 and b2, that is: create a domino"""
270266
try:
@@ -286,7 +282,64 @@ def apply_matching(self, matching):
286282
self.match(self.children[d.first[0]].children[d.first[1]],
287283
self.children[d.second[0]].children[d.second[1]])
288284

289-
def set_value(self, value):
290-
"""Need to call self.update() manually, as the change is not obvious to the observer!"""
285+
def update(self):
286+
self.apply_matching(self.value.matching)
287+
for k,d in self.dominos.items():
288+
d.compute(self.css_classes)
289+
#d.set_value(False) # unpress buttons
290+
291+
def domino_for_position(self, pos):
292+
geometry = self.value.domino_for_position(pos)
293+
for t in (geometry.first, geometry.second):
294+
if t in self.dominos:
295+
print("domino for position", t, ":", self.dominos[t].geometry, self.dominos[t].value)
296+
return self.dominos[t]
297+
298+
def not_tracking(self, value):
299+
self.donottrack = value
300+
for d in self.dominos.values():
301+
d.donottrack = value
302+
303+
@observe(All)
304+
def set_cell(self, change):
305+
if self.donottrack:
306+
return
307+
if change.name.startswith('cell_'):
308+
print("set_cell()", change.name, change.old, change.new)
309+
else:
310+
print("set_cell()", change.name)
311+
# Try to reset everything right now to avoid unwanted propagations
312+
domino = self.domino_for_position(extract_coordinates(change.name))
313+
# First, we want to make the pressed domino visible to the user
314+
self.not_tracking(True)
315+
domino.first.value = True
316+
domino.second.value = True
317+
# Any pressed neighbor?
318+
other = None
319+
if self.dirty:
320+
for pos in self.dirty:
321+
other = self.domino_for_position(pos)
322+
if other and not other.geometry in domino.geometry.neighbors():
323+
other = None
324+
continue # we don't have to reset everything, I guess(hope)
325+
if not other:
326+
self.dirty[domino.geometry.first] = True
327+
self.dirty[domino.geometry.second] = True
328+
self.not_tracking(False)
329+
return
330+
if domino.link:
331+
domino.link.unlink()
332+
if other.link:
333+
other.link.unlink()
334+
self.not_tracking(False)
335+
super(FlippingDominosWidget, self).set_cell(change)
336+
self.not_tracking(True)
337+
# And now, we want to reset everything before the flip
338+
domino.first.value = False
339+
domino.second.value = False
340+
other.first.value = False
341+
other.second.value = False
342+
# Now, recreate the 2 dominos and compute style
291343
self.reset_dirty()
292344
self.update()
345+
self.not_tracking(False)

0 commit comments

Comments
 (0)