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:
@ -15,6 +15,7 @@
|
||||
|
||||
import bpy
|
||||
from . import exporter, render
|
||||
from . import operators, properties, ui
|
||||
|
||||
bl_info = {
|
||||
"name": "Korman",
|
||||
@ -31,9 +32,12 @@ def register():
|
||||
"""Registers all Blender operators and GUI items in Korman"""
|
||||
|
||||
# This will auto-magically register all blender classes for us
|
||||
# We will define a lot of them, methinks...
|
||||
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():
|
||||
"""Unregisters all Blender operators and GUI items"""
|
||||
bpy.utils.unregister_module(__name__)
|
||||
|
@ -37,7 +37,8 @@ class PlasmaExporter(bpy.types.Operator):
|
||||
|
||||
@classmethod
|
||||
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):
|
||||
# TODO
|
||||
@ -54,4 +55,5 @@ class PlasmaExporter(bpy.types.Operator):
|
||||
def menu_cb(self, context):
|
||||
self.layout.operator_context = "INVOKE_DEFAULT"
|
||||
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