Skip to content

Commit

Permalink
Minor Options Revamp (#86)
Browse files Browse the repository at this point in the history
* change the way options are displayed

* make Options.Field abstract, make relevant options generics

* add option reprs
  • Loading branch information
apple1417 authored Feb 27, 2021
1 parent 2c3cd47 commit f8bc5f7
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 40 deletions.
22 changes: 16 additions & 6 deletions Mods/ModMenu/OptionManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@
_MOD_OPTIONS_EVENT_ID: int = 1417
_MOD_OPTIONS_MENU_NAME: str = "MODS"

_INDENT: int = 2


class _ModHeader(Options.Field):
def __init__(self, Caption: str) -> None:
self.Caption = Caption
self.Description = ""
self.IsHidden = False


def _create_data_provider(name: str) -> unrealsdk.UObject:
"""
Expand Down Expand Up @@ -149,15 +158,18 @@ def _DataProviderOptionsBasePopulate(caller: unrealsdk.UObject, function: unreal
continue
if not one_shown:
one_shown = True
all_options.append(Options.Field(mod.Name))
all_options.append(_ModHeader(mod.Name))
all_options.append(option)

_nested_options_stack.append(Options.Nested(_MOD_OPTIONS_MENU_NAME, "", all_options))

first_level = len(_nested_options_stack) == 1
for idx, option in enumerate(_nested_options_stack[-1].Children):
if option.IsHidden:
continue

indent = " " * _INDENT if first_level and not isinstance(option, _ModHeader) else ""

if isinstance(option, Options.Spinner):
spinner_idx: int
if isinstance(option, Options.Boolean):
Expand All @@ -166,12 +178,12 @@ def _DataProviderOptionsBasePopulate(caller: unrealsdk.UObject, function: unreal
spinner_idx = option.Choices.index(option.CurrentValue)

params.TheList.AddSpinnerListItem(
idx, option.Caption, False, spinner_idx, option.Choices
idx, indent + option.Caption, False, spinner_idx, option.Choices
)
elif isinstance(option, Options.Slider):
params.TheList.AddSliderListItem(
idx,
option.Caption,
indent + option.Caption,
False,
option.CurrentValue,
option.MinValue,
Expand All @@ -180,11 +192,9 @@ def _DataProviderOptionsBasePopulate(caller: unrealsdk.UObject, function: unreal
)
elif isinstance(option, Options.Field):
disabled = False
new = False
if isinstance(option, Options.Nested):
disabled = not _is_anything_shown(option.Children)
new = True
params.TheList.AddListItem(idx, option.Caption, disabled, new)
params.TheList.AddListItem(idx, indent + option.Caption, disabled, False)

caller.AddDescription(idx, option.Description)

Expand Down
112 changes: 78 additions & 34 deletions Mods/ModMenu/Options.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from abc import ABC, abstractmethod
from typing import Any, Optional, Sequence, Tuple
from reprlib import recursive_repr
from typing import Any, Generic, Optional, Sequence, Tuple, TypeVar

from . import DeprecationHelper as dh

Expand All @@ -14,6 +15,8 @@
"Value",
)

T = TypeVar("T")


class Base(ABC):
"""
Expand All @@ -39,7 +42,7 @@ def __init__(
raise NotImplementedError


class Value(Base):
class Value(Base, Generic[T]):
"""
The abstract base class for all options that store a value.
Expand All @@ -52,22 +55,22 @@ class Value(Base):
IsHidden: If the option is hidden from the options menu.
"""
CurrentValue: Any
StartingValue: Any
CurrentValue: T
StartingValue: T

@abstractmethod
def __init__(
self,
Caption: str,
Description: str,
StartingValue: Any,
StartingValue: T,
*,
IsHidden: bool = True
) -> None:
raise NotImplementedError


class Hidden(Value):
class Hidden(Value[T]):
"""
A hidden option that never displays in the menu but stores an arbitrary (json serializable)
value to the settings file.
Expand All @@ -81,11 +84,12 @@ class Hidden(Value):
StartingValue: The default value of the option.
IsHidden: If the option is hidden from the options menu. This is forced to True.
"""

def __init__(
self,
Caption: str,
Description: str = "",
StartingValue: Any = None,
StartingValue: T = None, # type: ignore
*,
IsHidden: bool = True
) -> None:
Expand Down Expand Up @@ -116,8 +120,18 @@ def IsHidden(self) -> bool: # type: ignore
def IsHidden(self, val: bool) -> None:
pass

@recursive_repr()
def __repr__(self) -> str:
return (
f"Hidden("
f"Caption={repr(self.Caption)},"
f"Description={repr(self.Description)},"
f"*,IsHidden={repr(self.IsHidden)}"
f")"
)

class Slider(Value):

class Slider(Value[int]):
"""
An option which allows users to select a value along a slider.
Expand Down Expand Up @@ -176,8 +190,23 @@ def __init__(
self.Increment = Increment
self.IsHidden = IsHidden


class Spinner(Value):
@recursive_repr()
def __repr__(self) -> str:
return (
f"Slider("
f"Caption={repr(self.Caption)},"
f"Description={repr(self.Description)},"
f"CurrentValue={repr(self.CurrentValue)},"
f"StartingValue={repr(self.StartingValue)},"
f"MinValue={repr(self.MinValue)},"
f"MaxValue={repr(self.MaxValue)},"
f"Increment={repr(self.Increment)},"
f"*,IsHidden={repr(self.IsHidden)}"
f")"
)


class Spinner(Value[str]):
"""
An option which allows users to select one value from a sequence of strings.
Expand Down Expand Up @@ -242,8 +271,21 @@ def __init__(
f"Provided starting value '{self.StartingValue}' is not in the list of choices."
)


class Boolean(Spinner):
@recursive_repr()
def __repr__(self) -> str:
return (
f"Spinner("
f"Caption={repr(self.Caption)},"
f"Description={repr(self.Description)},"
f"CurrentValue={repr(self.CurrentValue)},"
f"StartingValue={repr(self.StartingValue)},"
f"Choices={repr(self.Choices)},"
f"*,IsHidden={repr(self.IsHidden)}"
f")"
)


class Boolean(Spinner, Value[bool]):
"""
A special form of a spinner, with two options representing boolean values.
Expand Down Expand Up @@ -309,6 +351,19 @@ def CurrentValue(self, val: Any) -> None:
else:
self._current_value = bool(val)

@recursive_repr()
def __repr__(self) -> str:
return (
f"Boolean("
f"Caption={repr(self.Caption)},"
f"Description={repr(self.Description)},"
f"CurrentValue={repr(self.CurrentValue)},"
f"StartingValue={repr(self.StartingValue)},"
f"Choices={repr(self.Choices)},"
f"*,IsHidden={repr(self.IsHidden)}"
f")"
)


class Field(Base):
"""
Expand All @@ -320,33 +375,11 @@ class Field(Base):
IsHidden: If the field is hidden from the options menu.
"""

def __init__(
self,
Caption: str,
Description: str = "",
*,
IsHidden: bool = False
) -> None:
"""
Creates the option.
Args:
Caption: The name of the option.
Description: A short description of the option to show when hovering over it in the menu.
IsHidden (keyword only): If the value is hidden from the options menu.
"""
self.Caption = Caption
self.Description = Description
self.IsHidden = IsHidden


class Nested(Field):
"""
A field which when clicked opens up a nested menu with more options.
These are distinguished from normal fields by having the "new" exclaimation mark to the side of
it, but you should probably still give it a meaningful description.
Note that these fields will be disabled if all child options are either hidden or other disabled
nested fields.
Expand Down Expand Up @@ -383,3 +416,14 @@ def __init__(
self.Description = Description
self.Children = Children
self.IsHidden = IsHidden

@recursive_repr()
def __repr__(self) -> str:
return (
f"Nested("
f"Caption={repr(self.Caption)},"
f"Description={repr(self.Description)},"
f"Children={repr(self.Children)},"
f"*,IsHidden={repr(self.IsHidden)}"
f")"
)

0 comments on commit f8bc5f7

Please sign in to comment.