Object mode Selection options brought back for view3d.select

- 'center', while Ctrl is held select objects from their center location
- 'enumerate', while Alt is held, give a list of objects under the mouse
- Object selection menu now uses icons with names
- operator object.select_name(name, extend=False)
- keybindings so combinations of Ctrl/Alt/Shift can be used (like in 2.4x)
- logic text input field was using deprecated ID_SCRIPT rather then ID_TXT

details
- added comments to DNA_ID.h ID types
- removed unused ID types Sector and Life
- added uiIconFromID() to get an icon from the object.
- using name for selection is weak but currently there isnt a really good way to do this.
This commit is contained in:
2009-09-16 01:15:30 +00:00
parent be613fd9dd
commit 51f1e82290
10 changed files with 255 additions and 90 deletions

View File

@@ -99,7 +99,6 @@ static IDType idtypes[]= {
{ ID_IP, "Ipo", IDTYPE_FLAGS_ISLINKABLE},
{ ID_KE, "Key", 0},
{ ID_LA, "Lamp", IDTYPE_FLAGS_ISLINKABLE},
{ ID_LF, "Life", 0},
{ ID_LI, "Library", 0},
{ ID_LT, "Lattice", IDTYPE_FLAGS_ISLINKABLE},
{ ID_MA, "Material", IDTYPE_FLAGS_ISLINKABLE},
@@ -110,7 +109,6 @@ static IDType idtypes[]= {
{ ID_SCE, "Scene", IDTYPE_FLAGS_ISLINKABLE},
{ ID_SCR, "Screen", 0},
{ ID_SEQ, "Sequence", 0},
{ ID_SE, "Sector", 0},
{ ID_SO, "Sound", IDTYPE_FLAGS_ISLINKABLE},
{ ID_TE, "Texture", IDTYPE_FLAGS_ISLINKABLE},
{ ID_TXT, "Text", IDTYPE_FLAGS_ISLINKABLE},

View File

@@ -420,6 +420,8 @@ uiBut *uiDefIDPoinBut(uiBlock *block, uiIDPoinFuncFP func, short blocktype, int
short x1, short y1, short x2, short y2, void *idpp, char *tip);
int uiDefIDPoinButs(uiBlock *block, struct Main *main, struct ID *parid, struct ID *id, int id_code, short *pin_p, int x, int y, uiIDPoinFunc func, int events);
int uiIconFromID(struct ID *id);
uiBut *uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, char *str, short x1, short y1, short x2, short y2, char *tip);
uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, char *str, short x1, short y1, short x2, short y2, char *tip);
uiBut *uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, char *str, short x1, short y1, short x2, short y2, char *tip);

View File

@@ -33,6 +33,7 @@
#include "DNA_color_types.h"
#include "DNA_listBase.h"
#include "DNA_material_types.h"
#include "DNA_lamp_types.h""
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_texture_types.h"
@@ -509,6 +510,64 @@ int uiDefIDPoinButs(uiBlock *block, Main *bmain, ID *parid, ID *id, int id_code,
return x;
}
/* currently only object-data types */
int uiIconFromID(ID *id)
{
if (id==NULL)
return 0;
switch(GS(id->name)) {
case ID_OB:
{
Object *ob= (Object *)id;
switch(ob->type) {
case OB_EMPTY:
return ICON_EMPTY_DATA;
case OB_CURVE:
return ICON_CURVE_DATA;
case OB_SURF:
return ICON_SURFACE_DATA;
case OB_FONT:
return ICON_FONT_DATA;
}
return uiIconFromID(ob->data);
}
case ID_ME:
return ICON_MESH_DATA;
case ID_AR:
return ICON_ARMATURE_DATA;
case ID_MB:
return ICON_META_DATA;
case ID_CA:
return ICON_CAMERA_DATA;
case ID_LT:
return ICON_LATTICE_DATA;
case ID_CU:
return ICON_CURVE_DATA;
case ID_LA:
{
Lamp *la= (Lamp *)id;
switch(la->type) {
case LA_LOCAL:
return ICON_LAMP_POINT;
case LA_SUN:
return ICON_LAMP_SUN;
case LA_SPOT:
return ICON_LAMP_SPOT;
case LA_HEMI:
return ICON_LAMP_HEMI;
case LA_AREA:
return ICON_LAMP_AREA;
}
return ICON_LAMP_DATA;
}
}
return 0;
}
/* ****************************** default button callbacks ******************* */
/* ************ LEGACY WARNING, only to get things work with 2.48 code! ****** */

View File

@@ -79,6 +79,7 @@ void OBJECT_OT_select_by_layer(struct wmOperatorType *ot);
void OBJECT_OT_select_linked(struct wmOperatorType *ot);
void OBJECT_OT_select_grouped(struct wmOperatorType *ot);
void OBJECT_OT_select_mirror(struct wmOperatorType *ot);
void OBJECT_OT_select_name(struct wmOperatorType *ot);
/* object_add.c */
void OBJECT_OT_add(struct wmOperatorType *ot);

View File

@@ -102,6 +102,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_select_linked);
WM_operatortype_append(OBJECT_OT_select_grouped);
WM_operatortype_append(OBJECT_OT_select_mirror);
WM_operatortype_append(OBJECT_OT_select_name); /* XXX - weak, not compat with linked objects */
WM_operatortype_append(GROUP_OT_group_create);
WM_operatortype_append(GROUP_OT_objects_remove);

View File

@@ -923,6 +923,59 @@ void OBJECT_OT_select_mirror(wmOperatorType *ot)
RNA_def_enum(ot->srna, "seltype", prop_select_types, 1, "Selection", "Extend selection or clear selection then select");
}
static int object_select_name_exec(bContext *C, wmOperator *op)
{
char *name= RNA_string_get_alloc(op->ptr, "name", NULL, 0);
short extend= RNA_boolean_get(op->ptr, "extend");
short changed = 0;
if(!extend) {
CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
ED_base_object_select(base, BA_DESELECT);
}
CTX_DATA_END;
}
CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
if(strcmp(name, base->object->id.name+2)==0) {
ED_base_object_select(base, BA_SELECT);
changed= 1;
}
}
CTX_DATA_END;
MEM_freeN(name);
/* undo? */
if(changed) {
WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C));
return OPERATOR_FINISHED;
}
else {
return OPERATOR_CANCELLED;
}
}
void OBJECT_OT_select_name(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select Name";
ot->description = "Select an object with this name";
ot->idname= "OBJECT_OT_select_name";
/* api callbacks */
ot->exec= object_select_name_exec;
ot->poll= ED_operator_scene_editable;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
RNA_def_string(ot->srna, "name", "", 0, "Name", "Object name to select.");
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first.");
}
/**************************** Select Random ****************************/
static int object_select_random_exec(bContext *C, wmOperator *op)

View File

@@ -1534,7 +1534,7 @@ static short draw_controllerbuttons(bController *cont, uiBlock *block, short xco
uiBlockBeginAlign(block);
uiDefButI(block, MENU, B_REDR, "Execution Method%t|Script%x0|Module%x1", xco+4,yco-23, 66, 19, &pc->mode, 0, 0, 0, 0, "Python script type (textblock or module - faster)");
if(pc->mode==0)
uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "", xco+70,yco-23,width-74, 19, &pc->text, "Blender textblock to run as a script");
uiDefIDPoinBut(block, test_scriptpoin_but, ID_TXT, 1, "", xco+70,yco-23,width-74, 19, &pc->text, "Blender textblock to run as a script");
else {
uiDefBut(block, TEX, 1, "", xco+70,yco-23,(width-70)-25, 19, pc->module, 0, 63, 0, 0, "Module name and function to run e.g. \"someModule.main\". Internal texts and external python files can be used");
uiDefButBitI(block, TOG, CONT_PY_DEBUG, B_REDR, "D", (xco+width)-25, yco-23, 19, 19, &pc->flag, 0, 0, 0, 0, "Continuously reload the module from disk for editing external modules without restarting");

View File

@@ -201,7 +201,25 @@ void view3d_keymap(wmWindowManager *wm)
/* selection*/
WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", TRUE);
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "center", TRUE);
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "enumerate", TRUE);
/* selection key-combinations */
km = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
RNA_boolean_set(km->ptr, "center", TRUE);
RNA_boolean_set(km->ptr, "extend", TRUE);
km = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_ALT, 0);
RNA_boolean_set(km->ptr, "center", TRUE);
RNA_boolean_set(km->ptr, "enumerate", TRUE);
km = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0);
RNA_boolean_set(km->ptr, "extend", TRUE);
RNA_boolean_set(km->ptr, "enumerate", TRUE);
km = WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL|KM_ALT, 0);
RNA_boolean_set(km->ptr, "center", TRUE);
RNA_boolean_set(km->ptr, "extend", TRUE);
RNA_boolean_set(km->ptr, "enumerate", TRUE);
WM_keymap_add_item(keymap, "VIEW3D_OT_select_border", BKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0)->ptr, "deselect", 1);

View File

@@ -53,6 +53,7 @@
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
#include "BLI_rand.h"
#include "BLI_linklist.h"
#include "BKE_action.h"
#include "BKE_context.h"
@@ -845,56 +846,87 @@ static void deselectall_except(Scene *scene, Base *b) /* deselect all except b
}
}
static Base *mouse_select_menu(ViewContext *vc, unsigned int *buffer, int hits, short *mval)
static Base *mouse_select_menu(bContext *C, ViewContext *vc, unsigned int *buffer, int hits, short *mval, short extend)
{
Scene *scene= vc->scene;
View3D *v3d= vc->v3d;
Base *baseList[SEL_MENU_SIZE]={NULL}; /*baseList is used to store all possible bases to bring up a menu */
Base *base;
short baseCount = 0;
char menuText[20 + SEL_MENU_SIZE*32] = "Select Object%t"; /* max ob name = 22 */
char str[32];
short ok;
LinkNode *linklist= NULL;
for(base=FIRSTBASE; base; base= base->next) {
if (BASE_SELECTABLE(v3d, base)) {
baseList[baseCount] = NULL;
CTX_DATA_BEGIN(C, Base*, base, selectable_bases) {
ok= FALSE;
/* two selection methods, the CTRL select uses max dist of 15 */
if(buffer) {
int a;
for(a=0; a<hits; a++) {
/* index was converted */
if(base->selcol==buffer[ (4 * a) + 3 ])
ok= TRUE;
}
}
else {
int temp, dist=15;
project_short(vc->ar, base->object->obmat[3], &base->sx);
/* two selection methods, the CTRL select uses max dist of 15 */
if(buffer) {
int a;
for(a=0; a<hits; a++) {
/* index was converted */
if(base->selcol==buffer[ (4 * a) + 3 ]) baseList[baseCount] = base;
}
}
else {
int temp, dist=15;
project_short(vc->ar, base->object->obmat[3], &base->sx);
temp= abs(base->sx -mval[0]) + abs(base->sy -mval[1]);
if(temp<dist ) baseList[baseCount] = base;
}
if(baseList[baseCount]) {
if (baseCount < SEL_MENU_SIZE) {
baseList[baseCount] = base;
sprintf(str, "|%s %%x%d", base->object->id.name+2, baseCount+1); /* max ob name == 22 */
strcat(menuText, str);
baseCount++;
}
}
temp= abs(base->sx -mval[0]) + abs(base->sy -mval[1]);
if(temp < dist)
ok= TRUE;
}
if(ok) {
baseCount++;
BLI_linklist_prepend(&linklist, base);
if (baseCount==SEL_MENU_SIZE)
break;
}
}
CTX_DATA_END;
if(baseCount<=1) return baseList[0];
if(baseCount)
if(baseCount==0) {
return NULL;
}
if(baseCount == 1) {
Base *base= (Base *)linklist->link;
BLI_linklist_free(linklist, NULL);
return base;
}
else {
baseCount = -1; // XXX = pupmenu(menuText);
if (baseCount != -1) { /* If nothing is selected then dont do anything */
return baseList[baseCount-1];
/* UI */
uiPopupMenu *pup= uiPupMenuBegin(C, "Select Object", 0);
uiLayout *layout= uiPupMenuLayout(pup);
uiLayout *split= uiLayoutSplit(layout, 0);
uiLayout *column= uiLayoutColumn(split, 0);
LinkNode *node;
node= linklist;
while(node) {
Base *base=node->link;
Object *ob= base->object;
char *name= ob->id.name+2;
/* annoying!, since we need to set 2 props cant use this. */
/* uiItemStringO(column, name, 0, "OBJECT_OT_select_name", "name", name); */
{
PointerRNA ptr;
WM_operator_properties_create(&ptr, "OBJECT_OT_select_name");
RNA_string_set(&ptr, "name", name);
RNA_boolean_set(&ptr, "extend", extend);
uiItemFullO(column, name, uiIconFromID((ID *)ob), "OBJECT_OT_select_name", ptr.data, WM_OP_EXEC_DEFAULT, 0);
}
node= node->next;
}
else return NULL;
uiPupMenuEnd(C, pup);
BLI_linklist_free(linklist, NULL);
return NULL;
}
}
@@ -958,14 +990,13 @@ static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buff
/* mval is region coords */
static void mouse_select(bContext *C, short *mval, short extend, short obcenter)
static void mouse_select(bContext *C, short *mval, short extend, short obcenter, short enumerate)
{
ViewContext vc;
ARegion *ar= CTX_wm_region(C);
View3D *v3d= CTX_wm_view3d(C);
Scene *scene= CTX_data_scene(C);
Base *base, *startbase=NULL, *basact=NULL, *oldbasact=NULL;
unsigned int buffer[4*MAXPICKBUF];
int temp, a, dist=100;
short hits;
@@ -981,10 +1012,9 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter)
if(vc.obedit==NULL && obcenter) {
/* note; shift+alt goes to group-flush-selecting */
/* XXX solve */
if(0)
basact= mouse_select_menu(&vc, NULL, 0, mval);
else {
if(enumerate) {
basact= mouse_select_menu(C, &vc, NULL, 0, mval, extend);
} else {
base= startbase;
while(base) {
if (BASE_SELECTABLE(v3d, base)) {
@@ -1006,6 +1036,8 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter)
}
}
else {
unsigned int buffer[4*MAXPICKBUF];
/* if objects have posemode set, the bones are in the same selection buffer */
hits= mixed_bones_object_selectbuffer(&vc, buffer, mval);
@@ -1016,9 +1048,9 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter)
for(a=0; a<hits; a++) if(buffer[4*a+3] & 0xFFFF0000) has_bones= 1;
/* note; shift+alt goes to group-flush-selecting */
if(has_bones==0 && 0)
basact= mouse_select_menu(&vc, buffer, hits, mval);
else {
if(has_bones==0 && enumerate) {
basact= mouse_select_menu(C, &vc, buffer, hits, mval, extend);
} else {
static short lastmval[2]={-100, -100};
int donearest= 0;
@@ -1571,6 +1603,8 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
Object *obedit= CTX_data_edit_object(C);
Object *obact= CTX_data_active_object(C);
short extend= RNA_boolean_get(op->ptr, "extend");
short center= RNA_boolean_get(op->ptr, "center");
short enumerate= RNA_boolean_get(op->ptr, "enumerate");
view3d_operator_needs_opengl(C);
@@ -1590,7 +1624,7 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
else if(obact && obact->mode & OB_MODE_PARTICLE_EDIT)
PE_mouse_particles(C, event->mval, extend);
else
mouse_select(C, event->mval, extend, 0);
mouse_select(C, event->mval, extend, center, enumerate);
/* allowing tweaks */
return OPERATOR_PASS_THROUGH|OPERATOR_FINISHED;
@@ -1611,7 +1645,9 @@ void VIEW3D_OT_select(wmOperatorType *ot)
ot->flag= OPTYPE_UNDO;
/* properties */
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everyting first.");
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend selection instead of deselecting everything first.");
RNA_def_boolean(ot->srna, "center", 0, "Center", "Use the object center when selecting (object mode only).");
RNA_def_boolean(ot->srna, "enumerate", 0, "Enumerate", "List objects under the mouse (object mode only).");
}

View File

@@ -155,40 +155,37 @@ typedef struct PreviewImage {
#endif
/* ID from database */
#define ID_SCE MAKE_ID2('S', 'C')
#define ID_LI MAKE_ID2('L', 'I')
#define ID_OB MAKE_ID2('O', 'B')
#define ID_ME MAKE_ID2('M', 'E')
#define ID_CU MAKE_ID2('C', 'U')
#define ID_MB MAKE_ID2('M', 'B')
#define ID_MA MAKE_ID2('M', 'A')
#define ID_TE MAKE_ID2('T', 'E')
#define ID_IM MAKE_ID2('I', 'M')
#define ID_IK MAKE_ID2('I', 'K')
#define ID_WV MAKE_ID2('W', 'V')
#define ID_LT MAKE_ID2('L', 'T')
#define ID_SE MAKE_ID2('S', 'E')
#define ID_LF MAKE_ID2('L', 'F')
#define ID_LA MAKE_ID2('L', 'A')
#define ID_CA MAKE_ID2('C', 'A')
#define ID_IP MAKE_ID2('I', 'P')
#define ID_KE MAKE_ID2('K', 'E')
#define ID_WO MAKE_ID2('W', 'O')
#define ID_SCR MAKE_ID2('S', 'R')
#define ID_SCRN MAKE_ID2('S', 'N')
#define ID_VF MAKE_ID2('V', 'F')
#define ID_TXT MAKE_ID2('T', 'X')
#define ID_SO MAKE_ID2('S', 'O')
#define ID_GR MAKE_ID2('G', 'R')
#define ID_ID MAKE_ID2('I', 'D')
#define ID_AR MAKE_ID2('A', 'R')
#define ID_AC MAKE_ID2('A', 'C')
#define ID_SCRIPT MAKE_ID2('P', 'Y')
#define ID_NT MAKE_ID2('N', 'T')
#define ID_BR MAKE_ID2('B', 'R')
#define ID_PA MAKE_ID2('P', 'A')
#define ID_GD MAKE_ID2('G', 'D')
#define ID_WM MAKE_ID2('W', 'M')
#define ID_SCE MAKE_ID2('S', 'C') /* Scene */
#define ID_LI MAKE_ID2('L', 'I') /* Library */
#define ID_OB MAKE_ID2('O', 'B') /* Object */
#define ID_ME MAKE_ID2('M', 'E') /* Mesh */
#define ID_CU MAKE_ID2('C', 'U') /* Curve */
#define ID_MB MAKE_ID2('M', 'B') /* MetaBall */
#define ID_MA MAKE_ID2('M', 'A') /* Material */
#define ID_TE MAKE_ID2('T', 'E') /* Texture */
#define ID_IM MAKE_ID2('I', 'M') /* Image */
#define ID_WV MAKE_ID2('W', 'V') /* Wave (unused) */
#define ID_LT MAKE_ID2('L', 'T') /* Lattice */
#define ID_LA MAKE_ID2('L', 'A') /* Lamp */
#define ID_CA MAKE_ID2('C', 'A') /* Camera */
#define ID_IP MAKE_ID2('I', 'P') /* Ipo (depreciated, replaced by FCurves) */
#define ID_KE MAKE_ID2('K', 'E') /* Key (shape key) */
#define ID_WO MAKE_ID2('W', 'O') /* World */
#define ID_SCR MAKE_ID2('S', 'R') /* Screen */
#define ID_SCRN MAKE_ID2('S', 'N') /* (depreciated?) */
#define ID_VF MAKE_ID2('V', 'F') /* VectorFont */
#define ID_TXT MAKE_ID2('T', 'X') /* Text */
#define ID_SO MAKE_ID2('S', 'O') /* Sound */
#define ID_GR MAKE_ID2('G', 'R') /* Group */
#define ID_ID MAKE_ID2('I', 'D') /* (internal use only) */
#define ID_AR MAKE_ID2('A', 'R') /* Armature */
#define ID_AC MAKE_ID2('A', 'C') /* Action */
#define ID_SCRIPT MAKE_ID2('P', 'Y') /* Script (depreciated) */
#define ID_NT MAKE_ID2('N', 'T') /* NodeTree */
#define ID_BR MAKE_ID2('B', 'R') /* Brush */
#define ID_PA MAKE_ID2('P', 'A') /* ParticleSettings */
#define ID_GD MAKE_ID2('G', 'D') /* GreasePencil */
#define ID_WM MAKE_ID2('W', 'M') /* WindowManager */
/* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */
#define ID_SEQ MAKE_ID2('S', 'Q')