armory/blender/props_traits.py

303 lines
11 KiB
Python
Raw Normal View History

2015-10-30 13:23:09 +01:00
import shutil
import bpy
import os
import json
2016-09-23 00:34:42 +02:00
from props_traits_params import *
2015-10-30 13:23:09 +01:00
from bpy.types import Menu, Panel, UIList
from bpy.props import *
2016-10-27 01:11:11 +02:00
import armutils
2016-07-10 00:51:39 +02:00
import write_data
import subprocess
2015-10-30 13:23:09 +01:00
class ListTraitItem(bpy.types.PropertyGroup):
# Group of properties representing an item in the list
name = bpy.props.StringProperty(
name="Name",
description="A name for this item",
2016-07-10 00:51:39 +02:00
default="")
2015-10-30 13:23:09 +01:00
enabled_prop = bpy.props.BoolProperty(
name="",
description="A name for this item",
default=True)
type_prop = bpy.props.EnumProperty(
2016-08-22 23:18:30 +02:00
items = [('Haxe Script', 'Haxe Script', 'Haxe Script'),
2016-08-21 00:16:13 +02:00
('Python Script', 'Python Script', 'Python Script'),
('JS Script', 'JS Script', 'JS Script'),
2016-08-22 23:18:30 +02:00
('Bundled Script', 'Bundled Script', 'Bundled Script'),
2016-08-29 09:56:34 +02:00
('Logic Nodes', 'Logic Nodes', 'Logic Nodes')
2015-10-30 13:23:09 +01:00
],
name = "Type")
2016-08-29 09:56:34 +02:00
# data_prop = bpy.props.StringProperty(
# name="Data",
# description="A name for this item",
# default="")
2015-10-30 13:23:09 +01:00
class_name_prop = bpy.props.StringProperty(
name="Class",
description="A name for this item",
2016-07-10 00:51:39 +02:00
default="")
2015-10-30 13:23:09 +01:00
2016-08-21 00:16:13 +02:00
jsscript_prop = bpy.props.StringProperty(
name="Text",
description="A name for this item",
default="")
2015-10-30 13:23:09 +01:00
nodes_name_prop = bpy.props.StringProperty(
name="Nodes",
description="A name for this item",
default="")
2016-07-17 20:29:53 +02:00
my_paramstraitlist = bpy.props.CollectionProperty(type=ListParamsTraitItem)
2016-07-17 23:29:30 +02:00
paramstraitlist_index = bpy.props.IntProperty(name="Index for my_list", default=0)
2016-07-10 00:51:39 +02:00
2015-10-30 13:23:09 +01:00
class MY_UL_TraitList(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# We could write some code to decide which icon to use here...
custom_icon = 'OBJECT_DATAMODE'
# Make sure your code supports all 3 layout types
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(item, "enabled_prop")
2016-08-29 09:56:34 +02:00
layout.label(item.name, icon=custom_icon)
2015-10-30 13:23:09 +01:00
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label("", icon = custom_icon)
def initObjectProperties():
2016-12-05 01:54:01 +01:00
bpy.types.Object.my_traitlist = bpy.props.CollectionProperty(type=ListTraitItem)
bpy.types.Object.traitlist_index = bpy.props.IntProperty(name="Index for my_list", default=0)
2015-11-28 21:51:42 +01:00
2015-10-30 13:23:09 +01:00
class LIST_OT_TraitNewItem(bpy.types.Operator):
# Add a new item to the list
bl_idname = "my_traitlist.new_item"
bl_label = "Add a new item"
def execute(self, context):
bpy.context.object.my_traitlist.add()
2016-07-17 23:29:30 +02:00
bpy.context.object.traitlist_index = len(bpy.context.object.my_traitlist) - 1
2015-10-30 13:23:09 +01:00
return{'FINISHED'}
class LIST_OT_TraitDeleteItem(bpy.types.Operator):
# Delete the selected item from the list
bl_idname = "my_traitlist.delete_item"
bl_label = "Deletes an item"
@classmethod
def poll(self, context):
""" Enable if there's something in the list """
return len(bpy.context.object.my_traitlist) > 0
def execute(self, context):
list = bpy.context.object.my_traitlist
index = bpy.context.object.traitlist_index
list.remove(index)
if index > 0:
index = index - 1
bpy.context.object.traitlist_index = index
return{'FINISHED'}
class LIST_OT_TraitMoveItem(bpy.types.Operator):
# Move an item in the list
bl_idname = "my_traitlist.move_item"
bl_label = "Move an item in the list"
direction = bpy.props.EnumProperty(
items=(
('UP', 'Up', ""),
('DOWN', 'Down', ""),))
@classmethod
def poll(self, context):
""" Enable if there's something in the list. """
return len(bpy.context.object.my_traitlist) > 0
def move_index(self):
# Move index of an item render queue while clamping it
index = bpy.context.object.traitlist_index
list_length = len(bpy.context.object.my_traitlist) - 1
new_index = 0
if self.direction == 'UP':
new_index = index - 1
elif self.direction == 'DOWN':
new_index = index + 1
new_index = max(0, min(new_index, list_length))
index = new_index
def execute(self, context):
list = bpy.context.object.my_traitlist
index = bpy.context.object.traitlist_index
if self.direction == 'DOWN':
neighbor = index + 1
#queue.move(index,neighbor)
self.move_index()
elif self.direction == 'UP':
neighbor = index - 1
#queue.move(neighbor, index)
self.move_index()
else:
return{'CANCELLED'}
return{'FINISHED'}
2016-07-10 00:51:39 +02:00
class ArmoryEditScriptButton(bpy.types.Operator):
2016-09-23 00:34:42 +02:00
'''Edit script in Kode Studio'''
2016-07-10 00:51:39 +02:00
bl_idname = 'arm.edit_script'
bl_label = 'Edit Script'
def execute(self, context):
2016-11-01 00:30:10 +01:00
project_path = armutils.get_fp()
item = context.object.my_traitlist[context.object.traitlist_index]
hx_path = project_path + '/Sources/' + bpy.data.worlds['Arm'].arm_project_package + '/' + item.class_name_prop + '.hx'
2016-10-27 01:11:11 +02:00
sdk_path = armutils.get_sdk_path()
if armutils.get_os() == 'win':
2016-11-01 12:02:58 +01:00
kode_path = sdk_path + '/win32/Kode Studio.exe'
2016-11-09 14:40:07 +01:00
subprocess.Popen([kode_path, armutils.get_fp(), hx_path])
2016-10-27 01:11:11 +02:00
elif armutils.get_os() == 'mac':
2016-11-01 12:02:58 +01:00
kode_path = '"' + sdk_path + '/Kode Studio.app/Contents/MacOS/Electron"'
2016-11-01 00:30:10 +01:00
subprocess.Popen([kode_path + ' ' + armutils.get_fp() + ' ' + hx_path], shell=True)
2016-08-15 12:08:50 +02:00
else:
2016-11-01 12:02:58 +01:00
kode_path = sdk_path + '/linux64/kodestudio'
2016-11-09 14:40:07 +01:00
subprocess.Popen([kode_path, armutils.get_fp(), hx_path])
2016-11-01 00:30:10 +01:00
2016-07-10 00:51:39 +02:00
return{'FINISHED'}
class ArmoryNewScriptDialog(bpy.types.Operator):
2016-09-23 00:34:42 +02:00
'''Create blank script'''
2016-07-10 00:51:39 +02:00
bl_idname = "arm.new_script"
bl_label = "New Script"
class_name = StringProperty(name="Name")
def execute(self, context):
self.class_name = self.class_name.replace(' ', '')
write_data.write_traithx(self.class_name)
2016-10-27 01:11:11 +02:00
armutils.fetch_script_names()
2016-07-10 00:51:39 +02:00
obj = context.object
item = obj.my_traitlist[obj.traitlist_index]
item.class_name_prop = self.class_name
return {'FINISHED'}
def invoke(self, context, event):
self.class_name = 'MyTrait'
return context.window_manager.invoke_props_dialog(self)
class ArmoryRefreshScriptsListButton(bpy.types.Operator):
2016-09-23 00:34:42 +02:00
'''Fetch all script names'''
2016-07-10 00:51:39 +02:00
bl_idname = 'arm.refresh_scripts_list'
bl_label = 'Refresh Scripts List'
def execute(self, context):
2016-10-27 01:11:11 +02:00
armutils.fetch_script_names()
2016-07-10 00:51:39 +02:00
return{'FINISHED'}
2015-10-30 13:23:09 +01:00
# Menu in tools region
class ToolsTraitsPanel(bpy.types.Panel):
2016-07-10 00:51:39 +02:00
bl_label = "Armory Traits"
2015-10-30 13:23:09 +01:00
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
def draw(self, context):
layout = self.layout
obj = bpy.context.object
rows = 2
if len(obj.my_traitlist) > 1:
rows = 4
row = layout.row()
row.template_list("MY_UL_TraitList", "The_List", obj, "my_traitlist", obj, "traitlist_index", rows=rows)
col = row.column(align=True)
col.operator("my_traitlist.new_item", icon='ZOOMIN', text="")
col.operator("my_traitlist.delete_item", icon='ZOOMOUT', text="")#.all = False
if len(obj.my_traitlist) > 1:
col.separator()
col.operator("my_traitlist.move_item", icon='TRIA_UP', text="").direction = 'UP'
col.operator("my_traitlist.move_item", icon='TRIA_DOWN', text="").direction = 'DOWN'
if obj.traitlist_index >= 0 and len(obj.my_traitlist) > 0:
2016-08-29 09:56:34 +02:00
item = obj.my_traitlist[obj.traitlist_index]
2015-10-30 13:23:09 +01:00
# Default props
row = layout.row()
row.prop(item, "type_prop")
# Script
2016-08-22 23:18:30 +02:00
if item.type_prop == 'Haxe Script' or item.type_prop == 'Bundled Script':
2015-10-30 13:23:09 +01:00
item.name = item.class_name_prop
row = layout.row()
2016-07-10 00:51:39 +02:00
# row.prop(item, "class_name_prop")
2016-08-22 23:18:30 +02:00
if item.type_prop == 'Haxe Script':
row.prop_search(item, "class_name_prop", bpy.data.worlds['Arm'], "scripts_list", "Class")
2016-07-10 00:51:39 +02:00
else:
row.prop_search(item, "class_name_prop", bpy.data.worlds['Arm'], "bundled_scripts_list", "Class")
2016-01-28 12:32:05 +01:00
# Params
layout.label("Parameters")
paramsrow = layout.row()
paramsrows = 2
2016-07-10 00:51:39 +02:00
if len(item.my_paramstraitlist) > 1:
2016-01-28 12:32:05 +01:00
paramsrows = 4
row = layout.row()
2016-07-10 00:51:39 +02:00
row.template_list("MY_UL_ParamsTraitList", "The_List", item, "my_paramstraitlist", item, "paramstraitlist_index", rows=paramsrows)
2016-01-28 12:32:05 +01:00
col = row.column(align=True)
col.operator("my_paramstraitlist.new_item", icon='ZOOMIN', text="")
col.operator("my_paramstraitlist.delete_item", icon='ZOOMOUT', text="")
2016-07-10 00:51:39 +02:00
if len(item.my_paramstraitlist) > 1:
2016-01-28 12:32:05 +01:00
col.separator()
col.operator("my_paramstraitlist.move_item", icon='TRIA_UP', text="").direction = 'UP'
col.operator("my_paramstraitlist.move_item", icon='TRIA_DOWN', text="").direction = 'DOWN'
2016-07-10 00:51:39 +02:00
if item.paramstraitlist_index >= 0 and len(item.my_paramstraitlist) > 0:
2016-07-17 23:29:30 +02:00
paramitem = item.my_paramstraitlist[item.paramstraitlist_index]
# Picker
layout.label('Pickers')
layout.prop_search(paramitem, 'object_picker', bpy.context.scene, "objects", "Object")
layout.prop(paramitem, 'color_picker')
2016-07-10 00:51:39 +02:00
2016-08-22 23:18:30 +02:00
if item.type_prop == 'Haxe Script':
2016-07-10 00:51:39 +02:00
row = layout.row()
if item.class_name_prop == '':
row.enabled = False
row.operator("arm.edit_script")
layout.operator("arm.new_script")
layout.operator("arm.refresh_scripts_list")
2015-12-07 20:04:23 +01:00
2016-08-21 00:16:13 +02:00
# JS/Python Script
elif item.type_prop == 'JS Script' or item.type_prop == 'Python Script':
item.name = item.jsscript_prop
row = layout.row()
row.prop_search(item, "jsscript_prop", bpy.data, "texts", "Text")
2015-10-30 13:23:09 +01:00
# Nodes
2016-08-22 23:18:30 +02:00
elif item.type_prop == 'Logic Nodes':
2015-10-30 13:23:09 +01:00
item.name = item.nodes_name_prop
row = layout.row()
row.prop_search(item, "nodes_name_prop", bpy.data, "node_groups", "Tree")
2015-12-07 20:04:23 +01:00
def register():
bpy.utils.register_module(__name__)
initObjectProperties()
def unregister():
bpy.utils.unregister_module(__name__)