From 834dbe7d786a9ef591a67231b5bdcb71bea484ed Mon Sep 17 00:00:00 2001 From: Abhishek Yenpure Date: Sun, 24 Aug 2025 10:17:30 -0700 Subject: [PATCH 1/6] fix: P0 variable in reader and move camera controls to toolbar --- quickview/interface.py | 19 ++----- quickview/plugins/eam_reader.py | 2 +- quickview/ui/toolbar.py | 8 +++ quickview/ui/view_settings.py | 94 +++++++++++++++++++-------------- 4 files changed, 66 insertions(+), 57 deletions(-) diff --git a/quickview/interface.py b/quickview/interface.py index 00d793c..12a325e 100644 --- a/quickview/interface.py +++ b/quickview/interface.py @@ -23,7 +23,7 @@ from quickview.ui.slice_selection import SliceSelection from quickview.ui.projection_selection import ProjectionSelection from quickview.ui.variable_selection import VariableSelection -from quickview.ui.view_settings import ViewProperties, ViewControls +from quickview.ui.view_settings import ViewProperties from quickview.ui.toolbar import Toolbar # Build color cache here @@ -738,23 +738,10 @@ def ui(self) -> SinglePageWithDrawerLayout: load_variables=self.load_variables, update_available_color_maps=self.update_available_color_maps, generate_state=self.generate_state, + zoom=self.zoom, + move=self.pan_camera, ) - card_style = """ - position: fixed; - bottom: 1rem; - right: 1rem; - height: 2.4rem; - z-index: 2; - display: flex; - align-items: center; - """ - ViewControls( - zoom=self.zoom, - move=self.pan_camera, - style=card_style, - ) - with layout.drawer as drawer: drawer.width = 400 drawer.style = ( diff --git a/quickview/plugins/eam_reader.py b/quickview/plugins/eam_reader.py index 1e5a594..672bd66 100644 --- a/quickview/plugins/eam_reader.py +++ b/quickview/plugins/eam_reader.py @@ -99,7 +99,7 @@ def FindSpecialVariable(data, lev, hya, hyb): if len(_hyai) != len(_hybi): raise Exception("Unmatched pair of hya and hyb variables found") - p0 = EAMConstants.P0 + p0 = data["P0"][:].item() if "P0" in var else EAMConstants.P0 ps0 = EAMConstants.PS0 if len(_hyai) == 1: diff --git a/quickview/ui/toolbar.py b/quickview/ui/toolbar.py index 22a94a1..09834fa 100644 --- a/quickview/ui/toolbar.py +++ b/quickview/ui/toolbar.py @@ -1,5 +1,6 @@ from trame.decorators import TrameApp, task from trame.widgets import html, vuetify2 as v2 +from quickview.ui.view_settings import ViewControls try: from trame.widgets import tauri @@ -88,6 +89,8 @@ def __init__( load_variables=None, update_available_color_maps=None, generate_state=None, + zoom=None, + move=None, **kwargs, ): self.server = server @@ -299,6 +302,11 @@ def __init__( width=3, ) v2.VDivider(vertical=True, classes="mx-2") + ViewControls( + zoom=zoom, + move=move, + style="flex-shrink: 0;", + ) with v2.VTooltip(bottom=True): with html.Template(v_slot_activator="{ on, attrs }"): with v2.VBtn( diff --git a/quickview/ui/view_settings.py b/quickview/ui/view_settings.py index 4d1ae2e..276a63c 100644 --- a/quickview/ui/view_settings.py +++ b/quickview/ui/view_settings.py @@ -126,9 +126,15 @@ def __init__( @TrameApp() class ViewControls(v2.VCard): def __init__(self, zoom=None, move=None, **kwargs): + # Merge any incoming style with our default style + default_style = "background-color: #f5f5f5; border-radius: 4px;" + incoming_style = kwargs.pop("style", "") + merged_style = f"{default_style} {incoming_style}".strip() + super().__init__( - classes="overflow-hidden pa-0 ma-2", - rounded="lg", + flat=True, + classes="d-flex align-center px-2 py-1 mx-1", + style=merged_style, **kwargs, ) with self: @@ -145,55 +151,63 @@ def __init__(self, zoom=None, move=None, **kwargs): v2.VIcon("mdi-camera") style = dict(dense=True, hide_details=True) """ - style = dict( + btn_style = dict( icon=True, flat=True, outlined=False, density="compact", hide_details=True, - height="30px", - width="30px", + height="28px", + width="28px", + classes="ma-0", ) - with v2.VCardText(classes="pa-0", style="opacity: 80%"): + + with v2.VCardText(classes="pa-1", style="opacity: 85%"): with v2.VTooltip(bottom=True): with html.Template(v_slot_activator="{ on, attrs }"): with html.Div( v_bind="attrs", v_on="on", + classes="d-flex flex-column", + style="gap: 2px;", ): - with v2.VBtn( - **style, - click=(zoom, "['in']"), - ): - v2.VIcon("mdi-magnify-plus", large=True) - v2.VDivider(vertical=True) - with v2.VBtn( - **style, - click=(zoom, "['out']"), - ): - v2.VIcon("mdi-magnify-minus", large=True) - v2.VDivider(vertical=True) - with v2.VBtn( - **style, - click=(move, "['up']"), + # First row: Up, Left, Zoom In + with html.Div( + classes="d-flex justify-center", style="gap: 2px;" ): - v2.VIcon("mdi-arrow-up-thick", large=True) - v2.VDivider(vertical=True) - with v2.VBtn( - **style, - click=(move, "['down']"), - ): - v2.VIcon("mdi-arrow-down-thick", large=True) - v2.VDivider(vertical=True) - with v2.VBtn( - **style, - click=(move, "['left']"), - ): - v2.VIcon("mdi-arrow-left-thick", large=True) - v2.VDivider(vertical=True) - with v2.VBtn( - **style, - click=(move, "['right']"), + with v2.VBtn( + **btn_style, + click=(move, "['up']"), + ): + v2.VIcon("mdi-arrow-up-thick", size="18") + with v2.VBtn( + **btn_style, + click=(move, "['left']"), + ): + v2.VIcon("mdi-arrow-left-thick", size="18") + with v2.VBtn( + **btn_style, + click=(zoom, "['in']"), + ): + v2.VIcon("mdi-magnify-plus", size="18") + + # Second row: Down, Right, Zoom Out + with html.Div( + classes="d-flex justify-center", style="gap: 2px;" ): - v2.VIcon("mdi-arrow-right-thick", large=True) - html.Span("View Camera Controls") + with v2.VBtn( + **btn_style, + click=(move, "['down']"), + ): + v2.VIcon("mdi-arrow-down-thick", size="18") + with v2.VBtn( + **btn_style, + click=(move, "['right']"), + ): + v2.VIcon("mdi-arrow-right-thick", size="18") + with v2.VBtn( + **btn_style, + click=(zoom, "['out']"), + ): + v2.VIcon("mdi-magnify-minus", size="18") + html.Span("View Camera Controls", classes="text-caption mt-1") From d7c7f0ce754e6066473cf55d5f2b654e25bd9095 Mon Sep 17 00:00:00 2001 From: Abhishek Yenpure Date: Sun, 24 Aug 2025 10:44:12 -0700 Subject: [PATCH 2/6] fix: Moving busy icon to title --- quickview/interface.py | 12 +++++-- quickview/ui/toolbar.py | 71 ++++++++++++----------------------------- 2 files changed, 30 insertions(+), 53 deletions(-) diff --git a/quickview/interface.py b/quickview/interface.py index 12a325e..fc738cb 100644 --- a/quickview/interface.py +++ b/quickview/interface.py @@ -19,7 +19,6 @@ from quickview.pipeline import EAMVisSource -from quickview import __version__ as version from quickview.ui.slice_selection import SliceSelection from quickview.ui.projection_selection import ProjectionSelection from quickview.ui.variable_selection import VariableSelection @@ -712,9 +711,16 @@ def ui(self) -> SinglePageWithDrawerLayout: if self._ui is None: self._ui = SinglePageWithDrawerLayout(self.server) with self._ui as layout: - # layout.footer.clear() + layout.footer.clear() layout.title.clear() with layout.title: + v2.VProgressCircular( + bg_color="rgba(0,0,0,0)", + indeterminate=("trame__busy",), + color="primary", + width=3, + ) + """ with html.Div( style="display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 4px 8px;", ): @@ -728,7 +734,7 @@ def ui(self) -> SinglePageWithDrawerLayout: f"v{version}", style="font-size: 12px; color: rgba(0, 0, 0, 0.8); font-weight: 700; letter-spacing: 0.3px; line-height: 1;", ) - + """ with layout.toolbar as toolbar: Toolbar( toolbar, diff --git a/quickview/ui/toolbar.py b/quickview/ui/toolbar.py index 09834fa..36c37b4 100644 --- a/quickview/ui/toolbar.py +++ b/quickview/ui/toolbar.py @@ -220,7 +220,6 @@ def __init__( ): v2.VIcon("mdi-file-check") html.Span("Load Files") - """ with v2.VTooltip(bottom=True): with html.Template(v_slot_activator="{ on, attrs }"): with v2.VBtn( @@ -228,45 +227,13 @@ def __init__( dense=True, flat=True, small=True, - click=load_data, + click=self.export_state, v_bind="attrs", v_on="on", + classes="mx-1", ): - v2.VIcon("mdi-swap-horizontal") - html.Span("Replace Files") - """ - with v2.VTooltip(bottom=True): - with html.Template(v_slot_activator="{ on, attrs }"): - with v2.VBtn( - icon=True, - dense=True, - flat=True, - small=True, - v_bind="attrs", - v_on="on", - ): - v2.VIcon( - v_if="pipeline_valid", - children=["mdi-check-circle-outline"], - color="green", - ) - v2.VIcon( - v_if="!pipeline_valid", - children=["mdi-alert-circle-outline"], - color="red", - ) - with html.Div(v_if="pipeline_valid"): - html.Span("Pipeline Valid") - with html.Div(v_if="!pipeline_valid"): - html.Span("Pipeline Invalid") - - v2.VDivider(vertical=True, classes="mx-2") - # State management buttons group - with v2.VCard( - flat=True, - classes="d-flex align-center px-2 py-1 mx-1", - style="background-color: #f5f5f5; border-radius: 4px; flex-shrink: 0;", - ): + v2.VIcon("mdi-download") + html.Span("Save State") with v2.VTooltip(bottom=True): with html.Template(v_slot_activator="{ on, attrs }"): with v2.VBtn( @@ -274,13 +241,13 @@ def __init__( dense=True, flat=True, small=True, - click=self.export_state, + click=self.import_state, v_bind="attrs", v_on="on", classes="mx-1", ): - v2.VIcon("mdi-download") - html.Span("Save State") + v2.VIcon("mdi-upload") + html.Span("Load State") with v2.VTooltip(bottom=True): with html.Template(v_slot_activator="{ on, attrs }"): with v2.VBtn( @@ -288,19 +255,23 @@ def __init__( dense=True, flat=True, small=True, - click=self.import_state, v_bind="attrs", v_on="on", - classes="mx-1", ): - v2.VIcon("mdi-upload") - html.Span("Load State") - v2.VProgressCircular( - bg_color="rgba(0,0,0,0)", - indeterminate=("trame__busy",), - color="primary", - width=3, - ) + v2.VIcon( + v_if="pipeline_valid", + children=["mdi-check-circle-outline"], + color="green", + ) + v2.VIcon( + v_if="!pipeline_valid", + children=["mdi-alert-circle-outline"], + color="red", + ) + with html.Div(v_if="pipeline_valid"): + html.Span("Pipeline Valid") + with html.Div(v_if="!pipeline_valid"): + html.Span("Pipeline Invalid") v2.VDivider(vertical=True, classes="mx-2") ViewControls( zoom=zoom, From a904837c30beeb380d296f715848a7472f397f80 Mon Sep 17 00:00:00 2001 From: Abhishek Yenpure Date: Sun, 24 Aug 2025 10:58:01 -0700 Subject: [PATCH 3/6] fix: clear layout/registry by triggering pipeline invalid on state load --- quickview/interface.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/quickview/interface.py b/quickview/interface.py index fc738cb..338b7be 100644 --- a/quickview/interface.py +++ b/quickview/interface.py @@ -368,6 +368,7 @@ def generate_state(self): return to_export def load_state(self, state_file): + self.state.pipeline_valid = False from_state = json.loads(Path(state_file).read_text()) data_file = from_state["data_file"] conn_file = from_state["conn_file"] @@ -389,12 +390,14 @@ def load_state(self, state_file): "w": item.get("w", 4), "h": item.get("h", 3), } - self.source.Update( + is_valid = self.source.Update( data_file=data_file, conn_file=conn_file, ) - self.update_state_from_source() - self.update_state_from_config(from_state) + if is_valid: + self.update_state_from_source() + self.update_state_from_config(from_state) + self.state.pipeline_valid = is_valid def load_data(self): state = self.state From 8e3549a93b3dbc303ce6cdf0cf9156a9ea7fcb9c Mon Sep 17 00:00:00 2001 From: Abhishek Yenpure Date: Sun, 24 Aug 2025 16:14:56 -0700 Subject: [PATCH 4/6] Adding updates for state loading and cache preserving --- quickview/interface.py | 70 +++++++++++----------- quickview/ui/toolbar.py | 5 -- quickview/view_manager.py | 123 +++++++++----------------------------- 3 files changed, 63 insertions(+), 135 deletions(-) diff --git a/quickview/interface.py b/quickview/interface.py index 338b7be..2813eae 100644 --- a/quickview/interface.py +++ b/quickview/interface.py @@ -302,7 +302,7 @@ def update_state_from_source(self): def update_state_from_config(self, initstate): source = self.source self.state.update(initstate) - self.update_available_color_maps() + with self.state as state: state.surface_vars = source.surface_vars state.interface_vars = source.interface_vars @@ -314,7 +314,6 @@ def update_state_from_config(self, initstate): state.surface_vars_state = selection_surface state.midpoint_vars_state = selection_midpoint state.interface_vars_state = selection_interface - self.surface_vars_state = np.array(selection_surface) self.midpoint_vars_state = np.array(selection_midpoint) self.interface_vars_state = np.array(selection_interface) @@ -476,10 +475,11 @@ def load_variables(self, use_cached_layout=False): with self.state as state: state.variables = vars - # When loading from cached state, preserve existing color values - # Otherwise, initialize with defaults + # Initialize arrays that are always needed regardless of cache status + # Color configuration arrays will be populated by ViewContext via sync_color_config_to_state if not use_cached_layout: - state.varcolor = [self.get_default_colormap()] * len(vars) + # Initialize empty arrays - ViewContext will populate them through sync + state.varcolor = [""] * len(vars) state.uselogscale = [False] * len(vars) state.invert = [False] * len(vars) state.varmin = [np.nan] * len(vars) @@ -496,11 +496,9 @@ def load_variables(self, use_cached_layout=False): else 0 ) if current_len != len(vars): - # If array lengths don't match, extend with defaults or trim - default_colormap = self.get_default_colormap() - state.varcolor = (state.varcolor + [default_colormap] * len(vars))[ - : len(vars) - ] + # If array lengths don't match, extend with empty strings or trim + # ViewContext will populate correct values through sync + state.varcolor = (state.varcolor + [""] * len(vars))[: len(vars)] state.uselogscale = (state.uselogscale + [False] * len(vars))[ : len(vars) ] @@ -705,6 +703,9 @@ def clear_interface_vars(self, clear_var_name): self.interface_vars_state = np.array([False] * len(self.source.interface_vars)) self.state.dirty("interface_vars_state") + def close_view(self, index): + print("Requested close view for ", index) + def start(self, **kwargs): """Initialize the UI and start the server for GeoTrame.""" self.ui.server.start(**kwargs) @@ -839,51 +840,46 @@ def ui(self) -> SinglePageWithDrawerLayout: html.Div( style="position:absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1;" ) - # Top-left info: time and level info + # Top-left info: time, level, variable name and average with html.Div( style="position: absolute; top: 8px; left: 8px; padding: 4px 8px; background-color: rgba(255, 255, 255, 0.1); color: white; font-size: 0.875rem; border-radius: 4px; z-index: 2;", classes="drag-ignore font-monospace", ): - # Show time + # Variable name html.Div( - "t = {{ tstamp }}", + "{{ variables[idx] }}", style="color: white;", classes="font-weight-medium", ) - # Show level for midpoint variables + # Average value html.Div( - v_if="midpoint_vars.includes(variables[idx])", - children="k = {{ midpoint }}", + ( + "(avg: {{ " + "varaverage[idx] !== null && varaverage[idx] !== undefined && !isNaN(varaverage[idx]) && typeof varaverage[idx] === 'number' ? " + "varaverage[idx].toExponential(2) : " + "'N/A' " + "}})" + ), style="color: white;", classes="font-weight-medium", ) - # Show level for interface variables + # Show time html.Div( - v_if="interface_vars.includes(variables[idx])", - children="k = {{ interface }}", + "t = {{ tstamp }}", style="color: white;", classes="font-weight-medium", ) - # Top-right info: variable name and average - with html.Div( - style="position: absolute; top: 8px; right: 8px; padding: 4px 8px; background-color: rgba(255, 255, 255, 0.1); color: white; font-size: 0.875rem; border-radius: 4px; z-index: 2; text-align: right;", - classes="drag-ignore font-monospace", - ): - # Variable name + # Show level for midpoint variables html.Div( - "{{ variables[idx] }}", + v_if="midpoint_vars.includes(variables[idx])", + children="k = {{ midpoint }}", style="color: white;", classes="font-weight-medium", ) - # Average value + # Show level for interface variables html.Div( - ( - "(avg: {{ " - "varaverage[idx] !== null && varaverage[idx] !== undefined && !isNaN(varaverage[idx]) && typeof varaverage[idx] === 'number' ? " - "varaverage[idx].toExponential(2) : " - "'N/A' " - "}})" - ), + v_if="interface_vars.includes(variables[idx])", + children="k = {{ interface }}", style="color: white;", classes="font-weight-medium", ) @@ -973,5 +969,11 @@ def ui(self) -> SinglePageWithDrawerLayout: style="color: white;", classes="font-weight-medium", ) + # with v2.VBtn( + # icon=True, + # style="position: absolute; top: 8px; right: 8px; padding: 4px 8px; z-index: 2; color: white;", + # click=(self.close_view, "[idx]"), + # ): + # v2.VIcon("mdi-close") return self._ui diff --git a/quickview/ui/toolbar.py b/quickview/ui/toolbar.py index 36c37b4..863137f 100644 --- a/quickview/ui/toolbar.py +++ b/quickview/ui/toolbar.py @@ -106,11 +106,6 @@ def __init__( self._load_state = load_state self._update_available_color_maps = update_available_color_maps - # Initialize toggle states - with self.state: - self.state.use_cvd_colors = False - self.state.use_standard_colors = True - # Set initial color maps based on default toggle states self._update_color_maps() diff --git a/quickview/view_manager.py b/quickview/view_manager.py index b4a7c7e..7b1b3ce 100644 --- a/quickview/view_manager.py +++ b/quickview/view_manager.py @@ -201,6 +201,14 @@ def __init__(self, source: EAMVisSource, server, state): # Register state change listener for pipeline_valid self.state.change("pipeline_valid")(self._on_pipeline_valid_change) + def get_default_colormap(self): + """Get default colormap from interface or fallback""" + # Try to get from the server's interface instance + if self.state.use_cvd_colors: + return "batlow" + # Fallback to a reasonable default + return "Cool to Warm (Extended)" + def _on_pipeline_valid_change(self, pipeline_valid, **kwargs): """Clear view registry when pipeline becomes invalid.""" if not pipeline_valid: @@ -477,114 +485,37 @@ def rebuild_visualization_layout(self, cached_layout=None): view.BackgroundColorMode = "Gradient" view.GetRenderWindow().SetOffScreenRendering(True) context.state.view_proxy = view - # Use loaded color range if override is enabled and values are valid - if ( - index < len(state.override_range) - and state.override_range[index] - and index < len(state.varmin) - and index < len(state.varmax) - and not ( - state.varmin[index] != state.varmin[index] - ) # Check for NaN - and not (state.varmax[index] != state.varmax[index]) - ): # Check for NaN - context.config.min_value = state.varmin[index] - context.config.max_value = state.varmax[index] - context.config.override_range = True - else: + # First time creating view for this context + # Context already has its configuration from previous sessions + # Just update range if not overridden (critical requirement) + if not context.config.override_range: context.config.min_value = varrange[0] context.config.max_value = varrange[1] self.configure_new_view(var, context, self.source.views) else: - # Update context with all loaded color settings - # Update colormap if available - if index < len(state.varcolor): - context.config.colormap = state.varcolor[index] - # Update log scale setting if available - if index < len(state.uselogscale): - context.config.use_log_scale = state.uselogscale[index] - # Update invert colors setting if available - if index < len(state.invert): - context.config.invert_colors = state.invert[index] - - # Update color range if override is enabled and values are valid - if ( - index < len(state.override_range) - and state.override_range[index] - and index < len(state.varmin) - and index < len(state.varmax) - and not ( - state.varmin[index] != state.varmin[index] - ) # Check for NaN - and not (state.varmax[index] != state.varmax[index]) - ): # Check for NaN - context.config.min_value = state.varmin[index] - context.config.max_value = state.varmax[index] - context.config.override_range = True - - # Apply all the loaded color settings to the transfer function - coltrfunc = GetColorTransferFunction(var) - # Apply colormap - coltrfunc.ApplyPreset(context.config.colormap, True) - # Apply log scale - if context.config.use_log_scale: - coltrfunc.MapControlPointsToLogSpace() - coltrfunc.UseLogScale = 1 - else: - coltrfunc.UseLogScale = 0 - # Apply invert colors - if context.config.invert_colors: - coltrfunc.InvertTransferFunction() - # Apply color range if overridden - if context.config.override_range: - coltrfunc.RescaleTransferFunction( - context.config.min_value, context.config.max_value - ) + # Trust the ViewContext - it's already configured + # Only update the color range if not overridden (critical requirement) + if not context.config.override_range: + context.config.min_value = varrange[0] + context.config.max_value = varrange[1] + # Only refresh the display, don't change configuration self.refresh_view_display(context) else: + # Creating a completely new ViewContext view = CreateRenderView() - # Preserve override flag if context already exists - existing_context = self.registry.get_view(var) - override = ( - existing_context.config.override_range - if existing_context - else ( - index < len(state.override_range) - and state.override_range[index] - ) - ) - # Use loaded color range if override is enabled and values are valid - if ( - override - and index < len(state.varmin) - and index < len(state.varmax) - and not ( - state.varmin[index] != state.varmin[index] - ) # Check for NaN - and not (state.varmax[index] != state.varmax[index]) - ): # Check for NaN - min_val = state.varmin[index] - max_val = state.varmax[index] - else: - min_val = varrange[0] - max_val = varrange[1] + # Use defaults for new variables + default_colormap = self.get_default_colormap() config = ViewConfiguration( variable=var, - colormap=state.varcolor[index] - if index < len(state.varcolor) - else state.varcolor[0], - use_log_scale=state.uselogscale[index] - if index < len(state.uselogscale) - else False, - invert_colors=state.invert[index] - if index < len(state.invert) - else False, - min_value=min_val, - max_value=max_val, - override_range=override, + colormap=default_colormap, + use_log_scale=False, # Default + invert_colors=False, # Default + min_value=varrange[0], # Always use current data range + max_value=varrange[1], + override_range=False, # Default to auto-range ) view_state = ViewState( view_proxy=view, From d344235b7d8adc6122e40192d3bff8673ba605b5 Mon Sep 17 00:00:00 2001 From: Abhishek Yenpure Date: Sun, 24 Aug 2025 16:27:29 -0700 Subject: [PATCH 5/6] fix: progress icon resize disable --- quickview/interface.py | 36 +++++++++++++++--------------------- quickview/ui/toolbar.py | 9 +++++++++ 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/quickview/interface.py b/quickview/interface.py index 2813eae..f22b383 100644 --- a/quickview/interface.py +++ b/quickview/interface.py @@ -314,6 +314,7 @@ def update_state_from_config(self, initstate): state.surface_vars_state = selection_surface state.midpoint_vars_state = selection_midpoint state.interface_vars_state = selection_interface + self.update_available_color_maps() self.surface_vars_state = np.array(selection_surface) self.midpoint_vars_state = np.array(selection_midpoint) self.interface_vars_state = np.array(selection_interface) @@ -717,28 +718,21 @@ def ui(self) -> SinglePageWithDrawerLayout: with self._ui as layout: layout.footer.clear() layout.title.clear() - with layout.title: - v2.VProgressCircular( - bg_color="rgba(0,0,0,0)", - indeterminate=("trame__busy",), - color="primary", - width=3, + """ + with html.Div( + style="display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 4px 8px;", + ): + ( + html.Img( + src=f"data:image/png;base64,{LOGO_BASE64}", + style="height: 30px; width: 60px; border-radius: 4px; margin-bottom: 2px;", + ), ) - """ - with html.Div( - style="display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 4px 8px;", - ): - ( - html.Img( - src=f"data:image/png;base64,{LOGO_BASE64}", - style="height: 30px; width: 60px; border-radius: 4px; margin-bottom: 2px;", - ), - ) - html.Span( - f"v{version}", - style="font-size: 12px; color: rgba(0, 0, 0, 0.8); font-weight: 700; letter-spacing: 0.3px; line-height: 1;", - ) - """ + html.Span( + f"v{version}", + style="font-size: 12px; color: rgba(0, 0, 0, 0.8); font-weight: 700; letter-spacing: 0.3px; line-height: 1;", + ) + """ with layout.toolbar as toolbar: Toolbar( toolbar, diff --git a/quickview/ui/toolbar.py b/quickview/ui/toolbar.py index 863137f..40e0e5e 100644 --- a/quickview/ui/toolbar.py +++ b/quickview/ui/toolbar.py @@ -112,6 +112,15 @@ def __init__( with layout_toolbar as toolbar: toolbar.density = "compact" toolbar.style = "overflow-x: auto; overflow-y: hidden;" + with html.Div( + style="min-width: 32px; flex-shrink: 0; display: flex; align-items: center; justify-content: center;" + ): + v2.VProgressCircular( + bg_color="rgba(0,0,0,0)", + indeterminate=("trame__busy",), + color="primary", + size=24, + ) v2.VDivider(vertical=True, classes="mx-2") v2.VBtn( "Load Variables", From 13a678c3e109711c53c9ecee83146e26237f55b2 Mon Sep 17 00:00:00 2001 From: Abhishek Yenpure Date: Sun, 24 Aug 2025 16:59:13 -0700 Subject: [PATCH 6/6] =?UTF-8?q?Bump=20version:=200.1.19=20=E2=86=92=200.1.?= =?UTF-8?q?20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- pyproject.toml | 2 +- quickview/__init__.py | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 728af5b..972bc1c 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.1.19 +current_version = 0.1.20 commit = True tag = True diff --git a/pyproject.toml b/pyproject.toml index c81fbf0..ee08e13 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "quickview" -version = "0.1.19" +version = "0.1.20" description = "An application to explore/analyze data for atmosphere component for E3SM" authors = [ {name = "Kitware Inc."}, diff --git a/quickview/__init__.py b/quickview/__init__.py index 80a133e..59db7a3 100644 --- a/quickview/__init__.py +++ b/quickview/__init__.py @@ -1,5 +1,5 @@ """QuickView: Visual Analysis for E3SM Atmosphere Data.""" -__version__ = "0.1.19" +__version__ = "0.1.20" __author__ = "Kitware Inc." __license__ = "Apache-2.0" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index fa96a91..dbb3d94 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "app" -version = "0.1.19" +version = "0.1.20" description = "QuickView: Visual Analyis for E3SM Atmosphere Data" authors = ["Kitware"] license = "" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 358f3f9..df49b04 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -7,7 +7,7 @@ }, "package": { "productName": "QuickView", - "version": "0.1.19" + "version": "0.1.20" }, "tauri": { "allowlist": {