mirror of
https://github.com/H-uru/korman.git
synced 2025-07-14 22:36:52 +00:00
Basic age/page UI controls
We are attempting to encourage the pages=layers paradigm; however, this is not strictly enforced. This commit has lots of bits and bobs but little actual substance. More to come when I begin work on the exporter.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
*.py[co]
|
*.py[co]
|
||||||
|
__pycache__
|
||||||
|
|
||||||
# Packages
|
# Packages
|
||||||
*.egg
|
*.egg
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from . import exporter, render
|
from . import exporter, render
|
||||||
|
from . import operators, properties, ui
|
||||||
|
|
||||||
bl_info = {
|
bl_info = {
|
||||||
"name": "Korman",
|
"name": "Korman",
|
||||||
@ -31,9 +32,12 @@ def register():
|
|||||||
"""Registers all Blender operators and GUI items in Korman"""
|
"""Registers all Blender operators and GUI items in Korman"""
|
||||||
|
|
||||||
# This will auto-magically register all blender classes for us
|
# This will auto-magically register all blender classes for us
|
||||||
# We will define a lot of them, methinks...
|
|
||||||
bpy.utils.register_module(__name__)
|
bpy.utils.register_module(__name__)
|
||||||
|
|
||||||
|
# We have to setup pointer props to our custom property groups ourselves,
|
||||||
|
# so let's go ahead and do that now.
|
||||||
|
properties.register()
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
"""Unregisters all Blender operators and GUI items"""
|
"""Unregisters all Blender operators and GUI items"""
|
||||||
bpy.utils.unregister_module(__name__)
|
bpy.utils.unregister_module(__name__)
|
||||||
|
@ -37,7 +37,8 @@ class PlasmaExporter(bpy.types.Operator):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
return context.object is not None
|
if context.object is not None:
|
||||||
|
return context.scene.render.engine == "PLASMA_GAME"
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
# TODO
|
# TODO
|
||||||
@ -54,4 +55,5 @@ class PlasmaExporter(bpy.types.Operator):
|
|||||||
def menu_cb(self, context):
|
def menu_cb(self, context):
|
||||||
self.layout.operator_context = "INVOKE_DEFAULT"
|
self.layout.operator_context = "INVOKE_DEFAULT"
|
||||||
self.layout.operator(PlasmaExporter.bl_idname, text="Plasma Age (.age)")
|
self.layout.operator(PlasmaExporter.bl_idname, text="Plasma Age (.age)")
|
||||||
bpy.types.INFO_MT_file_export.append(menu_cb)
|
def register():
|
||||||
|
bpy.types.INFO_MT_file_export.append(menu_cb)
|
||||||
|
16
korman/operators/__init__.py
Normal file
16
korman/operators/__init__.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# This file is part of Korman.
|
||||||
|
#
|
||||||
|
# Korman is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Korman is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from .op_world import *
|
72
korman/operators/op_world.py
Normal file
72
korman/operators/op_world.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
# This file is part of Korman.
|
||||||
|
#
|
||||||
|
# Korman is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Korman is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
class AgeOperator:
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return context.scene.render.engine == "PLASMA_GAME"
|
||||||
|
|
||||||
|
class PlasmaPageAddOperator(AgeOperator, bpy.types.Operator):
|
||||||
|
bl_idname = "world.plasma_page_add"
|
||||||
|
bl_label = "Add Page"
|
||||||
|
bl_description = "Adds a new Plasma Registry Page"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
w = context.world
|
||||||
|
if w:
|
||||||
|
age = w.plasma_age
|
||||||
|
page = age.pages.add()
|
||||||
|
|
||||||
|
# Find the first non-zero ID and suggest that.
|
||||||
|
suffixes = []
|
||||||
|
for p in age.pages:
|
||||||
|
# Filter out pages with no-id or
|
||||||
|
if p.seq_suffix:
|
||||||
|
suffixes.append(p.seq_suffix)
|
||||||
|
if len(suffixes):
|
||||||
|
suffixes.sort()
|
||||||
|
test = set(range(suffixes[0], suffixes[-1]))
|
||||||
|
missing = test - set(suffixes)
|
||||||
|
try:
|
||||||
|
suffix = missing.pop()
|
||||||
|
except KeyError:
|
||||||
|
suffix = suffixes[-1] + 1
|
||||||
|
page.make_default_name(suffix)
|
||||||
|
else:
|
||||||
|
# Page 0 is a magic "catch-all" page. The user *may* define it
|
||||||
|
# if he wants. If he doesn't, we'll defer it until export time
|
||||||
|
page.make_default_name(1)
|
||||||
|
|
||||||
|
# Finally, select the new page
|
||||||
|
age.active_page_index = len(age.pages) - 1
|
||||||
|
return {"FINISHED"}
|
||||||
|
else:
|
||||||
|
return {"CANCELLED"}
|
||||||
|
|
||||||
|
|
||||||
|
class PlasmaPageRemoveOperator(AgeOperator, bpy.types.Operator):
|
||||||
|
bl_idname = "world.plasma_page_remove"
|
||||||
|
bl_label = "Remove Page"
|
||||||
|
bl_description = "Removes the selected Plasma Registry Page"
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
w = context.world
|
||||||
|
if w:
|
||||||
|
# ...
|
||||||
|
return {"FINISHED"}
|
||||||
|
else:
|
||||||
|
return {"CANCELLED"}
|
24
korman/properties/__init__.py
Normal file
24
korman/properties/__init__.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# This file is part of Korman.
|
||||||
|
#
|
||||||
|
# Korman is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Korman is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
from .prop_object import *
|
||||||
|
from .prop_world import *
|
||||||
|
|
||||||
|
def register():
|
||||||
|
bpy.types.Object.plasma_object = PointerProperty(type=PlasmaObject)
|
||||||
|
bpy.types.World.plasma_age = PointerProperty(type=PlasmaAge)
|
||||||
|
bpy.types.World.plasma_fni = PointerProperty(type=PlasmaFni)
|
51
korman/properties/prop_object.py
Normal file
51
korman/properties/prop_object.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# This file is part of Korman.
|
||||||
|
#
|
||||||
|
# Korman is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Korman is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
from bpy.props import *
|
||||||
|
|
||||||
|
class PlasmaObject(bpy.types.PropertyGroup):
|
||||||
|
def _export_changed(self, context):
|
||||||
|
# This makes me sad
|
||||||
|
if not self.is_inited:
|
||||||
|
self._init(context)
|
||||||
|
self.is_inited = True
|
||||||
|
|
||||||
|
def _init(self, context):
|
||||||
|
o = context.object
|
||||||
|
age = context.scene.world.plasma_age
|
||||||
|
|
||||||
|
# We want to encourage the pages = layers paradigm.
|
||||||
|
# So, let's see which layers we're on and check for a page whose
|
||||||
|
# suffix matches our layers. We'll take the first match.
|
||||||
|
num_layers = len(o.layers)
|
||||||
|
for page in age.pages:
|
||||||
|
if page.seq_suffix > num_layers:
|
||||||
|
continue
|
||||||
|
if o.layers[page.seq_suffix-1]:
|
||||||
|
o.plasma_object.page = page.name
|
||||||
|
break
|
||||||
|
|
||||||
|
export = BoolProperty(name="Export",
|
||||||
|
description="Export this as a discrete object",
|
||||||
|
default=False,
|
||||||
|
update=_export_changed)
|
||||||
|
page = StringProperty(name="Page",
|
||||||
|
description="Page this object will be exported to")
|
||||||
|
|
||||||
|
# Implementation Details
|
||||||
|
is_inited = BoolProperty(description="INTERNAL: Init proc complete",
|
||||||
|
default=False,
|
||||||
|
options={"HIDDEN"})
|
114
korman/properties/prop_world.py
Normal file
114
korman/properties/prop_world.py
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
# This file is part of Korman.
|
||||||
|
#
|
||||||
|
# Korman is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Korman is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
from bpy.props import *
|
||||||
|
|
||||||
|
class PlasmaFni(bpy.types.PropertyGroup):
|
||||||
|
bl_idname = "world.plasma_fni"
|
||||||
|
|
||||||
|
fog_color = FloatVectorProperty(name="Fog Color",
|
||||||
|
description="The default fog color used in your age",
|
||||||
|
default=(0.3, 0.2, 0.05),
|
||||||
|
subtype="COLOR")
|
||||||
|
clear_color = FloatVectorProperty(name="Clear Color",
|
||||||
|
description="The default background color rendered in your age",
|
||||||
|
subtype="COLOR")
|
||||||
|
yon = IntProperty(name="Draw Distance",
|
||||||
|
description="The distance (in feet) Plasma will draw",
|
||||||
|
default=100000,
|
||||||
|
soft_min=100,
|
||||||
|
min=1)
|
||||||
|
# TODO: density
|
||||||
|
|
||||||
|
class PlasmaPage(bpy.types.PropertyGroup):
|
||||||
|
def _check_suffix(self, context):
|
||||||
|
"""Verifies that a suffix change does not conflict"""
|
||||||
|
old = self.last_seq_suffix
|
||||||
|
self.last_seq_suffix = self.seq_suffix
|
||||||
|
if not self.check_suffixes:
|
||||||
|
return None
|
||||||
|
|
||||||
|
for page in context.world.plasma_age.pages:
|
||||||
|
if page.seq_suffix == self.seq_suffix:
|
||||||
|
# Need to supress checking while we override the suffix
|
||||||
|
page.check_suffixes = False
|
||||||
|
page.seq_suffix = old
|
||||||
|
page.check_suffixes = True
|
||||||
|
break
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _rename_page(self, context):
|
||||||
|
# Need to init?
|
||||||
|
if self.last_name == "" and self.name:
|
||||||
|
self.last_name = self.name
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Empty page names not allowed!
|
||||||
|
if self.name == "":
|
||||||
|
self.make_default_name(self.seq_suffix)
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Since many objects will have page names attached to them, we'll be
|
||||||
|
# very nice and handle renames for the user.
|
||||||
|
for obj in bpy.data.objects:
|
||||||
|
if obj.plasma_object.page == self.last_name:
|
||||||
|
obj.plasma_object.page = self.name
|
||||||
|
self.last_name = self.name
|
||||||
|
return None
|
||||||
|
|
||||||
|
def make_default_name(self, suffix):
|
||||||
|
self.seq_suffix = suffix
|
||||||
|
self.name = "Page%02i" % suffix
|
||||||
|
self.check_suffixes = True
|
||||||
|
|
||||||
|
name = StringProperty(name="Name",
|
||||||
|
description="Name of the specified page",
|
||||||
|
update=_rename_page)
|
||||||
|
seq_suffix = IntProperty(name="ID",
|
||||||
|
description="A numerical ID for this page",
|
||||||
|
soft_min=0, # Negatives indicate global--advanced users only
|
||||||
|
default=0, # The add operator will autogen a default
|
||||||
|
update=_check_suffix)
|
||||||
|
auto_load = BoolProperty(name="Auto Load",
|
||||||
|
description="Load this page on link-in",
|
||||||
|
default=True)
|
||||||
|
|
||||||
|
# Implementation details...
|
||||||
|
last_name = StringProperty(description="INTERNAL: Cached page name",
|
||||||
|
options={"HIDDEN"})
|
||||||
|
last_seq_suffix = IntProperty(description="INTERNAL: Cached sequence suffix",
|
||||||
|
options={"HIDDEN"})
|
||||||
|
check_suffixes = BoolProperty(description="INTERNAL: Should we sanity-check suffixes?",
|
||||||
|
options={"HIDDEN"},
|
||||||
|
default=False)
|
||||||
|
|
||||||
|
|
||||||
|
class PlasmaAge(bpy.types.PropertyGroup):
|
||||||
|
day_length = FloatProperty(name="Day Length",
|
||||||
|
description="Length of a day (in hours) on this age",
|
||||||
|
default=24.0,
|
||||||
|
soft_min=0.1,
|
||||||
|
min=0.0)
|
||||||
|
seq_prefix = IntProperty(name="Sequence Prefix",
|
||||||
|
description="A unique numerical ID for this age",
|
||||||
|
soft_min=0, # Negative indicates global--advanced users only
|
||||||
|
default=100)
|
||||||
|
pages = CollectionProperty(name="Pages",
|
||||||
|
description="Registry pages for this age",
|
||||||
|
type=PlasmaPage)
|
||||||
|
|
||||||
|
# Implementation details
|
||||||
|
active_page_index = IntProperty(name="Active Page Index")
|
17
korman/ui/__init__.py
Normal file
17
korman/ui/__init__.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# This file is part of Korman.
|
||||||
|
#
|
||||||
|
# Korman is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Korman is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from .ui_object import *
|
||||||
|
from .ui_world import *
|
40
korman/ui/ui_object.py
Normal file
40
korman/ui/ui_object.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# This file is part of Korman.
|
||||||
|
#
|
||||||
|
# Korman is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Korman is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
class ObjectButtonsPanel:
|
||||||
|
bl_space_type = "PROPERTIES"
|
||||||
|
bl_region_type = "WINDOW"
|
||||||
|
bl_context = "object"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return context.object and context.scene.render.engine == "PLASMA_GAME"
|
||||||
|
|
||||||
|
|
||||||
|
class PlasmaObjectPanel(ObjectButtonsPanel, bpy.types.Panel):
|
||||||
|
bl_label = "Plasma Object"
|
||||||
|
|
||||||
|
def draw_header(self, context):
|
||||||
|
self.layout.prop(context.object.plasma_object, "export", text="")
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
pl_obj = context.object.plasma_object
|
||||||
|
pl_age = context.scene.world.plasma_age
|
||||||
|
layout.active = pl_obj.export
|
||||||
|
|
||||||
|
layout.prop_search(pl_obj, "page", pl_age, "pages", icon="BOOKMARKS")
|
69
korman/ui/ui_world.py
Normal file
69
korman/ui/ui_world.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# This file is part of Korman.
|
||||||
|
#
|
||||||
|
# Korman is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Korman is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
|
||||||
|
class AgeButtonsPanel:
|
||||||
|
bl_space_type = "PROPERTIES"
|
||||||
|
bl_region_type = "WINDOW"
|
||||||
|
bl_context = "world"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return context.world and context.scene.render.engine == "PLASMA_GAME"
|
||||||
|
|
||||||
|
|
||||||
|
class PlasmaAgePanel(AgeButtonsPanel, bpy.types.Panel):
|
||||||
|
bl_label = "Plasma Age"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
age = context.world.plasma_age
|
||||||
|
|
||||||
|
# Core age settings
|
||||||
|
# ...
|
||||||
|
|
||||||
|
# We want a list of pages and an editor below that
|
||||||
|
row = layout.row()
|
||||||
|
row.template_list(age, "pages", age, "active_page_index", rows=2)
|
||||||
|
col = row.column(align=True)
|
||||||
|
col.operator("world.plasma_page_add", icon="ZOOMIN", text="")
|
||||||
|
col.operator("world.plasma_page_remove", icon="ZOOMOUT", text="")
|
||||||
|
|
||||||
|
# name/id editor for current selection
|
||||||
|
if age.active_page_index < len(age.pages):
|
||||||
|
active_page = age.pages[age.active_page_index]
|
||||||
|
split = layout.split(percentage=0.65)
|
||||||
|
col = split.column()
|
||||||
|
col.prop(active_page, "name")
|
||||||
|
col = split.column()
|
||||||
|
col.prop(active_page, "seq_suffix")
|
||||||
|
|
||||||
|
|
||||||
|
class PlasmaEnvironmentPanel(AgeButtonsPanel, bpy.types.Panel):
|
||||||
|
bl_label = "Plasma Environment"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
fni = context.world.plasma_fni
|
||||||
|
|
||||||
|
# Column-ize the colors
|
||||||
|
split = layout.split()
|
||||||
|
col = split.column()
|
||||||
|
col.prop(fni, "fog_color")
|
||||||
|
col = split.column()
|
||||||
|
col.prop(fni, "clear_color")
|
||||||
|
|
||||||
|
layout.prop(fni, "yon")
|
Reference in New Issue
Block a user