Browse Source

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.
pull/1/head
Adam Johnson 12 years ago
parent
commit
5fececf4e1
  1. 1
      .gitignore
  2. 6
      korman/__init__.py
  3. 6
      korman/exporter.py
  4. 16
      korman/operators/__init__.py
  5. 72
      korman/operators/op_world.py
  6. 24
      korman/properties/__init__.py
  7. 51
      korman/properties/prop_object.py
  8. 114
      korman/properties/prop_world.py
  9. 17
      korman/ui/__init__.py
  10. 40
      korman/ui/ui_object.py
  11. 69
      korman/ui/ui_world.py

1
.gitignore vendored

@ -1,4 +1,5 @@
*.py[co]
__pycache__
# Packages
*.egg

6
korman/__init__.py

@ -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__)

6
korman/exporter.py

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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")
Loading…
Cancel
Save