def render(self): events = yield from c.window( title=self.name, widget=c.multi_orr([ c.text("Style: "), c.orr_same_line([ c.radio_button(label, active=self.style == label) for label in self.style_choices ]), c.spacing(), c.text("Username: "******"inject" ImGui calls into the rendering routine. # It may be better to abstract these `lift` calls out into a function (or not). # Note that Concur (and ImGui as a whole) are primarily made for debug interfaces, so custom styling like this is a bit clunky. # The calls used for sizing are [documented here](https://pyimgui.readthedocs.io/en/latest/reference/imgui.core.html). # You can do a whole lot of customization like this, I recommend skimming through the above link. c.lift(lambda: imgui.push_item_width(100)), c.input_text(name="", value=self.username, tag="Username", buffer_length=10), c.text("Password: "******"", value=self.password, tag="Password"), c.lift(lambda: imgui.pop_item_width()), c.checkbox("Remember credentials", self.remember_credentials), c.spacing(), c.text("Input file: "), c.same_line(), c.text(self.filepath), c.button("Open"), self.custom_spacing(0, 20), c.separator(), c.button("Save"), c.same_line(), c.button("Reset"), ])) for tag, value in events: # This is how event handling works with `multi_orr` if tag in self.style_choices: self.style = tag self.style_choices[tag]() elif tag == "Open": self.prompt_for_input_file() elif tag == "Username": self.username = value elif tag == "Password": self.password = value elif tag == "Remember credentials": self.remember_credentials = value elif tag == "Save": print("Saved") elif tag == "Reset": print("Resetted") return self
def app(): return c.columns([ [c.text("Hello,"), c.button("Click me")], [c.text("columns!"), c.button("Or me")], [c.text("columns!"), c.button("Or me")], [c.text("columns!"), c.button("Or me")], [c.text("columns!"), c.button("Or me")], ], "start", True)
def __auth_view(self): view = c.orr([ c.collapsing_header( text="Languages", widget=c.orr([ c.radio_button( label='English', active=True if self.language == 'default' else False, tag='english'), c.same_line(), c.radio_button( label='Russian', active=True if self.language == 'cyrillic' else False, tag='cyrillic'), c.same_line(), c.radio_button( label='Korean', active=True if self.language == 'korean' else False, tag='korean'), c.same_line(), c.radio_button( label='Japanese', active=True if self.language == 'japanese' else False, tag='japanese'), c.same_line(), c.radio_button(label='Chinese', active=True if self.language == 'chinese_full' else False, tag='chinese_full'), c.same_line(), c.radio_button( label='German', active=True if self.language == 'latin' else False, tag='latin'), ]), open=True), self.custom_spacing(1, 1), c.text("Username:"******"", value=self.username, tag="username"), c.text("Password:"******"", value=self.password, tag="password"), c.button("Terminate", tag='terminate') if self.process else self.dynamic_popup_button( label="Login", error=self.evaluate_popup_behaviour({ 'user': self.username, 'password': self.password }), tag='login'), ]) return view
def app(): while True: tag, value = yield from c.orr([ c.text("Drag & drop example:"), c.drag_drop_source("Drag", 123, c.button("Hello, 123")), c.drag_drop_source("Drag", 456, c.text("Hello, 456")), c.drag_drop_target("Drag", 'abc', c.button("Drop here")), c.drag_drop_target("Drag", 'def', c.button("or here")), ]) if tag == "Hello": print("Hello") elif tag == "Drag": print(value) yield
def app(image_path, output_path): view = c.Image(Image.open(image_path)) autosave = True try: r = csv.reader(open(output_path, 'r')) pts = [(int(x), int(y)) for x, y in r] except FileNotFoundError: pts = [] while True: tag, value = yield from c.orr([ c.orr_same_line([c.button("Save"), c.text(f"Click to (de)annotate. N: {len(pts)}"), c.checkbox("Autosave", autosave)]), c.image("Image", view, content_gen=c.partial(overlay, np.array(pts).reshape(-1, 2))), ]) if tag == "Image": view = value elif tag == "Autosave": autosave = value elif tag == "Rem": pts.pop(value) elif tag == "Add": pts.append((int(value[0]), int(value[1]))) if tag == "Save" or autosave and tag in ["Rem", "Add"]: with open(output_path, 'w') as f: csv.writer(f).writerows(pts) yield
def generate_thread_table(self): """Render a simple table with thread statuses.""" rows = [c.text_colored("Thread status:", 'yellow')] if self.task_statuses: for i, status in enumerate(self.task_statuses): rows.append(c.text(f"{i}: {status}")) return c.collapsing_header("Thread status", c.optional(bool(self.task_statuses), c.orr, rows), open=False)
def hello_world(): show_demo_window = True demo_state = DemoState() show_another_window = False float = 0.0 counter = 0 while True: tag, value = yield from c.orr([ c.window( "Hello, world!", c.orr([ c.text("This is some useful text."), c.checkbox("Demo Window", show_demo_window), c.checkbox("Another Window", show_another_window), c.slider_float("Float", float, 0, 1), # Not implemented: background color chooser c.orr_same_line( [c.button("Button"), c.text(f"counter = {counter}")]), # Not implemented: FPS counter ])), c.optional( show_another_window, lambda: c.window( "Another Window", c.orr([ c.text("Hello from another window!"), c.button("Close Me"), ]))), c.optional(show_demo_window, c.partial(demo_window, demo_state)), ]) if tag == "Demo Window": show_demo_window = value elif tag == "Another Window": show_another_window = value elif tag == "Float": float = value elif tag == "Button": counter += 1 elif tag == "Close Me": show_another_window = False yield
def demo_window(state): while True: tag, value = yield from c.window( "Concur Demo", c.orr([ c.text("Concur says hello. (TODO: version)"), c.collapsing_header("Help", c.orr([ c.text("Not implemented."), ]), False), c.collapsing_header("Configuration", c.orr([ c.text("Not implemented."), ]), False), c.collapsing_header("Window options", c.orr([ c.text("Not implemented."), ]), False), c.collapsing_header( "Widgets", c.orr([ c.tree_node("Basic", c.orr([ c.button("Button"), ]), False), ]), False), c.collapsing_header("Layout & Scrolling", c.orr([ c.text("Not implemented."), ]), False), c.collapsing_header("Popups & Modal windows", c.orr([ c.text("Not implemented."), ]), False), c.collapsing_header("Columns", c.orr([ c.text("Not implemented."), ]), False), c.collapsing_header("Filtering", c.orr([ c.text("Not implemented."), ]), False), c.collapsing_header("Inputs, Navigation & Focus", c.orr([ c.text("Not implemented."), ]), False), ])) yield
def controlee(): counter = 5 while True: action, _ = yield from c.orr([ c.text(f"Count: {counter}"), tester.mark("--", c.button("Decrement")), tester.mark("++", c.button("Increment")), ]) if action == "Increment": counter += 1 elif action == "Decrement": counter -= 1 yield
def app(): im1 = c.Image(Image.open("examples/lenna.png")) im2 = c.Image(Image.open("examples/lenna.png")) while True: k, v = yield from c.orr([ c.button("Hello,"), c.button("world!"), c.orr_same_line([ c.text("Hello,"), c.nothing(), c.text_tooltip("Text tooltip", c.text("world!")), c.text_tooltip("Orr tooltip", c.orr([ c.text_tooltip("Button tooltip", c.button("Button1")), c.button("Button2"), ])), c.orr([ c.button("Button3"), c.button("Button4"), ]), c.text("Finish line."), ]), c.draggable("Drag", c.orr([c.button("Draggable Button"), c.forever(c.button, "Another")])), c.input_text("Hello", "world!", 123), c.collapsing_header("Image", c.orr([ c.tooltip(c.orr([c.text("Hello!"), c.image("", im1, width=300, height=200), c.event(("Key", "Tooltip value"))]), c.image("Im1", im1, width=30, height=20)), c.image("Im2", im2, width=30, height=20), ])), c.input_text("Hello", "world!", 123), c.key_press("Key", glfw.KEY_SPACE), ]) if k == "Im1": im1 = v if k == "Im2": im2 = v print(k, v) yield
def app(): image = Image.open("examples/lenna.png") view = c.Image(image) while True: tag, value = yield from c.orr([ c.text( "Drag using right mouse button,\nscroll using mouse wheel."), c.image("Image", view, content_gen=overlay), ]) if tag == "Image": view = value elif tag == "Rotate": image = image.transpose(Image.ROTATE_270) view.change_image(image) yield
def app(): view = c.Image(Image.open("examples/lenna.png")) lines = [] while True: tag, value = yield from c.orr([ c.text("Create lines by dragging with the left mouse button."), c.image("Image", view, content_gen=c.partial(overlay, deepcopy(lines)), drag_tag="Drag", down_tag="Down"), ]) if tag == "Image": view = value elif tag == "Draw": lines = value yield
def app(): while True: key, value = yield from c.orr([ c.main_menu_bar(c.orr([ c.menu("File", c.orr([ c.menu_item("New", "Ctrl+N"), c.menu_item("Open...", "Ctrl+O"), c.separator(), c.menu_item("Quit", "Ctrl+Q"), ])), ])), c.text("Try Ctrl+Q."), c.key_press("Quit", ord('Q'), ctrl=True), ]) print(key, value) if key == "Quit": return yield
def counter(): counter = 0 while True: action, _ = yield from c.orr([ c.text(f"Count: {counter}"), c.orr_same_line([ c.button("Increment"), c.button("Decrement"), c.button("Reset") ]), ]) if action == "Increment": counter += 1 elif action == "Decrement": counter -= 1 elif action == "Reset": counter = 0 yield
def draw(i): return c.orr([ c.text(f"i: {i}"), ])
font_name = "DejaVuSansCode_0.ttf" font_name_2 = "Hack Regular Nerd Font Complete Mono Windows Compatible.ttf" font_file = str(Path(__file__).parent / "src" / "resources" / font_name) font_file_2 = str(Path(__file__).parent / "src" / "resources" / font_name_2) imgui.create_context() io = imgui.get_io() font = io.fonts.add_font_from_file_ttf( font_file, 30, io.fonts.custom_glyph_ranges([ 0x0020, 0x00FF, 0x2000, 0x206F, 0x3000, 0x30FF, 0x31F0, 0x31FF, 0xFF00, 0xFFEF, 0x4e00, 0x9FAF, ])) io.fonts.add_font_from_file_ttf(font_file_2, 30, io.fonts.custom_glyph_ranges( [0x1f600, 0x1f800]), merge=True) c.main(c.text("hello \U0001f600 汉字"))
def hello_world(tester): return c.orr([c.text("Hello, world!"), tester.pause()])
def timer(): yield from c.orr([c.text(""), c.button("Start timer")]) yield future = executor.submit(lambda: time.sleep(3)) yield from c.orr([c.text("waiting for 3s..."), c.button("Cancel"), c.Block(future)])
def render(self): if self.task_statuses: # Prepare the progress bar n_working_or_finished = sum([ status in ["Working...", "Done."] for status in self.task_statuses ]) n_total_threads = len(self.task_statuses) progress = n_working_or_finished / n_total_threads progress_text = f"{n_working_or_finished}/{n_total_threads}" progress_bar = self.progress_bar_widget(progress_text, progress) else: progress_bar = c.nothing() # use `multi_orr`, so that concurrent events aren't thrown away events = yield from c.window( self.name, c.multi_orr([ c.text_tooltip( "Drag the slider or enter your preferred amount directly to adjust the amount of threads used.", c.text("Number of Threads")), c.slider_int(label="", value=self.n_threads, min_value=1, max_value=100, tag='threads'), c.same_line(), c.lift(lambda: imgui.push_item_width( self.evaluate_field_size(self.n_threads, self.n_tasks))), c.interactive_elem(imgui.input_int, "", self.n_threads, tag="threads"), c.lift(lambda: imgui.pop_item_width()), c.slider_int(label="", value=self.n_tasks, min_value=1, max_value=100, tag='tasks'), c.same_line(), c.lift(lambda: imgui.push_item_width( self.evaluate_field_size(self.n_threads, self.n_tasks))), c.interactive_elem(imgui.input_int, "", self.n_tasks, tag="threads"), c.lift(lambda: imgui.pop_item_width()), c.input_text(name="Information, the feature needs", value=self.information, tag="info"), c.button("Terminate", tag='terminate') if self.process else self.dynamic_popup_button( "Start", "Feature information is missing. Continue anyway?" if not self.information else self.evaluate_popup_behaviour( {'information': True})), c.separator(), c.text_colored("Feature status:", 'yellow'), c.text(f"{self.window_status}"), progress_bar, c.optional(bool(self.task_statuses), self.generate_thread_table), c.separator(), c.text_colored(f"{self.name} Log:", 'orange'), # c.child(name=f"{self.name} Log", widget=self.log_widget(self.log), width=-1, height=-1, border=True), c.window("Log", self.log_widget(self.log)), c.tag(tag_name="status_queue", elem=c.listen(self.status_queue)), c.tag("log_queue", c.listen(self.log_queue)), ])) for tag, value in events: # This is how event handling works with `multi_orr` if tag == "info": self.information = value elif tag == "Start": assert self.process is None self.status_queue = Queue() self.task_statuses = ["Waiting"] * self.n_tasks information_dict = { 'log_queue': self.log_queue, 'information': self.information } self.process = Process(target=self.threadify, args=( NiceFeature, information_dict, )) self.process.start() elif tag == "terminate": assert self.process is not None self.process.terminate() self.window_status = "Terminated." self.process = None for i, status in enumerate(self.task_statuses, 0): if status in ["Waiting", "Working..."]: self.task_statuses[i] = "Terminated." elif tag == "status_queue": # Handle events fired by threads. # Update the thread state table thread_id, new_status = value # Update the feature status if thread_id < 0: self.window_status = new_status if new_status == "Work done.": self.process = None else: self.task_statuses[thread_id] = new_status elif tag == "log_queue": msg = value.getMessage() # Colored logging try: text, color = msg.split("|") except: text, color = msg, "white" if color == "green": rgb_tuple = (0, 255, 0) elif color == "red": rgb_tuple = (255, 0, 0) else: rgb_tuple = (255, 255, 255) self.log_list.append((text, rgb_tuple)) elif tag == "tasks": self.n_tasks = value elif tag == "threads": self.n_threads = value return self