def visible_children(asker, object): expanded = convert.check_hard(asker, is_expanded(), object) object = asker.refresh(object) if not expanded: return asker.reply(answer=T.from_list([])) else: children = asker.ask(fields.get_field(all_children(), object)).firm_answer return asker.reply(answer=children)
def add_pointer_to_bottom(asker, object): visible_children = asker.ask(fields.get_field(visible_children()), object).firm_answer if convert.check_hard(asker, lists.is_empty(), visible_children): return asker.reply(answer=updates.update(is_pointer_now(), object)) else: result = updates.update(has_pointer_now(), object) result = updates.update( updates.apply_to( fields.compose(visible_children(), lists.last_element()), add_pointer_to_bottom() ), result ) return asker.reply(answer=result)
def outline_to_lines(asker, root): debug() result = asker.ask(fields.get_field(cached_lines(), root)).answer if result is not None: return asker.reply(answer=result) base_headline = asker.ask(fields.get_field(headline(), root)).firm_answer root = asker.refresh(root) prefix = "* " if convert.check_hard(asker, is_pointer(), root) else " " full_headline = strings.string_concat(T.from_str(prefix), base_headline) root = asker.refresh(root) children = asker.ask(fields.get_field(visible_children(), root)).firm_answer body = empty_lines() for child in lists.iterator(asker, children): section = asker.ask(outline_to_lines(child)).firm_answer body = concat_lines(body, section) result = concat_lines(one_line(full_headline), indent_lines(body)) asker.update(updates.set_field(cached_lines(), result), root) return asker.reply(answer=result)
def process_char(asker, root, c, parents): c = convert.to_char(asker, c) if convert.check_hard(asker, is_pointer(), root): if c == 'q': return asker.reply(value=quit) elif c == 'j': children = asker.ask(fields.get_field(visible_children(), root)).firm_answer if convert.check_hard(asker, lists.is_empty(), children): asker.pass_through(moved(down)) else: children = asker.refresh(children) first_child = asker.ask(fields.get_fields(lists.first(), children)).firm_answer asker.update(has_pointer_now(), root) asker.update(is_pointer_now(), first_child) return asker.reply() elif c == 'k': return asker.reply(value=moved(up)) elif c == 'z': asker.update(toggle_expanded(), root) return asker.reply() elif c == 'h': return asker.reply(value=moved(left)) elif c == 'l': #FIXME zoom out one by one instead of all of the way... #this is pretty straightforward if we are willing to go into and out of python #but it would surely be nicer to do it the 'right' way #I'm also pretty happy to wait asker.ask(explore_outline(root, parents)) return asker.reply(value=moved(left)) elif convert.check_hard(asker, has_pointer(), root): children = asker.ask(field.get_field(visible_children(), root)).firm_answer def make_handler(above, below): handler = Dispatcher("exploration child handler", ("question",)) @handler(moved.head) def move(asker, question, direction): if direction.head == down.head: if below is None: asker.pass_through(moved(direction)) else: asker.update(now_is_pointer(), below) asker.update(remove_pointer(), child) if direction.head == up.head: if above is None: asker.update(now_is_pointer(), root) asker.update(remove_pointer(), child) else: asker.update(add_pointer_to_bottom(), above) asker.update(remove_pointer(), child) elif direction.head == left.head: asker.update(remove_pointer(), child) asker.update(now_is_pointer(), root) return properties.trivial() #TODO insert a handler for changing underlying terms *etc* #I think that this is going to require some thought, #but I can wait return handler child_list = list(lists.iterator(asker, children)) new_parents = lists.snoc(parents, root) for i in range(len(child_list)): child = child_list[i] if i > 0: below = child_list[i-1] else: below = None if i < len(child_list) - 1: above = child_list[i+1] else: above = None asker.ask(process_char(child, c, new_parents), handler=make_handler(above, below)) return asker.reply()
def has_pointer_now(asker, object): if convert.check_hard(asker, has_pointer(), object): result = updates.update(updates.remove_modifier(is_pointer()), object) else: result = properties.simple_add_modifier(result, has_pointer()) return asker.reply(answer=result)
def toggle_expanded(asker, object): if convert.check_hard(asker, is_expanded(), object): result = updates.update(updates.remove_modifier(is_expanded()), object) else: result = properties.simple_add_modifier(object, is_expanded()) return asker.reply(answer=result)