def emacs_for_name(parent): new_k = parent.item_key_of_eventual_item x, w = x_and_width_for_name() change1 = parent.build_change_for_insert_WIP_row(new_k) change2 = parent.build_change_for_show_EMACS_field( new_k, x, w, 'nn', new_k) return _response(changes=(change1, change2))
def _move_up_down(self, adv, diff): ref_k = self._FC_curr_key focus_item_offset = _item_offset_via_item_key(ref_k) target_item_offset = focus_item_offset + diff num = self._current_number_of_items if num == target_item_offset: # #here6 reason = "can't move bottom item down" return self._response_via_info('wrong_way', reason) if -1 == target_item_offset: # #here6 reason = "can't move top item up" return self._response_via_info('wrong_way', reason) # OK please enjoy this one: the component that moved had focus before, # and (as an entirely obvious design choice) it should continue to # have focus after. Corollarily, the item it swapped places with didn't # have focus before and should continue not to have it after. Easy. # So as far as the components themselves are concerned, there's no # focusing to update. HOWEVER, the focus controller keeps track of # who has the focus by item key, and this key changed. # Also note we don't need to re-draw buttons until #here6 target_k = _item_key_via_item_offset(target_item_offset) cx = self._components ref_item = cx[ref_k] target_item = cx[target_k] cx[target_k] = ref_item cx[ref_k] = target_item self._focus_controller.accept_new_key_of_focused_component__(target_k) # emi = _emi_via_info_line('moved_item', f"moved item {adv}") nah return _response(changed_visually=(ref_k, target_k))
def emacs(parent): new_k = parent.item_key_of_eventual_item x = _hand_w + _lb_w change1 = parent.build_change_for_insert_WIP_row(new_k) change2 = parent.build_change_for_show_EMACS_field( new_k, x, slot_w, new_k) return _response(changes=(change1, change2))
def receive_new_value_from_modal_(self, mixed): if mixed is None: pass # it means they cancelled out. keep old value else: self._value_string = mixed # no validation for now lol self._state.move_to_state_via_transition_name('done_with_emacs_thing') # (probably not nec to tell the host we changed b.c it redraws anyway) return _response(changed_visually=(self._key, ))
def _apply_change_focus(self, k, butt_k, k_, cbpk): # Bounce the focus controller's own patch back to it so it notifies # one component of the loss and one of the gain ("cast" the direction # controller to a focus controller) no = self._DC.apply_change_focus(k, k_) assert no is None # Change the button area (probably) and notify BBC yield self._apply_change_buttons(butt_k, cbpk) cv = *(() if k is None else (k, )), k_ yield _response(changed_visually=cv)
def _DONE(self): # You're going to pop out. leave your label row as focused because # that's what had focus when you popped in. if 'label_row' == self._FC_curr_key: resp = _response(changes=()) # 😢 else: resp = self._focus_controller.change_focus_to('label_row') # You've got to leave your focus controller alive because you use # it to change focus at the apply stroke later (to change buttons) # self._focus_controller = None # #here8 change = 'input_controller', 'pop_receiver', self._key resp.changes = *resp.changes, change # meh return resp
def _apply_push_receiver(self, soa_k): """implement the ability for a child component to change the input mode so it receives focus and handles directional events itself. See section on SACs in [#608.L]. The details of this (like the interface of the directive, the interface of the below methods called) are all HIGHLY EXPERIMENTAL. it's just a rough prototyping sketch """ # Get what is probably the component with focus # (amazing we get this far (as the I.C) without needing these) # (this is the payback for the convenience of string-only directives) stack = self._controller_stack cx = stack[-1].DC.FOCUSABLE_COMPONENTS__ c = cx[soa_k] # Build and push the new frame kw = {k: v for k, v in c.CONTROLLER_FRAME__()} # Remove this one thing from it cbpk = kw.pop('component_button_page_key_once_has_focus') # Add this one thing to it kw['SOA_component_key'] = soa_k new_frame = _controller_frame(**kw) stack.append(new_frame) # Assume SAC already focuses its top child when it itself gets focus. # But now that we're pushing in to it we gotta change buttons # Gotta change the buttons. Assume SAC already had item with focus changes = (('input_controller', 'change_buttons', soa_k, cbpk), ) resp = _response(changes=changes) # We're like 99% sure we want to stale the buttons always because # that's practically the whole point of pushing in to a new mode is # getting new available actions. Otherwise, if not here, where? # Redraw the whole SAC (meh) and the buttons, assert resp.changed_visually is None # hack it. meh resp.changed_visually = (soa_k, 'buttons') return resp
def _bounceback_translate_area(self, stack): # Typically rendering happens by: responses flag those components that # need a redraw, then just before the host blocks for input, it asks # the root compound area for those components and asks those components # for their current rows, then we (somehow) determine screen offsets # for the rows and render them to screen. # But when it comes to an "emacs field", the component has almost no # interest in managing the rendering (or input) itself. It only wants # to be able to specify an X and a width and let the host do the rest. # Here we translate SAC-space coordinates to screen coords for that.. these = tuple(stack.pop() for _ in range(0, 7)) recip, typ, comp_path, h, w, y, x = these if 2 < len(self._controller_stack): xx("wow how ambitious. do you really want to do this?") hh = self._controller_stack[-2].harnesses_experimental ah = hh[comp_path[0]] # 😢 use_y, use_x = ah.translate_point__(y, x) change = recip, typ, comp_path, h, w, use_y, use_x, *reversed(stack) return _response(changes=(change, ))
def listener(*args): # A big hack to make code read more familiarly but BE CAREFUL emi = _emission(args) emis = (emi, ) return _response(emissions=emis)
def _response_for_quit(): line = 'Goodbye from ncurses yikes®' # #todo put app name here, or not emi = _emission(('info', 'expression', 'goodbye', lambda: (line, ))) changes = (('host_directive', 'quit'), ) return _response(emissions=(emi, ), changes=changes)
def _enter_modal(self): changes = (('host_directive', 'enter_emacs_modal', self._key), ) return _response(changes=changes)
def _toggle(self): self._is_checked = not self._is_checked return _response(changed_visually=(self._key, ))
def experiment_transition(_, tname, *item_k): change = 'input_controller', 'traverse_transition', tname, *item_k # noqa: E501 return _response(changes=(change,))
def _this_response(self): return _response(changed_visually=(self._key,))
def _response_via_info(self, cat, msg): emi = _emi_via_info_line(cat, msg) return _response(emissions=(emi,))
def emacs_for_value(parent, item_k): x, w = x_and_width_for_value() change = parent.build_change_for_show_EMACS_field( item_k, x, w, 'vv', item_k) return _response(changes=(change,))
def _response_for_quit(): line = 'Goodbye from ncurses yikes®' # #todo put app name here, or not emi = _emission(('info', 'expression', 'goodbye', lambda: (line, ))) changes = (('host_directive', 'quit'), ) return _response(emissions=(emi, ), changes=changes) def listener(*args): # A big hack to make code read more familiarly but BE CAREFUL emi = _emission(args) emis = (emi, ) return _response(emissions=emis) _no_change = _response() # == Local constants _arrow_keys = set('KEY_UP KEY_RIGHT KEY_DOWN KEY_LEFT'.split()) _enter = '\n' _lowercase_alpha = re.compile(r'[a-z]\Z') def xx(msg=None): raise RuntimeError(''.join(('cover me', *((': ', msg) if msg else ())))) # #born
def _ENTER(self): # Entering into an SOC, push a new controller (us) on to the stack change = 'input_controller', 'push_receiver', self._key return _response(changes=(change,))