Пример #1
0
    def draw(self):
        imgui.begin(self.title)

        #imgui.text(str(imgui.is_mouse_down(0)))
        imgui.label_text(str(imgui.get_mouse_pos()), "position")
        imgui.label_text(str(imgui.is_mouse_down(0)), "left button")
        imgui.label_text(str(imgui.is_mouse_down(1)), "right button")
        imgui.label_text(str(imgui.is_mouse_down(2)), "middle button")

        imgui.end()
Пример #2
0
    def on_gui(self):
        # ---------------------------------------------------
        # Scene Hierarchy
        # ---------------------------------------------------
        imgui.begin("Scene Hierarchy")
        # draw all entities
        for entity in self.scene:
            self._draw_entity_node(entity)

        # clear selection
        if imgui.is_mouse_down(0) and imgui.is_window_hovered():
            self.selected_entity = None

        # create new entity
        if imgui.begin_popup_context_window():
            if menu_item_clicked("Create Empty Entity"):
                self.scene.create_entity("Empty Entity")
            imgui.end_popup()
        imgui.end()

        # ---------------------------------------------------
        # Properties
        # ---------------------------------------------------
        imgui.begin("Properties")
        if self.selected_entity:
            self._draw_entity_components(self.selected_entity)
        imgui.end()
Пример #3
0
    def mainloop(self):
        if self.use_imgui:
            self.canva.init_shader()
            self.canva.create_objects()
            self.rqq.rq_set_size(self.canva.view_size[0],
                                 self.canva.view_size[1])
            print("Waiting set size reply")
            self.rqq.process(self.canva)
            self.parse_reply()
            self.rqq.rq_load_image()
            while (not self.canva.should_close() and (not self.please_stop)):
                self.canva.proc()
                if self.canva.get_need_resize():
                    self.canva.set_image_black()
                    self.rqq.rq_set_size(self.canva.view_size[0],
                                         self.canva.view_size[1])
                    self.canva.start_frame()
                    self.canva.swap_buffers()
                    self.canva.poll_events()
                    continue
                self.rqq.process(self.canva)
                if self.canva.pipe.poll() == True:
                    self.parse_reply()
                self.impl.process_inputs()
                imgui.new_frame()

                if imgui.begin_main_menu_bar():
                    if imgui.begin_menu("File", True):
                        clicked_quit, selected_quit = imgui.menu_item(
                            "Quit", 'Ctrl+Q', False, True)
                        if clicked_quit:
                            self.please_stop = True
                        imgui.end_menu()
                    if imgui.begin_menu("Render", True):
                        imgui.menu_item("Save", None, False, True)
                        imgui.end_menu()
                    imgui.end_main_menu_bar()

                # right button rotation
                if imgui.is_mouse_down(1):
                    if self.canva.drag_start == None:
                        pos = imgui.get_io().mouse_pos
                        self.canva.drag_start = [pos[0], pos[1]]
                        self.rqq.rq_start_rotation(self.canva.drag_start[0],
                                                   self.canva.drag_start[1])
                    else:
                        pos = imgui.get_io().mouse_pos
                        self.pt = [pos[0], pos[1]]
                        self.rqq.rq_rotate(self.pt[0], self.pt[1])
                # left button panning
                elif imgui.is_mouse_down(0):
                    if self.canva.drag_start == None:
                        pos = imgui.get_io().mouse_pos
                        self.canva.drag_start = [pos[0], pos[1]]
                        self.prev_pos = pos
                    else:
                        pos = imgui.get_io().mouse_pos
                        if not self.prev_pos == pos:
                            self.rqq.rq_pan(pos[0] - self.prev_pos[0],
                                            pos[1] - self.prev_pos[1])
                            self.prev_pos = pos
                # wheel button scrolling
                else:
                    self.canva.drag_start = None
                    mw = imgui.get_io().mouse_wheel
                    pos = imgui.get_io().mouse_pos
                    if mw != 0:
                        self.rqq.rq_scroll(mw)
                    else:
                        if not self.prev_pos == pos:
                            self.rqq.rq_move(pos[0], pos[1])
                            self.prev_pos = pos

                self.canva.start_frame()
                imgui.render()
                draw_data = imgui.get_draw_data()
                self.impl.render(draw_data)
                self.canva.swap_buffers()
                self.canva.poll_events()
            self.canva.rq_stop()
            self.canva.pipe.close()
            print("GUI stopped")
        else:
            while True:
                rq = self.canva.pipe.recv()
                jdata = json.loads(rq)
                #print("rq:", rq, "jdata:", type(jdata))
                if jdata['rq'] == requests[RQ_LOAD_IMAGE]:
                    tex = self.canva.call_load_image()
                elif jdata['rq'] == requests[RQ_START_ROTATION]:
                    self.canva.call_start_rotation(jdata['args'][0],
                                                   jdata['args'][1])
                elif jdata['rq'] == requests[RQ_ROTATE]:
                    self.canva.call_rotate(jdata['args'][0], jdata['args'][1])
                elif jdata['rq'] == requests[RQ_SET_SIZE]:
                    self.canva.call_set_size(jdata['args'][0],
                                             jdata['args'][1])
                elif jdata['rq'] == requests[RQ_SCROLL]:
                    self.canva.call_scroll(jdata['args'])
                elif jdata['rq'] == requests[RQ_MOVE]:
                    self.canva.call_move(jdata['args'][0], jdata['args'][1])
                elif jdata['rq'] == requests[RQ_PAN]:
                    self.canva.call_pan(jdata['args'][0], jdata['args'][1])
                elif jdata['rq'] == requests[RQ_STOP]:
                    break
            self.canva.img.unlink()
            self.canva.pipe.close()
            print("OCCT stopped")
Пример #4
0
def main():
    global width_library
    global width_shematic
    global width_context
    global height_window

    global previous_key_callback
    global selected_link
    global selected_node
    global iggraph
    global node_library
    global debug_is_mouse_dragging
    
    global show_debug_window

    # states -------------------------
    
    scrolling = imgui.Vec2(0, 0)

    iggraph = IGGraph(node_library)

    # iggraph.reset()

    node_hovered_in_scene = -1
    parameter_link_start = None
    selected_parameter = None

    io_hovered = None 
    io_anchors_width_not_hovered = 10
    io_anchors_width_hovered = 15 
    right_splitter_is_active = False
    left_splitter_is_active = False
    
    image_width = 0
    image_height = 0
    image_texture = None

    # states -------------------------

    imgui.create_context()
    window = impl_glfw_init()
    impl = GlfwRenderer(window)
    io = imgui.get_io()
    previous_key_callback = glfw.set_key_callback(window,key_event)
    init_textures()

    assign_parameter_colors(node_library)

    while not glfw.window_should_close(window):
        glfw.poll_events()
        impl.process_inputs()

        imgui.new_frame()
        if imgui.begin_main_menu_bar():
            if imgui.begin_menu("File", True):
                clicked_new, selected_new = imgui.menu_item(
                    "New", 'Cmd+N', False, True
                )
                if clicked_new:
                    iggraph = IGGraph(node_library)
                clicked_load, selected_load = imgui.menu_item(
                    "Load", 'Cmd+L', False, True
                )
                if clicked_load:
                    root = tk.Tk()
                    root.withdraw()
                    filename = filedialog.askopenfilename()
                    if filename :
                        f=open(filename)
                        iggraph.from_json(json.load(f))
                        f.close()
                clicked_save, selected_save = imgui.menu_item(
                    "Save", 'Cmd+S', False, True
                )
                if clicked_save:
                    iggraph.reset()
                    graph_json = iggraph.to_json()
                    text2save = json.dumps(graph_json, indent=4, sort_keys=True)
                    root = tk.Tk()
                    root.withdraw()
                    f = filedialog.asksaveasfile(mode='w', defaultextension=".json")
                    if f is None: # asksaveasfile return `None` if dialog closed with "cancel".
                        return
                    f.write(text2save)
                    f.close()
                clicked_quit, selected_quit = imgui.menu_item(
                    "Quit", 'Cmd+Q', False, True
                )
                if clicked_quit:
                    exit(0)
                imgui.end_menu()
            if imgui.begin_menu("Debug", True):
                show_debug_window_clicked,  show_debug_window_selected = imgui.menu_item(
                    "Show Debug window", 'Cmd+D', show_debug_window, True
                )
                if show_debug_window_clicked:
                    show_debug_window = not show_debug_window
                catch_exceptions_clicked,  catch_exceptions_selected = imgui.menu_item(
                    "Catch Exceptions", '', iggraph.catch_exceptions, True
                )
                if catch_exceptions_clicked:
                    iggraph.catch_exceptions = not iggraph.catch_exceptions
                imgui.separator()
                imgui.menu_item(
                    "Examples", '', False, False
                )
                show_example_mosaic_clicked,  show_example_mosaic_selected = imgui.menu_item(
                    "Mosaic", '', False, True
                )
                if show_example_mosaic_clicked:
                    example_mosaic(iggraph)
                imgui.end_menu()
            imgui.end_main_menu_bar()

        height_window = io.display_size.y - 18  # imgui.get_cursor_pos_y()

        imgui.push_style_var(imgui.STYLE_ITEM_SPACING, imgui.Vec2(0,0))
        imgui.set_next_window_size(io.display_size.x, height_window)
        imgui.set_next_window_position(0, 18)
        imgui.push_style_var(imgui.STYLE_WINDOW_ROUNDING, 0)
        imgui.begin("Splitter test", False, imgui.WINDOW_NO_TITLE_BAR | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_BRING_TO_FRONT_ON_FOCUS)
        imgui.pop_style_var()
        imgui.pop_style_var()

        width_shematic = io.display_size.x - separator_width  - width_context - separator_width - width_library

        # ==============================================================================
        # Library
        # ==============================================================================

        imgui.push_style_var(imgui.STYLE_CHILD_BORDERSIZE, 0)
        imgui.begin_child("Library", width_library, 0, True)
        for node_name in node_library.nodes:
            if imgui.button(node_name, width_library):
                iggraph.create_node(node_name)
        imgui.end_child()
        imgui.pop_style_var()

        imgui.same_line()
        imgui.button("left_splitter", separator_width, height_window - 20)
        left_splitter_is_active = imgui.is_item_active()
        if (left_splitter_is_active):
            width_library += io.mouse_delta.x
            scrolling = imgui.Vec2(scrolling.x - io.mouse_delta.x, scrolling.y)
        if (imgui.is_item_hovered()):
            imgui.set_mouse_cursor(imgui.MOUSE_CURSOR_RESIZE_EW)
        
        imgui.same_line()

        # ==============================================================================
        # Shematic
        # ==============================================================================
        imgui.push_style_var(imgui.STYLE_CHILD_BORDERSIZE, 0)
        imgui.begin_child("shematic", width_shematic, 0, True)

        if show_inputs_popup(iggraph):
            imgui.open_popup("Outputs")
        show_outputs_popup(iggraph)

        # create our child canvas
        if iggraph.get_state() == iggraph.STATE_IDLE:
            imgui.text("status: edit | ")
        elif iggraph.get_state() == iggraph.STATE_RUNNING:
            imgui.text("status: run  | ")
        imgui.same_line()
        if iggraph.get_state() == iggraph.STATE_IDLE:
            if imgui.button("run"):
                #TODO if not running
                iggraph.set_state(iggraph.STATE_RUNNING)
                iggraph.prepare_to_run()
                imgui.open_popup("User Input")
            imgui.same_line()
            if imgui.button("run one step"):
                iggraph.set_state(iggraph.STATE_RUNNING)
                iggraph.prepare_to_run()
                iggraph.run_one_step()
        elif iggraph.get_state() == iggraph.STATE_RUNNING:
            if imgui.button("stop running"):
                iggraph.reset()
                iggraph.set_state(iggraph.STATE_IDLE)
            imgui.same_line()
            if imgui.button("run one step"):
                iggraph.set_state(iggraph.STATE_RUNNING)
                iggraph.run_one_step()
        # imgui.same_line(imgui.get_window_width() - 100)
        imgui.push_style_var(imgui.STYLE_FRAME_PADDING, imgui.Vec2(1, 1))
        imgui.push_style_var(imgui.STYLE_WINDOW_PADDING, imgui.Vec2(0, 0))
        imgui.begin_child("scrolling_region", 0, 0, True, imgui.WINDOW_NO_SCROLLBAR | imgui.WINDOW_NO_MOVE)
        imgui.pop_style_var()
        imgui.pop_style_var()
        imgui.push_item_width(120.0)

        offset = add(imgui.get_cursor_screen_pos(), scrolling)
        draw_list = imgui.get_window_draw_list()

        # Display links
        draw_list.channels_split(2)
        draw_list.channels_set_current(0)
        for link in iggraph.links:
            draw_link_param_to_param(draw_list, offset, link.output_parameter, link.input_parameter, selected_link == link)

        # Display nodes
        parameter_link_end = None
        one_parameter_hovered = False
        one_node_moving_active = False
        for node in iggraph.nodes:
            imgui.push_id(str(node.id))
            node_rect_min = add(offset, node.pos)
            draw_list.channels_set_current(1) # foreground
            old_any_active = imgui.is_any_item_active()

            #display node content first
            # todo
            test = add(node_rect_min, NODE_WINDOW_PADDING)
            imgui.set_cursor_screen_position(add(node_rect_min, NODE_WINDOW_PADDING))
            imgui.begin_group()
            imgui.text("")
            imgui.text(node.name)
            imgui.text("")
            imgui.end_group()

            # save size
            node_widgets_active = False # (not old_any_active and imgui.is_any_item_active())
            node.size = add( add( imgui.get_item_rect_size(), NODE_WINDOW_PADDING) , NODE_WINDOW_PADDING)
            node_rect_max = add(node.size, node_rect_min) 
            
            #display node box
            draw_list.channels_set_current(0) # background
            imgui.set_cursor_screen_position(node_rect_min)
            imgui.invisible_button(str(node.id), node.size.x, node.size.y)
            if imgui.is_item_hovered():
                node_hovered_in_scene = node.id
            else:
                node_hovered_in_scene = None
            node_moving_active = imgui.is_item_active()
            use_hovered_color = node_hovered_in_scene or selected_node == node
            draw_list.add_rect_filled(node_rect_min.x, node_rect_min.y, node_rect_max.x, node_rect_max.y, get_node_color(node, iggraph, use_hovered_color), 5)
            if node_hovered_in_scene and iggraph.is_error(node):
                imgui.begin_tooltip()
                imgui.text(iggraph.error_nodes[node])
                imgui.end_tooltip()

            # input parameters
            for parameter_name in node.inputs:
                parameter = node.inputs[parameter_name]
                center = node.get_intput_slot_pos(parameter)
                center_with_offset = add(offset, center)
                if io_hovered == parameter:
                    io_anchors_width = io_anchors_width_hovered
                else:
                    io_anchors_width = io_anchors_width_not_hovered
                imgui.set_cursor_pos(imgui.Vec2(center.x-io_anchors_width/2, center.y-io_anchors_width/2))
                imgui.push_id(str(str(node.id) + "input" + parameter.id))
                if (imgui.invisible_button("input", io_anchors_width, io_anchors_width)):
                    selected_parameter = parameter
                # imgui.is_item_hovered() does not work when dragging
                is_hovering = ((io.mouse_pos.x-offset.x>center.x-io_anchors_width/2) and 
                               (io.mouse_pos.x-offset.x<center.x+io_anchors_width/2) and
                               (io.mouse_pos.y-offset.y>center.y-io_anchors_width/2) and
                               (io.mouse_pos.y-offset.y<center.y+io_anchors_width/2))
                if is_hovering:
                    io_hovered = parameter
                    one_parameter_hovered = True
                    imgui.begin_tooltip()
                    imgui.text(parameter_name)
                    imgui.end_tooltip()
                if is_hovering and imgui.is_mouse_released(0):
                    parameter_link_end = parameter
                imgui.pop_id()
                draw_list.add_circle_filled(center_with_offset.x, center_with_offset.y, io_anchors_width/2, get_parameter_color(parameter))

            # output parameters
            for parameter_name in node.outputs:
                parameter = node.outputs[parameter_name]
                center = node.get_output_slot_pos(parameter)
                center_with_offset = add(offset, center)
                if io_hovered == parameter:
                    io_anchors_width = io_anchors_width_hovered
                else:
                    io_anchors_width = io_anchors_width_not_hovered
                imgui.set_cursor_pos(imgui.Vec2(center.x-io_anchors_width/2, center.y-io_anchors_width/2))
                imgui.push_id(str(str(node.id) + "output" + parameter.id))
                if (imgui.invisible_button("output", io_anchors_width, io_anchors_width)):
                    selected_parameter = parameter
                is_hovering = ((io.mouse_pos.x-offset.x>center.x-io_anchors_width/2) and 
                    (io.mouse_pos.x-offset.x<center.x+io_anchors_width/2) and
                    (io.mouse_pos.y-offset.y>center.y-io_anchors_width/2) and
                    (io.mouse_pos.y-offset.y<center.y+io_anchors_width/2))
                if is_hovering:
                    io_hovered = parameter
                    one_parameter_hovered = True
                    imgui.begin_tooltip()
                    imgui.text(parameter_name)
                    imgui.end_tooltip()
                draw_list.add_circle_filled(center_with_offset.x, center_with_offset.y, io_anchors_width/2, get_parameter_color(parameter))
                imgui.pop_id()
                # cannot use imgui.is_item_active, seems buggy with the scroll
                if is_hovering and imgui.is_mouse_down(0):
                    parameter_link_start = parameter

            if node_widgets_active or node_moving_active:
                selected_node = node
                one_node_moving_active = True
            if node_moving_active and imgui.is_mouse_dragging(0) and node.id==selected_node.id:
               node.pos = add(node.pos, io.mouse_delta)

            debug_is_mouse_dragging = imgui.is_mouse_dragging(0)

            imgui.pop_id()
        draw_list.channels_merge()
        if not one_parameter_hovered:
            io_hovered = None

        # scrolling
        mouse_is_in_schematic = (io.mouse_pos.x > width_library) and\
                                (io.mouse_pos.x < (width_library + width_shematic)) and\
                                (io.mouse_pos.y < height_window) and\
                                (io.mouse_pos.y > 18)
        if not one_node_moving_active and\
           not parameter_link_start and\
           imgui.is_mouse_dragging(0) and\
           mouse_is_in_schematic and\
           not left_splitter_is_active and\
           not right_splitter_is_active and\
           imgui.is_window_focused():
            scroll_offset = imgui.Vec2(io.mouse_delta.x, io.mouse_delta.y)
            scrolling = add(scrolling, scroll_offset)
        # link creation
        if parameter_link_start and parameter_link_end:
            iggraph.add_link(parameter_link_start, parameter_link_end)
        # creating link
        elif parameter_link_start and imgui.is_mouse_dragging(0):
            draw_link_param_to_point(draw_list, offset, parameter_link_start, io.mouse_pos.x, io.mouse_pos.y, True)
        # mouse release
        if imgui.is_mouse_released(0):
            parameter_link_start = None

        imgui.pop_item_width()
        imgui.end_child()

        # mouse click on the scene
        if imgui.is_mouse_clicked(0):
            mouse_pos = imgui.get_mouse_pos()
            local_mouse_pos = imgui.Vec2(mouse_pos.x - offset.x, mouse_pos.y - offset.y)
            selected_link = None
            for link in iggraph.links:
                start_node = link.output_parameter.owner
                start_pos = start_node.get_output_slot_pos(link.output_parameter)
                end_node = link.input_parameter.owner
                end_pos = end_node.get_intput_slot_pos(link.input_parameter)
                distance_mouse_start = math.sqrt(((local_mouse_pos.x-start_pos.x)**2) + ((local_mouse_pos.y-start_pos.y)**2))
                distance_mouse_end = math.sqrt(((local_mouse_pos.x-end_pos.x)**2) + ((local_mouse_pos.y-end_pos.y)**2))
                distance_start_end = math.sqrt(((start_pos.x-end_pos.x)**2) + ((start_pos.y-end_pos.y)**2))
                if ((distance_mouse_start + distance_mouse_end) - distance_start_end) < 0.1:
                    selected_link = link
                
        imgui.end_child()
        imgui.pop_style_var()

        imgui.same_line()
        imgui.button("right_splitter", separator_width, height_window - 20)
        right_splitter_is_active = imgui.is_item_active()
        if (right_splitter_is_active):
            width_context -= io.mouse_delta.x
        if (imgui.is_item_hovered()):
            imgui.set_mouse_cursor(imgui.MOUSE_CURSOR_RESIZE_EW)

        # ==============================================================================
        # Context
        # ==============================================================================

        imgui.same_line()
        imgui.push_style_var(imgui.STYLE_CHILD_BORDERSIZE, 0)
        imgui.begin_child("child3", width_context, 0, True);
        if selected_node:
            if selected_node.handle_dynamic_parameters():
                if imgui.button("add parameter"):
                    selected_node.add_dynamic_parameter()
            if imgui.tree_node("Inputs"):
                for parameter_name in selected_node.inputs:
                    parameter = selected_node.inputs[parameter_name]
                    if imgui.tree_node(parameter.id):
                        display_parameter(parameter, True)
                        imgui.tree_pop()
                imgui.tree_pop()
            if imgui.tree_node("Output"):
                for parameter_name in selected_node.outputs:
                    parameter = selected_node.outputs[parameter_name]
                    if imgui.tree_node(parameter.id):
                        display_parameter(parameter, False)
                        imgui.tree_pop()
                imgui.tree_pop()
        imgui.end_child()
        imgui.pop_style_var()

        # 
        imgui.end()

        # ==============================================================================
        # Debug Window
        # ==============================================================================
        if show_debug_window:
            debug_window_expanded, show_debug_window = imgui.begin("Debug", True)
            if parameter_link_start:
                imgui.text("parameter_link_start: " + parameter_link_start.id)
            else:
                imgui.text("parameter_link_start: " + "None")
            if selected_parameter:
                imgui.text("selected_parameter: " + selected_parameter.id)
            else:
                imgui.text("selected_parameter: " + "None")
            imgui.text("is_mouse_dragging: " + str(debug_is_mouse_dragging))
            imgui.text("mouse: (" + str(io.mouse_pos.x) + ", " + str(io.mouse_pos.y) + ")")
            imgui.end()

        gl.glClearColor(1., 1., 1., 1)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT)

        imgui.render()
        impl.render(imgui.get_draw_data())
        glfw.swap_buffers(window)

    impl.shutdown()
    glfw.terminate()
Пример #5
0
def global_keyboard_capture() -> bool:
    # TOOD: Mouse thing is weird behavior but probably fine?
    if _frames_without_modal < 2:
        return False
    return not ig.get_io().want_capture_keyboard or ig.is_mouse_down()
Пример #6
0
def on_frame():
    global cur_state, last_frame_x, last_frame_y, got_hold_last_frame

    imgui.set_next_window_position(0, 0)
    io = imgui.get_io()
    imgui.set_next_window_size(io.display_size.x, io.display_size.y)
    imgui.begin("Map",
                flags=imgui.WINDOW_NO_TITLE_BAR | imgui.WINDOW_NO_RESIZE
                | imgui.WINDOW_NO_COLLAPSE
                | imgui.WINDOW_NO_BRING_TO_FRONT_ON_FOCUS)

    map_hovered = imgui.is_window_hovered()

    draw_map()
    imgui.end()

    if imgui.begin_main_menu_bar():
        if imgui.begin_menu("File", True):
            clicked_quit, selected_quit = imgui.menu_item(
                "Quit", 'Cmd+Q', False, True)
            if clicked_quit:
                exit(1)

            clicked_load, selected_load = imgui.menu_item(
                "Load", "", False, True)
            if selected_load:
                load_map()

            clicked_save, selected_save = imgui.menu_item(
                "Save", "", False, True)
            if selected_save:
                save_map()

            clicked_export, selected_export = imgui.menu_item(
                "Export", "", False, True)
            if selected_export:
                export_map()

            clicked_reset, selected_reset = imgui.menu_item(
                "Reset", "", False, True)
            if selected_reset:
                cur_state = State()

            imgui.end_menu()
        imgui.end_main_menu_bar()

    imgui.begin("Tools", False)
    tools_hovered = imgui.is_window_hovered()
    draw_mode()

    left_button_clicked = imgui.is_mouse_clicked(button=0)
    right_button_clicked = imgui.is_mouse_clicked(button=1)

    mouse_button_clicked = (left_button_clicked or right_button_clicked)
    left_button_down = imgui.is_mouse_down(button=0)
    if mouse_button_clicked:
        print("clicked left {} right {}".format(left_button_clicked,
                                                right_button_clicked))

    #else:
    #    print("clearing down_x and down_y")
    #    start_down_x = None
    #    start_down_y = None

    if got_hold_last_frame:
        cur_x, cur_y = imgui.get_mouse_pos()
        moved_cam_x = last_frame_x - cur_x
        moved_cam_y = last_frame_y - cur_y
        cur_state.camera_x += moved_cam_x
        cur_state.camera_y += moved_cam_y

    if map_hovered and not tools_hovered and mouse_button_clicked:
        x, y = imgui.get_mouse_pos()
        print("interpreting click at {},{}".format(x, y))
        interpret_click(x + cur_state.camera_x, y + cur_state.camera_y,
                        LEFT_BUTTON if left_button_clicked else RIGHT_BUTTON)
    elif map_hovered and left_button_down:
        got_hold_last_frame = True
        last_frame_x, last_frame_y = imgui.get_mouse_pos()
    elif not left_button_down:
        got_hold_last_frame = False

    imgui.end()
Пример #7
0
def debug_window() -> IMGui[None]:
    with window(name="debug"):
        debug_window_draw_start_t_s = glfw.get_time()

        if debug_dict['crash'] is not None:
            origin = debug_dict['crash']['origin']
            cause = debug_dict['crash']['cause']
            exception = debug_dict['crash']['exception']
            with window(name="Crash report"):
                im.text(
                    'Exception raised during `{}`. State rolled back'.format(
                        origin))
                im.text('Caused by:')
                im.text('\t' + repr(cause))

                im.text('\n' + str(exception.__cause__) if exception.
                        __cause__ is not None else '')
                for line in traceback.format_tb(exception.__traceback__):
                    im.text(line)
                im.text("{}: {}".format(
                    type(exception).__qualname__,
                    str.join(', ', map(repr, exception.args))))

                if im.button('close'):
                    debug_dict['crash'] = None

        # print some general app state
        # im.text("actions: "+str(frame_actions))
        im.text("mouse:   " + str(get_mouse_position()))
        im.text("click:   " + str(im.is_mouse_clicked(button=0)))
        im.text("down:    " + str(im.is_mouse_down(button=0)))
        im.text(
            "cl+down: " +
            str(im.is_mouse_clicked(button=0) and im.is_mouse_down(button=0)))
        im.text("drag:    " + str(im.is_mouse_dragging(button=0)))
        im.text("drag-d:  " + str(im.get_mouse_drag_delta()))
        im.new_line()

        # print the avg durations of ranges set with `debug_log_time`
        show_avg_durations_of_recorded_ranges()

        # print the values in dicts logged with `debug_log_dict`
        for name, sequence in debug_dict['sequences'].items():
            im.new_line()
            show_sequence(sequence, name=name)

        # print the values in dicts logged with `debug_log_dict`
        for name, dictionary in debug_dict['dicts'].items():
            im.new_line()
            # d = order_dict_by_key(stringify_keys(flatten_dict(dictionary)))

            show_varied_dict(dictionary, name=name)

        # print all other values in debug (set with `debug_log`)
        im.new_line()
        show_varied_dict(debug_dict['values'])

        # print how long it took to draw the debug window (hehe)
        debug_window_draw_end_t_s = glfw.get_time()
        debug_window_draw_dur_ms = (debug_window_draw_end_t_s -
                                    debug_window_draw_start_t_s) * 1000
        im.new_line()
        im.text(
            "drawing debug took {:4.1f} ms".format(debug_window_draw_dur_ms))
Пример #8
0
def pan_zoom(name,
             state,
             width=None,
             height=None,
             content_gen=None,
             drag_tag=None,
             down_tag=None,
             hover_tag=None):
    """ Create the Pan & Zoom widget, serving as a container for a thing given by `content_gen`.

    This widget is mostly not used directly. Instead, a special-purpose wrapper can be used,
    such as `concur.extra_widgets.image.image`, or `concur.extra_widgets.frame.frame`.

    Args:
        name: widget name. Also serves as an event identifier
        state: `PanZoom` object representing state.
        width: widget width in pixels. If `None`, it fills the available space.
        height: widget height in pixels. If `None`, it fills the available space.
        content_gen: Widget generator to display inside the pan-zoom widget. All events are passed
            through as a return tuple member. This is a function that returns a Concur widget, and
            takes two keyword arguments:

            * **tf**: `concur.extra_widgets.pan_zoom.TF` object with transformation information
            * **event_gen**: This is an event generator which returns the drag, down, and hover events when they occur.

            It is up to the widget to do the necessary transformations
            using the `TF` object, and optionally react to the events created by `event_gen`.
        drag_tag: The event tag for LMB drag events. If `None`, no drag events are fired.
        down_tag: The event tag for LMB down events. If `None`, no down events are fired.
            Useful in combination with `drag_tag` to indicate when the dragging started.
        hover_tag: The event tag for mouse hover when no mouse buttons are down.
            If `None`, no hover events are fired. Events are fired only when the mouse is moving.

    Returns:
        To ease integration with other widgets, this widget returns events in a special format, `(name, state, event)`.
        `state` or `event` may be `None` in case `state` didn't change, or there is no `event`.

        If `drag_tag`, or `down_tag` arguments are used, these are fired in the `event` member of the return tuple.
    """
    assert content_gen is not None
    tf, content = None, None
    event_queue = queue.Queue()
    while True:
        assert not state.keep_aspect or not state.fix_axis, \
            "Can't fix axis and keep_aspect at the same time."
        # Dynamically rescale width and height if they weren't specified
        if width is None:
            w = imgui.get_content_region_available()[0]
        else:
            w = width
        if height is None:
            h = imgui.get_content_region_available()[1]
        else:
            h = height
        frame_w = max(1, w - state.margins[0] + state.margins[2])
        frame_h = max(1, h - state.margins[1] + state.margins[3])
        w = max(1, w)
        h = max(1, h)

        zoom_x = frame_w / (state.right - state.left)
        zoom_y = frame_h / (state.bottom - state.top)

        left, right = state.left, state.right
        top, bottom = state.top, state.bottom
        if state.keep_aspect:
            aspect = float(state.keep_aspect)
            assert state.keep_aspect > 0, "Negative aspect ratio is not supported."
            if abs(zoom_x) > abs(zoom_y) * aspect:
                zoom_x = np.sign(zoom_x) * abs(zoom_y) * aspect
                center_x = (left + right) / 2
                left = center_x - frame_w / zoom_x / 2
                right = center_x + frame_w / zoom_x / 2
            if abs(zoom_y) > abs(zoom_x) / aspect:
                zoom_y = np.sign(zoom_y) * abs(zoom_x) / aspect
                center_y = (top + bottom) / 2
                top = center_y - frame_h / zoom_y / 2
                bottom = center_y + frame_h / zoom_y / 2

        origin = imgui.get_cursor_screen_pos()

        # needs to be before is_window_hovered
        imgui.begin_child("Pan-zoom",
                          w,
                          h,
                          False,
                          flags=imgui.WINDOW_NO_SCROLLBAR
                          | imgui.WINDOW_NO_SCROLL_WITH_MOUSE)

        # Interaction
        st = copy.deepcopy(state)
        io = imgui.get_io()
        is_window_hovered = imgui.is_window_hovered()

        if (imgui.is_mouse_clicked(1)
                or imgui.is_mouse_clicked(2)) and is_window_hovered:
            st.is_rmb_dragged = True
        if not (io.mouse_down[1] or io.mouse_down[2]):
            st.is_rmb_dragged = False

        delta = io.mouse_delta

        # Pan
        if st.is_rmb_dragged and (delta[0] or delta[1]):
            if st.fix_axis != 'x':
                st.left -= delta[0] / zoom_x
                st.right -= delta[0] / zoom_x
            if st.fix_axis != 'y':
                st.top -= delta[1] / zoom_y
                st.bottom -= delta[1] / zoom_y

        # Zoom
        if (imgui.is_window_hovered() or st.is_rmb_dragged) and io.mouse_wheel:
            factor = 1.3**io.mouse_wheel

            if st.fix_axis != 'x':
                mx_rel = (io.mouse_pos[0] - origin[0] -
                          state.margins[0]) / frame_w * 2 - 1
                mx = mx_rel * (right - left) / (st.right - st.left) / 2 + 0.5
                wi = st.right - st.left
                st.left = st.left + wi * mx - wi / factor * mx
                st.right = st.right - wi * (1 - mx) + wi / factor * (1 - mx)

            if st.fix_axis != 'y':
                my_rel = (io.mouse_pos[1] - origin[1] -
                          state.margins[1]) / frame_h * 2 - 1
                my = my_rel * (bottom - top) / (st.bottom - st.top) / 2 + 0.5
                hi = st.bottom - st.top
                st.top = st.top + hi * my - hi / factor * my
                st.bottom = st.bottom - hi * (1 - my) + hi / factor * (1 - my)

        # Get screen-space bounds disregarding the margins
        left_s = left - st.margins[0] / zoom_x
        top_s = top - st.margins[1] / zoom_y
        right_s = right - st.margins[2] / zoom_x
        bottom_s = bottom - st.margins[3] / zoom_y

        s2c = np.array([  # Screen to Content
            [1 / zoom_x, 0, left_s - origin[0] / zoom_x],
            [0, 1 / zoom_y, top_s - origin[1] / zoom_y]
        ])

        c2s = np.array([  # Content to Screen
            [zoom_x, 0, origin[0] - left_s * zoom_x],
            [0, zoom_y, origin[1] - top_s * zoom_y]
        ])

        view_s = [origin[0], origin[1], origin[0] + w, origin[1] + h]
        view_c = [left_s, top_s, right_s, bottom_s]

        content_value = None
        content_returned = False

        new_tf = TF(c2s, s2c, view_c, view_s)
        if down_tag \
                and not st.is_rmb_dragged \
                and imgui.is_mouse_clicked() \
                and is_window_hovered:
            event_queue.put(
                (down_tag, new_tf.inv_transform(np.array([[*io.mouse_pos]
                                                          ]))[0]))
        if hover_tag \
                and not st.is_rmb_dragged \
                and not any(imgui.is_mouse_down(i) for i in [0,1,2]) \
                and is_window_hovered:
            new_tf.hovered = True
            if (delta[0] or delta[1]):
                event_queue.put(
                    (hover_tag,
                     new_tf.inv_transform(np.array([[*io.mouse_pos]]))[0]))
        if drag_tag \
                and not st.is_rmb_dragged:
            imgui.invisible_button("", w, h)
            dx, dy = io.mouse_delta
            if imgui.is_item_active() and (dx or dy):
                event_queue.put(
                    (drag_tag,
                     np.array([new_tf.s2c[0, 0] * dx, new_tf.s2c[1, 1] * dy])))
            imgui.set_item_allow_overlap()
        try:
            from concur.core import lift
            if tf is None or tf != new_tf:
                tf = new_tf
                w, h = tf.view_s[2] - tf.view_s[0], tf.view_s[3] - tf.view_s[1]
                content = content_gen(tf=tf,
                                      event_gen=lambda: listen(event_queue))
            next(content)
        except StopIteration as e:
            content_value = e.value
            content_returned = True
        finally:
            imgui.end_child()
        changed = st != state

        if changed or content_returned:
            return name, (st if changed else None, content_value)
        yield