Logic UI and Operators: adjusts on Layout + copy properties operator + fix on copy logic bricks operator (and moved to OBJECT_OT)

* adjusts on Layout:
 - in order to avoid much changes when copying Logics, it's nice to have the logic s/c/a always displaying even though it's not valid (e.g. edit mesh used from a camera object).
Now a message shows in the s/c/a alerting to the problem.

* logic operators under OBJECT_OT - copy properties and logics

Matt, is it possible to have the object game properties listed as a submenu from "Copy Properties" ?
So from the "Copy Game Property" menu we would have three options:
"Copy a property" -> (submenu) prop1, prop2, prop3 
"Replace all Properties"
"Merge all Properties"

For the current task list in Logic Editor:
http://www.pasteall.org/13245
This commit is contained in:
Dalai Felinto
2010-05-19 09:40:45 +00:00
parent 2d343d0774
commit a7a9862cc9
7 changed files with 213 additions and 87 deletions

View File

@@ -30,6 +30,7 @@
#include <time.h>
#include <float.h>
#include <ctype.h>
#include <stddef.h> //for offsetof
#include "MEM_guardedalloc.h"
@@ -104,6 +105,7 @@
/* for menu/popup icons etc etc*/
#include "UI_interface.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -1098,6 +1100,7 @@ void flip_subdivison(Scene *scene, View3D *v3d, int level)
static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob)
{
//XXX no longer used - to be removed - replaced by game_properties_copy_exec
bProperty *prop;
Base *base;
int nr, tot=0;
@@ -1156,6 +1159,7 @@ static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob)
static void copymenu_logicbricks(Scene *scene, View3D *v3d, Object *ob)
{
//XXX no longer used - to be removed - replaced by logicbricks_copy_exec
Base *base;
for(base= FIRSTBASE; base; base= base->next) {
@@ -2203,3 +2207,166 @@ void OBJECT_OT_game_property_remove(wmOperatorType *ot)
RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Property index to remove ", 0, INT_MAX);
}
static EnumPropertyItem game_properties_copy_types[] ={
{1, "REPLACE", 0, "Replace Properties", ""},
{2, "MERGE", 0, "Merge Properties", ""},
{3, "CLEAR", 0, "Clear All", ""},
{4, "COPY", 0, "Copy a Property", ""},
{0, NULL, 0, NULL, NULL}};
static int game_property_copy_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
Object *ob= CTX_data_active_object(C);
bProperty *prop;
int tot=0;
uiPopupMenu *pup;
uiLayout *menu;
/* count number of available properties */
prop= ob->prop.first;
while(prop) {
tot++;
prop= prop->next;
}
/* start building */
pup= uiPupMenuBegin(C, op->type->name, 0);
menu= uiPupMenuLayout(pup);
uiLayoutSetOperatorContext(menu, WM_OP_EXEC_DEFAULT);
if(!tot)
uiItemEnumO(menu, "OBJECT_OT_game_property_copy", NULL, 0, "type", 3);//CLEAR);
else {
uiItemEnumO(menu, "OBJECT_OT_game_property_copy", NULL, 0, "type", 1);//REPLACE);
uiItemEnumO(menu, "OBJECT_OT_game_property_copy", NULL, 0, "type", 2);//MERGE);
//Menu Separator
uiItemL(menu, "Copy a Property", 0);
prop= ob->prop.first;
while(prop) {
uiItemStringO(menu, prop->name, 0, "OBJECT_OT_game_property_copy", "property", prop->name);
prop= prop->next;
}
}
uiPupMenuEnd(C, pup);
/* this operator is only for a menu, not used further */
return OPERATOR_CANCELLED;
}
static int game_property_copy_exec(bContext *C, wmOperator *op)
{
Object *ob=ED_object_active_context(C);
bProperty *prop;
char prop_name[32];
int type = RNA_enum_get(op->ptr, "type");
RNA_string_get(op->ptr, "property", prop_name);
if ( type == 1 || type == 2 || type == 3) {
CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) {
if (ob != ob_iter) {
if (ob->data != ob_iter->data){
if (type == 2) {/* merge */
for(prop = ob->prop.first; prop; prop= prop->next ) {
set_ob_property(ob_iter, prop);
}
} else /* replace or clear */
copy_properties( &ob_iter->prop, &ob->prop );
}
}
}
CTX_DATA_END;
}
else if(strlen(prop_name) > 0) { /* copy */
prop = (bProperty *) BLI_findstring(&ob->prop, prop_name, offsetof(bProperty, name));
if(prop) {
CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) {
if (ob != ob_iter) {
if (ob->data != ob_iter->data)
set_ob_property(ob_iter, prop);
}
} CTX_DATA_END;
}
}
return OPERATOR_FINISHED;
}
void OBJECT_OT_game_property_copy(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Copy Game Property";
ot->idname= "OBJECT_OT_game_property_copy";
/* api callbacks */
ot->invoke= game_property_copy_invoke;
ot->exec= game_property_copy_exec;
ot->poll= ED_operator_object_active_editable;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
RNA_def_enum(ot->srna, "type", game_properties_copy_types, 4, "Operation", "");
RNA_def_string(ot->srna, "property", "", 32, "Name", "Name of the property to copy");
}
/************************ Copy Logic Bricks ***********************/
static int logicbricks_copy_exec(bContext *C, wmOperator *op)
{
Object *ob=ED_object_active_context(C);
CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) {
if(ob != ob_iter) {
if (ob->data != ob_iter->data){
/* first: free all logic */
free_sensors(&ob_iter->sensors);
unlink_controllers(&ob_iter->controllers);
free_controllers(&ob_iter->controllers);
unlink_actuators(&ob_iter->actuators);
free_actuators(&ob_iter->actuators);
/* now copy it, this also works without logicbricks! */
clear_sca_new_poins_ob(ob);
copy_sensors(&ob_iter->sensors, &ob->sensors);
copy_controllers(&ob_iter->controllers, &ob->controllers);
copy_actuators(&ob_iter->actuators, &ob->actuators);
set_sca_new_poins_ob(ob_iter);
/* some menu settings */
ob_iter->scavisflag= ob->scavisflag;
ob_iter->scaflag= ob->scaflag;
/* set the initial state */
ob_iter->state= ob->state;
ob_iter->init_state= ob->init_state;
}
if(ob_iter->totcol==ob->totcol) {
ob_iter->actcol= ob->actcol;
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob_iter);
}
}
}
CTX_DATA_END;
WM_event_add_notifier(C, NC_LOGIC, NULL);
return OPERATOR_FINISHED;
}
void OBJECT_OT_logic_bricks_copy(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Copy Logic Bricks to Selected";
ot->description = "Copy logic bricks to other selected objects.";
ot->idname= "OBJECT_OT_logic_bricks_copy";
/* api callbacks */
ot->exec= logicbricks_copy_exec;
ot->poll= ED_operator_object_active_editable;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}

View File

@@ -85,6 +85,11 @@ void OBJECT_OT_shade_flat(struct wmOperatorType *ot);
void OBJECT_OT_paths_calculate(struct wmOperatorType *ot);
void OBJECT_OT_paths_clear(struct wmOperatorType *ot);
void OBJECT_OT_game_property_new(struct wmOperatorType *ot);
void OBJECT_OT_game_property_remove(struct wmOperatorType *ot);
void OBJECT_OT_game_property_copy(struct wmOperatorType *ot);
void OBJECT_OT_logic_bricks_copy(struct wmOperatorType *ot);
/* object_select.c */
void OBJECT_OT_select_all(struct wmOperatorType *ot);
void OBJECT_OT_select_inverse(struct wmOperatorType *ot);
@@ -201,9 +206,6 @@ void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_sort(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_move(struct wmOperatorType *ot);
void OBJECT_OT_game_property_new(struct wmOperatorType *ot);
void OBJECT_OT_game_property_remove(struct wmOperatorType *ot);
/* object_shapekey.c */
void OBJECT_OT_shape_key_add(struct wmOperatorType *ot);
void OBJECT_OT_shape_key_remove(struct wmOperatorType *ot);

View File

@@ -183,6 +183,8 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_game_property_new);
WM_operatortype_append(OBJECT_OT_game_property_remove);
WM_operatortype_append(OBJECT_OT_game_property_copy);
WM_operatortype_append(OBJECT_OT_logic_bricks_copy);
WM_operatortype_append(OBJECT_OT_shape_key_add);
WM_operatortype_append(OBJECT_OT_shape_key_remove);

View File

@@ -533,48 +533,6 @@ void LOGIC_OT_actuator_add(wmOperatorType *ot)
prop= RNA_def_string(ot->srna, "name", "", 32, "Name", "Name of the Actuator to add");
}
/* Copy Routines */
static int logicbricks_copy_exec(bContext *C, wmOperator *op)
{
Object *ob=ED_object_active_context(C);
CTX_DATA_BEGIN(C, Object*, ob_iter, selected_editable_objects) {
if(ob != ob_iter) {
if (ob->data != ob_iter->data){
copy_sensors(&ob_iter->sensors, &ob->sensors);
copy_controllers(&ob_iter->controllers, &ob->controllers);
copy_actuators(&ob_iter->actuators, &ob->actuators);
}
if(ob_iter->totcol==ob->totcol) {
ob_iter->actcol= ob->actcol;
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob_iter);
}
}
}
CTX_DATA_END;
WM_event_add_notifier(C, NC_LOGIC, NULL);
return OPERATOR_FINISHED;
}
void LOGIC_OT_bricks_copy(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Copy Logic Bricks to Selected";
ot->description = "Copy logic bricks to other selected objects.";
ot->idname= "LOGIC_OT_bricks_copy";
/* api callbacks */
ot->exec= logicbricks_copy_exec;
ot->poll= ED_operator_object_active_editable;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
void ED_operatortypes_logic(void)
{
WM_operatortype_append(LOGIC_OT_sensor_remove);
@@ -583,5 +541,4 @@ void ED_operatortypes_logic(void)
WM_operatortype_append(LOGIC_OT_controller_add);
WM_operatortype_append(LOGIC_OT_actuator_remove);
WM_operatortype_append(LOGIC_OT_actuator_add);
WM_operatortype_append(LOGIC_OT_bricks_copy);
}

View File

@@ -3224,6 +3224,11 @@ static void draw_sensor_armature(uiLayout *layout, PointerRNA *ptr)
PropertyRNA *bones_prop;
uiLayout *row;
if(ob->type != OB_ARMATURE){
uiItemL(layout, "Sensor only available for armatures", 0);
return;
}
if (ob->pose) {
RNA_pointer_create((ID *)ob, &RNA_Pose, ob->pose, &pose_ptr);
bones_prop = RNA_struct_find_property(&pose_ptr, "bones");
@@ -3588,6 +3593,10 @@ static void draw_actuator_action(uiLayout *layout, PointerRNA *ptr)
PointerRNA settings_ptr;
uiLayout *row;
if(ob->type != OB_ARMATURE){
uiItemL(layout, "Actuator only available for armatures", 0);
return;
}
RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
row= uiLayoutRow(layout, 0);
@@ -3623,6 +3632,11 @@ static void draw_actuator_armature(uiLayout *layout, PointerRNA *ptr)
Object *ob = (Object *)ptr->id.data;
PointerRNA pose_ptr, pchan_ptr;
PropertyRNA *bones_prop;
if(ob->type != OB_ARMATURE){
uiItemL(layout, "Actuator only available for armatures", 0);
return;
}
if (ob->pose) {
RNA_pointer_create((ID *)ob, &RNA_Pose, ob->pose, &pose_ptr);
@@ -3782,6 +3796,7 @@ static void draw_actuator_constraint(uiLayout *layout, PointerRNA *ptr)
static void draw_actuator_edit_object(uiLayout *layout, PointerRNA *ptr)
{
Object *ob = (Object *)ptr->id.data;
uiLayout *row, *split, *subsplit;
uiItemR(layout, ptr, "mode", 0, NULL, 0);
@@ -3805,6 +3820,10 @@ static void draw_actuator_edit_object(uiLayout *layout, PointerRNA *ptr)
case ACT_EDOB_END_OBJECT:
break;
case ACT_EDOB_REPLACE_MESH:
if(ob->type != OB_MESH) {
uiItemL(layout, "Mode only available for mesh objects", 0);
break;
}
split = uiLayoutSplit(layout, 0.6, 0);
uiItemR(split, ptr, "mesh", 0, NULL, 0);
row = uiLayoutRow(split, 0);
@@ -3819,6 +3838,10 @@ static void draw_actuator_edit_object(uiLayout *layout, PointerRNA *ptr)
uiItemR(subsplit, ptr, "enable_3d_tracking", UI_ITEM_R_TOGGLE, NULL, 0);
break;
case ACT_EDOB_DYNAMICS:
if(ob->type != OB_MESH) {
uiItemL(layout, "Mode only available for mesh objects", 0);
break;
}
uiItemR(layout, ptr, "dynamic_operation", 0, NULL, 0);
if (RNA_enum_get(ptr, "dynamic_operation") == ACT_EDOB_SET_MASS)
uiItemR(layout, ptr, "mass", 0, NULL, 0);
@@ -4144,6 +4167,11 @@ static void draw_actuator_shape_action(uiLayout *layout, PointerRNA *ptr)
PointerRNA settings_ptr;
uiLayout *row;
if(ob->type != OB_MESH){
uiItemL(layout, "Actuator only available for mesh objects", 0);
return;
}
RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
row= uiLayoutRow(layout, 0);

View File

@@ -56,14 +56,6 @@ EnumPropertyItem actuator_type_items[] ={
{ACT_VISIBILITY, "VISIBILITY", 0, "Visibility", ""},
{0, NULL, 0, NULL, NULL}};
EnumPropertyItem edit_object_type_items[] ={
{ACT_EDOB_ADD_OBJECT, "ADDOBJECT", 0, "Add Object", ""},
{ACT_EDOB_END_OBJECT, "ENDOBJECT", 0, "End Object", ""},
{ACT_EDOB_REPLACE_MESH, "REPLACEMESH", 0, "Replace Mesh", ""},
{ACT_EDOB_TRACK_TO, "TRACKTO", 0, "Track to", ""},
{ACT_EDOB_DYNAMICS, "DYNAMICS", 0, "Dynamics", ""},
{0, NULL, 0, NULL, NULL} };
#ifdef RNA_RUNTIME
#include "BKE_sca.h"
@@ -346,28 +338,6 @@ static void rna_StateActuator_state_set(PointerRNA *ptr, const int *values)
}
}
static EnumPropertyItem *rna_EditObjectActuator_mode_itemf(bContext *C, PointerRNA *ptr, int *free)
{
EnumPropertyItem *item= NULL;
Object *ob = (Object *)ptr->id.data;
int totitem= 0;
if (ob->type!=OB_ARMATURE)
{
RNA_enum_items_add_value(&item, &totitem, edit_object_type_items, ACT_EDOB_REPLACE_MESH);
RNA_enum_items_add_value(&item, &totitem, edit_object_type_items, ACT_EDOB_DYNAMICS);
}
RNA_enum_items_add_value(&item, &totitem, edit_object_type_items, ACT_EDOB_ADD_OBJECT);
RNA_enum_items_add_value(&item, &totitem, edit_object_type_items, ACT_EDOB_END_OBJECT);
RNA_enum_items_add_value(&item, &totitem, edit_object_type_items, ACT_EDOB_TRACK_TO);
RNA_enum_item_end(&item, &totitem);
*free= 1;
return item;
}
/* Always keep in alphabetical order */
EnumPropertyItem *rna_Actuator_type_itemf(bContext *C, PointerRNA *ptr, int *free)
{
@@ -1209,14 +1179,21 @@ static void rna_def_edit_object_actuator(BlenderRNA *brna)
{ACT_EDOB_SET_MASS, "SETMASS", 0, "Set Mass", ""},
{0, NULL, 0, NULL, NULL} };
static EnumPropertyItem prop_type_items[] ={
{ACT_EDOB_ADD_OBJECT, "ADDOBJECT", 0, "Add Object", ""},
{ACT_EDOB_END_OBJECT, "ENDOBJECT", 0, "End Object", ""},
{ACT_EDOB_REPLACE_MESH, "REPLACEMESH", 0, "Replace Mesh", ""},
{ACT_EDOB_TRACK_TO, "TRACKTO", 0, "Track to", ""},
{ACT_EDOB_DYNAMICS, "DYNAMICS", 0, "Dynamics", ""},
{0, NULL, 0, NULL, NULL} };
srna= RNA_def_struct(brna, "EditObjectActuator", "Actuator");
RNA_def_struct_ui_text(srna, "Edit Object Actuator", "Actuator used to edit objects");
RNA_def_struct_sdna_from(srna, "bEditObjectActuator", "data");
prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, edit_object_type_items);
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_EditObjectActuator_mode_itemf");
RNA_def_property_enum_items(prop, prop_type_items);
RNA_def_property_ui_text(prop, "Edit Object", "The mode of the actuator");
RNA_def_property_update(prop, NC_LOGIC, NULL);

View File

@@ -128,11 +128,9 @@ EnumPropertyItem *rna_Sensor_type_itemf(bContext *C, PointerRNA *ptr, int *free)
if (ob != NULL) {
if (ob->type==OB_ARMATURE) {
RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_ARMATURE);
} else if(ob->type==OB_MESH) {
RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_COLLISION);
}
}
RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_COLLISION);
RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_DELAY);
RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_JOYSTICK);
RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_KEYBOARD);
@@ -143,12 +141,7 @@ EnumPropertyItem *rna_Sensor_type_itemf(bContext *C, PointerRNA *ptr, int *free)
RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_RADAR);
RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_RANDOM);
RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_RAY);
if (ob != NULL) {
if(ob->type==OB_MESH) {
RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_TOUCH);
}
}
RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_TOUCH);
RNA_enum_item_end(&item, &totitem);
*free= 1;