Skip to content

Commit

Permalink
Merge pull request #196 from overengineer/fix/resetting_selected_bran…
Browse files Browse the repository at this point in the history
…ch_workaround

Recover branch selection
  • Loading branch information
JR-Morgan authored Jun 5, 2024
2 parents 7431b57 + 669fd19 commit 230e27a
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 7 deletions.
4 changes: 3 additions & 1 deletion bpy_speckle/operators/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from bpy.types import Context
from bpy_speckle.functions import _report
from bpy_speckle.clients import speckle_clients
from bpy_speckle.properties.scene import SpeckleBranchObject, SpeckleCommitObject, SpeckleSceneSettings, SpeckleStreamObject, SpeckleUserObject, get_speckle
from bpy_speckle.properties.scene import SpeckleBranchObject, SpeckleCommitObject, SpeckleSceneSettings, SpeckleStreamObject, SpeckleUserObject, get_speckle, restore_selection_state
from specklepy.core.api.client import SpeckleClient
from specklepy.core.api.models import Stream
from specklepy.core.api.credentials import get_local_accounts, Account
Expand Down Expand Up @@ -202,6 +202,8 @@ def load_user_stream(self, context: Context) -> None:
sstream = client.stream.get(id=s.id, branch_limit=self.branch_limit, commit_limit=10)
add_user_stream(user, sstream)

restore_selection_state(speckle)

bpy.context.view_layer.update()

if context.area:
Expand Down
75 changes: 69 additions & 6 deletions bpy_speckle/properties/scene.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""
Scene properties
"""
from typing import Iterable, Optional, Tuple, cast
from typing import Iterable, Optional, Tuple, Union, cast
from dataclasses import dataclass
import bpy
from bpy.props import (
StringProperty,
Expand Down Expand Up @@ -35,6 +36,9 @@ def get_commits(self, context):
]
return [("0", "<none>", "<none>", 0)]

def commit_update_hook(self, context: bpy.types.Context):
selection_state.selected_commit_id = SelectionState.get_item_id_by_index(self.commits, self.commit)

name: StringProperty(default="main") # type: ignore
id: StringProperty(default="") # type: ignore
description: StringProperty(default="") # type: ignore
Expand All @@ -43,15 +47,15 @@ def get_commits(self, context):
name="Version",
description="Selected model version",
items=get_commits,
update=commit_update_hook,
) # type: ignore

def get_active_commit(self) -> Optional[SpeckleCommitObject]:
selected_index = int(self.commit)
if 0 <= selected_index < len(self.commits):
return self.commits[selected_index]
return None



class SpeckleStreamObject(bpy.types.PropertyGroup):
def get_branches(self, context):
if self.branches:
Expand All @@ -62,6 +66,9 @@ def get_branches(self, context):
if branch.name != "globals"
]
return [("0", "<none>", "<none>", 0)]

def branch_update_hook(self, context: bpy.types.Context):
selection_state.selected_branch_id = SelectionState.get_item_id_by_index(self.branches, self.branch)

name: StringProperty(default="") # type: ignore
description: StringProperty(default="") # type: ignore
Expand All @@ -71,6 +78,7 @@ def get_branches(self, context):
name="Model",
description="Selected Model",
items=get_branches,
update=branch_update_hook,
) # type: ignore

def get_active_branch(self) -> Optional[SpeckleBranchObject]:
Expand All @@ -79,22 +87,25 @@ def get_active_branch(self) -> Optional[SpeckleBranchObject]:
return self.branches[selected_index]
return None


class SpeckleUserObject(bpy.types.PropertyGroup):
def stream_update_hook(self, context: bpy.types.Context):
selection_state.selected_stream_id = SelectionState.get_item_id_by_index(self.streams, self.active_stream)

server_name: StringProperty(default="SpeckleXYZ") # type: ignore
server_url: StringProperty(default="https://speckle.xyz") # type: ignore
id: StringProperty(default="") # type: ignore
name: StringProperty(default="Speckle User") # type: ignore
email: StringProperty(default="user@speckle.xyz") # type: ignore
company: StringProperty(default="SpeckleSystems") # type: ignore
streams: CollectionProperty(type=SpeckleStreamObject) # type: ignore
active_stream: IntProperty(default=0) # type: ignore
active_stream: IntProperty(default=0, update=stream_update_hook) # type: ignore

def get_active_stream(self) -> Optional[SpeckleStreamObject]:
selected_index = int(self.active_stream)
if 0 <= selected_index < len(self.streams):
return self.streams[selected_index]
return None


class SpeckleSceneSettings(bpy.types.PropertyGroup):
def get_scripts(self, context):
Expand All @@ -120,6 +131,7 @@ def get_users(self, context):

def set_user(self, context):
bpy.ops.speckle.load_user_streams() # type: ignore
selection_state.selected_user_id = SelectionState.get_item_id_by_index(self.users, self.active_user)

active_user: EnumProperty(
items=get_users,
Expand Down Expand Up @@ -153,6 +165,8 @@ def set_user(self, context):
) # type: ignore

def get_active_user(self) -> Optional[SpeckleUserObject]:
if not self.active_user:
return None
selected_index = int(self.active_user)
if 0 <= selected_index < len(self.users):
return self.users[selected_index]
Expand Down Expand Up @@ -197,4 +211,53 @@ def get_speckle(context: bpy.types.Context) -> SpeckleSceneSettings:
"""
Gets the speckle scene object
"""
return context.scene.speckle #type: ignore
return context.scene.speckle #type: ignore

@dataclass
class SelectionState:
selected_user_id : Optional[str] = None
selected_stream_id : Optional[str] = None
selected_branch_id : Optional[str] = None
selected_commit_id : Optional[str] = None

@staticmethod
def get_item_id_by_index(collection: bpy.types.PropertyGroup, index: Union[str, int]) -> Optional[str]:
# print(list(collection.items()))
selected_index = int(index)
for index, (_, item) in enumerate(collection.items()):
if index == selected_index:
return item.id
return None

@staticmethod
def get_item_index_by_id(collection: Iterable[SpeckleCommitObject], id: Optional[str]) -> Optional[str]:
for index, item in enumerate(collection):
if item.id == id:
return str(index)
return None

selection_state = SelectionState()

def restore_selection_state(speckle: SpeckleSceneSettings) -> None:
# Restore branch selection state
if selection_state.selected_branch_id != None:
(active_user, active_stream) = speckle.validate_stream_selection()

is_same_user = active_user.id == selection_state.selected_user_id
is_same_stream = active_stream.id == selection_state.selected_stream_id

if is_same_user and is_same_stream:
if branch := SelectionState.get_item_index_by_id(active_stream.branches, selection_state.selected_branch_id):
active_stream.branch = branch

# Restore commit selection state
if selection_state.selected_commit_id != None:
(active_user, active_stream, active_branch) = speckle.validate_branch_selection()

is_same_user = active_user.id == selection_state.selected_user_id
is_same_stream = active_stream.id == selection_state.selected_stream_id
is_same_branch = active_branch.id == selection_state.selected_branch_id

if is_same_user and is_same_stream and is_same_branch:
if commit := SelectionState.get_item_index_by_id(active_branch.commits, selection_state.selected_commit_id):
active_branch.commit = commit

0 comments on commit 230e27a

Please sign in to comment.