Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
EmmaRenauld committed Apr 22, 2024
1 parent a0e8760 commit eb8c0b9
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 51 deletions.
4 changes: 4 additions & 0 deletions dwi_ml/GUI/args_management/argparse_equivalent.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
import logging

store_options = ['store_true', 'store_false']


Expand Down Expand Up @@ -35,6 +37,8 @@ def format_arg(argname, help, metavar=None, type=str, default=None,

class ArgparserForGui:
def __init__(self, description=None):
logging.debug(" GUI.args_management.argparse_equivalent: "
"Initializing ArgparserForGui")
self.description = description
self.required_args_list = {}
self.optional_args_list = {}
Expand Down
4 changes: 4 additions & 0 deletions dwi_ml/GUI/args_management/args_to_gui_all_args.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
import logging

import dearpygui.dearpygui as dpg

from dwi_ml.GUI.args_management.argparse_equivalent import ArgparserForGui
Expand All @@ -23,6 +25,8 @@ def add_args_to_gui(gui_parser: ArgparserForGui, known_file_dialogs=None):
List of str = accepted extensions (for files only).
ex: { 'out_filename': ['unique_file', ['.txt']]}
"""
logging.debug(" GUI.args_management.args_to_gui_all_args: adding args "
"to GUI.")
my_fonts = get_my_fonts_dictionary()

# 1. Required args:
Expand Down
105 changes: 67 additions & 38 deletions dwi_ml/GUI/args_management/args_to_gui_one_arg.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
| ------------------------------- | |---------------------- ----------------||
-------------------------------------------------------------------------------
"""
import logging
from typing import Dict, List

import dearpygui.dearpygui as dpg
Expand Down Expand Up @@ -58,13 +59,6 @@ def add_one_arg_and_help_to_gui(
"""
known_file_dialogs = known_file_dialogs or {}

# First, fix the params for our usage
# For us, const is the same as default.
if params['nargs'] == '?':
assert params['const'] is not None
assert params['default'] is None
params['default'] = params['const']

# Verify if optional
optional = True if argname[0] == '-' else False

Expand Down Expand Up @@ -177,38 +171,68 @@ def _get_nb_nargs(params):


def check_nargs_add_input(argname, params):
gui_narg_min, gui_narg_max = _get_nb_nargs(params)
logging.debug(" GUI.args_to_gui_one_arg: Checking nargs, adding input")

if gui_narg_max > gui_narg_min:
# Add a button to add more params and another to remove them
narg_min, narg_max = _get_nb_nargs(params)
logging.debug("For arg {}, expecting between {} and {} args."
.format(argname, narg_min, narg_max))

# Mutable value to keep track of nargs:
current_nb = {'current_nb': gui_narg_min}
user_data = (current_nb, gui_narg_max, argname, params)
if params['nargs'] == '?':
_add_const_input()
else:
if narg_max > narg_min:
_add_more_less_nargs_buttons(argname, narg_min, narg_max, params)
_add_initial_inputs(argname, narg_min, params)

dpg.add_button(label="Add more values",
parent=argname + OPTIONS_CELL,
tag=argname + ADD_NARGS_BUTTON,
callback=__callback_add_new_narg,
user_data=user_data)

# Add a button to remove params, but deactivated for now
# Button only exists if it is possible one day to remove nargs.
dpg.add_button(label="Remove values",
parent=argname + OPTIONS_CELL,
tag=argname + REMOVE_NARGS_BUTTON,
callback=__callback_remove_new_nargs,
user_data=user_data, enabled=False)
def _add_const_input():
pass

# Add the minimal number of nargs right now.
parent = argname + INPUTS_CELL
with dpg.group(tag=argname + NARGS_GROUP):
for n in range(gui_narg_min):
tag = argname + 'narg{}'.format(n) # tags start at 0
add_input_item_based_on_type(params, parent, tag)

def _add_more_less_nargs_buttons(argname, narg_min, narg_max, params):
# Add a button to add more params and another to remove them

# Mutable value to keep track of nargs:
current_nb = {'current_nb': narg_min}
user_data = (current_nb, narg_max, argname, params)

def __callback_add_new_narg(sender, __, user_data):
if not dpg.does_item_exist(argname + OPTIONS_CELL):
raise NotImplementedError("Wrong implementation. Wanted to add "
"the 'add_more_nargs' button, but "
"parent OPTIONS_CELL does not exist.")
logging.debug("ADDING MORE NARGS BUTTON")
dpg.add_button(label="Add more values",
parent=argname + OPTIONS_CELL,
tag=argname + ADD_NARGS_BUTTON,
callback=__callback_add_new_narg,
user_data=user_data)

# Add a button to remove params, but deactivated for now
# Button only exists if it is possible one day to remove nargs.
logging.debug("ADDING LESS NARGS BUTTON")
dpg.add_button(label="Remove values",
parent=argname + OPTIONS_CELL,
tag=argname + REMOVE_NARGS_BUTTON,
callback=__callback_remove_new_nargs,
user_data=user_data, enabled=False)


def _add_initial_inputs(argname, narg_min, params):
# Add the minimal number of nargs right now.
if not dpg.does_item_exist(argname + INPUTS_CELL):
raise NotImplementedError("Wrong implementation. Wanted to add "
"the 'add_more_nargs' button, but "
"parent INPUTS_CELL does not exist.")
logging.debug("ADDING NARGS GROUP")
with dpg.group(tag=argname + NARGS_GROUP,
parent=argname + INPUTS_CELL) as nargs_group:
for n in range(narg_min):
logging.debug("ADDING NARG #{} INPUT".format(n))
tag = argname + 'narg{}'.format(n) # tags start at 0
add_input_item_based_on_type(params, parent=nargs_group, tag=tag)


def __callback_add_new_narg(_, __, user_data):
"""
Callback given to the input section when nargs is set (one per narg).
Expand All @@ -221,6 +245,7 @@ def __callback_add_new_narg(sender, __, user_data):
params: dict
Argparser params.
"""
logging.debug(" GUI.args_to_gui_one_arg: Callback add new arg")
current_nb, gui_narg_max, argname, params = user_data

nb_nargs = current_nb['current_nb'] # Number of args already added
Expand All @@ -244,6 +269,7 @@ def __callback_add_new_narg(sender, __, user_data):


def __callback_remove_new_nargs(_, __, user_data):
logging.debug(" GUI.args_to_gui_one_arg: Callback remove new arg")
arg_info, nmin = user_data
arg_name = list(arg_info.keys())[0]
nb_nargs = arg_info[arg_name]
Expand All @@ -266,20 +292,25 @@ def __callback_allow_optional_input(_, app_data, user_data):
exclusive_list: list of other args that cannot be modified
at the same time.
"""
logging.debug(" GUI.args_to_gui_one_arg: Callback set optional arg.")

argname, params, exclusive_list = user_data

if app_data:
# Clicking!

# Remove the "Default = X" text; will replace by input receiver
if dpg.does_item_exist(argname + OPTION_DEFAULT_TEXTBOX):
logging.debug("- Hiding 'default=' text")
dpg.hide_item(argname + OPTION_DEFAULT_TEXTBOX)

if not dpg.does_item_exist(argname + NARGS_GROUP):
# If it's the first call, prepare buttons
logging.debug("- Preparing nargs buttons")
check_nargs_add_input(argname, params)
else:
# Else, show group back + nargs buttons
logging.debug("- Showing back nargs buttons")
dpg.show_item(argname + NARGS_GROUP)
if dpg.does_item_exist(argname + ADD_NARGS_BUTTON):
dpg.show_item(argname + ADD_NARGS_BUTTON)
Expand All @@ -288,26 +319,24 @@ def __callback_allow_optional_input(_, app_data, user_data):
# Verifying that other values in the exclusive groups are not also
# modified. If so, unselect them.
if exclusive_list is not None:
logging.debug("Hiding other exlusive args")
for excl_arg in exclusive_list:
if excl_arg != argname:
dpg.set_value(excl_arg + OPTION_CHECKBOX, False)

# Change checkbox text
if params['action'] in store_options:
dpg.set_item_label(argname + OPTION_CHECKBOX, "Unclick to unset")
else:

dpg.set_item_label(argname + OPTION_CHECKBOX,
"Unclick to use default")
dpg.set_item_label(argname + OPTION_CHECKBOX, "Unclick to unset")

else:
# Uncliking! (Changed our mind. Not using anymore)

# Show back text with "default = "
if dpg.does_item_exist(argname + OPTION_DEFAULT_TEXTBOX):
logging.debug("- Showing back 'default=' text.")
dpg.show_item(argname + OPTION_DEFAULT_TEXTBOX)

# Remove nargs, and possibly buttons
logging.debug("- Hiding nargs buttons")
dpg.hide_item(argname + NARGS_GROUP)
if dpg.does_item_exist(argname + ADD_NARGS_BUTTON):
dpg.hide_item(argname + ADD_NARGS_BUTTON)
Expand Down
5 changes: 2 additions & 3 deletions dwi_ml/GUI/main_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@


def prepare_main_menu():
logging.debug("Preparing main window...")
logging.debug("GUI.main_menu.prepare_main_menu(): "
"Preparing main window...")

titles = []
with dpg.window(tag="Primary Window"):
Expand Down Expand Up @@ -45,5 +46,3 @@ def prepare_main_menu():
dpg.bind_item_font(title, my_fonts['section_title'])

dpg.set_primary_window("Primary Window", True)

logging.debug("...main window done.\n")
16 changes: 9 additions & 7 deletions dwi_ml/GUI/menu1_create_hdf5.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@


def open_menu_create_hdf5():
logging.debug("Preparing HDF5 window...")
logging.debug("GUI.menu1_create_hdf5.open_menu_create_hdf5(): "
"Preparing HDF5 window...")
main_window = dpg.get_active_window()
dpg.hide_item(main_window)

Expand All @@ -38,7 +39,9 @@ def open_menu_create_hdf5():
" "
" CREATE A HDF5 DATASET:\n\n")
dpg.add_text("Choose your options. We will prepare a bash script "
"using dwiml_create_hdf5_dataset.py")
"using dwiml_create_hdf5_dataset.py\n"
"***************************************************"
"***************************************************")

# Creating known file dialogs.
# If arg names in the script change and if we don't make the
Expand Down Expand Up @@ -72,18 +75,17 @@ def open_menu_create_hdf5():
dpg.add_text("\n")
dpg.add_button(
label='OK! Create my script!', indent=1005, width=200,
height=100, callback=_create_hdf5_script,
height=100, callback=__create_hdf5_script_callback,
user_data=gui_parser)

# Set Title fonts
my_fonts = get_my_fonts_dictionary()
dpg.bind_item_font(main_title, my_fonts['main_title'])

logging.debug("...HDF5 window done.\n")


def _create_hdf5_script(_, __, user_data):
logging.debug("Getting all user choices and preparing HDF5 bash script.")
def __create_hdf5_script_callback(_, __, user_data):
logging.debug("GUI.menu1_create_hdf5.__create_hdf5_script_callback(): "
"Preparing script...")

# 1. Verify that user defined where to save the script.
out_path = dpg.get_value(TAG_HDF_SCRIPT_PATH)
Expand Down
3 changes: 2 additions & 1 deletion dwi_ml/GUI/menu1_l2t.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@


def open_menu_learn2track():
logging.debug("Preparing L2T window...")
logging.debug("GUI.menu1_l2t.open_menu_learn2track(): "
"Preparing L2T window...")
main_window = dpg.get_active_window()
dpg.hide_item(main_window)

Expand Down
3 changes: 2 additions & 1 deletion dwi_ml/GUI/menu1_tt.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@


def open_menu_transformers():
logging.debug("Preparing TT window...")
logging.debug("GUI.menu1_tt.open_menu_transformers(): "
"Preparing TT window...")
main_window = dpg.get_active_window()
dpg.hide_item(main_window)

Expand Down
17 changes: 16 additions & 1 deletion scripts_python/dwiml_launch_GUI.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Launch the GUI to help you prepare a script with all your favorite options.
"""
import argparse
import logging

from dwi_ml.GUI.main_menu import prepare_main_menu
from dwi_ml.GUI.utils.window import start_dpg, show_and_end_dpg
from dwi_ml.io_utils import add_logging_arg


def _prepare_argparser():
p = argparse.ArgumentParser(description=__doc__,
formatter_class=argparse.RawTextHelpFormatter)
add_logging_arg(p)
return p


def main():
logging.getLogger().setLevel(level='DEBUG')
p = _prepare_argparser()
args = p.parse_args()
logging.getLogger().setLevel(args.logging)

start_dpg()
prepare_main_menu()

Expand Down

0 comments on commit eb8c0b9

Please sign in to comment.