Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_select.c')
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c144
1 files changed, 90 insertions, 54 deletions
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index a7696d9fe31..a37e916064c 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -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];
-
- for(base=FIRSTBASE; base; base= base->next) {
- if (BASE_SELECTABLE(v3d, base)) {
- baseList[baseCount] = NULL;
-
- /* 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;
+ short ok;
+ LinkNode *linklist= 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);
- 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)
- if(baseCount<=1) return baseList[0];
+
+ 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;
@@ -1116,7 +1148,7 @@ static void mouse_select(bContext *C, short *mval, short extend, short obcenter)
WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, basact->object);
/* in weightpaint, we use selected bone to select vertexgroup, so no switch to new active object */
- if(basact->object->mode & OB_MODE_WEIGHT_PAINT) {
+ if(BASACT && BASACT->object->mode & OB_MODE_WEIGHT_PAINT) {
/* prevent activating */
basact= NULL;
}
@@ -1560,7 +1592,7 @@ void VIEW3D_OT_select_border(wmOperatorType *ot)
RNA_def_int(ot->srna, "ymin", 0, INT_MIN, INT_MAX, "Y Min", "", INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "ymax", 0, INT_MIN, INT_MAX, "Y Max", "", INT_MIN, INT_MAX);
- 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.");
}
/* ****** Mouse Select ****** */
@@ -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).");
}