diff options
Diffstat (limited to 'source/blender/editors')
47 files changed, 981 insertions, 294 deletions
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index a7879c7b70d..b2ce1c76f83 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -159,5 +159,7 @@ void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct AR void view3d_clipping_local(struct RegionView3D *rv3d, float mat[][4]); +Base *ED_view3d_give_base_under_cursor(struct bContext *C, short *mval); + #endif /* ED_VIEW3D_H */ diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 517a1e92f93..309cee7cb9c 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -61,6 +61,7 @@ struct ImageUser; struct uiWidgetColors; struct Tex; struct MTex; +struct ImBuf; typedef struct uiBut uiBut; typedef struct uiBlock uiBlock; @@ -343,6 +344,15 @@ void uiBlockSetXOfs (uiBlock *block, int xofs); int uiButGetRetVal (uiBut *but); +void uiButSetDragID(uiBut *but, struct ID *id); +void uiButSetDragRNA(uiBut *but, struct PointerRNA *ptr); +void uiButSetDragPath(uiBut *but, const char *path); +void uiButSetDragName(uiBut *but, const char *name); +void uiButSetDragValue(uiBut *but); +void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *ima, float scale); + +int UI_but_active_drop_name(struct bContext *C); + void uiButSetFlag (uiBut *but, int flag); void uiButClearFlag (uiBut *but, int flag); @@ -700,6 +710,7 @@ void uiItemPointerR(uiLayout *layout, char *name, int icon, struct PointerRNA *p void uiItemsFullEnumO(uiLayout *layout, char *opname, char *propname, struct IDProperty *properties, int context, int flag); void uiItemL(uiLayout *layout, char *name, int icon); /* label */ +void uiItemLDrag(uiLayout *layout, struct PointerRNA *ptr, char *name, int icon); /* label icon for dragging */ void uiItemM(uiLayout *layout, struct bContext *C, char *name, int icon, char *menuname); /* menu */ void uiItemV(uiLayout *layout, char *name, int icon, int argval); /* value */ void uiItemS(uiLayout *layout); /* separator */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 47a65812197..44c943fa4f4 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -2743,6 +2743,7 @@ uiBut *uiDefButO(uiBlock *block, int type, char *opname, int opcontext, char *st return but; } +/* if a1==1.0 then a2 is an extra icon blending factor (alpha 0.0 - 1.0) */ uiBut *uiDefIconBut(uiBlock *block, int type, int retval, int icon, short x1, short y1, short x2, short y2, void *poin, float min, float max, float a1, float a2, char *tip) { uiBut *but= ui_def_but(block, type, retval, "", x1, y1, x2, y2, poin, min, max, a1, a2, tip); @@ -3014,6 +3015,45 @@ int uiButGetRetVal(uiBut *but) return but->retval; } +void uiButSetDragID(uiBut *but, ID *id) +{ + but->dragtype= WM_DRAG_ID; + but->dragpoin= (void *)id; +} + +void uiButSetDragRNA(uiBut *but, PointerRNA *ptr) +{ + but->dragtype= WM_DRAG_RNA; + but->dragpoin= (void *)ptr; +} + +void uiButSetDragPath(uiBut *but, const char *path) +{ + but->dragtype= WM_DRAG_PATH; + but->dragpoin= (void *)path; +} + +void uiButSetDragName(uiBut *but, const char *name) +{ + but->dragtype= WM_DRAG_NAME; + but->dragpoin= (void *)name; +} + +/* value from button itself */ +void uiButSetDragValue(uiBut *but) +{ + but->dragtype= WM_DRAG_VALUE; +} + +void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale) +{ + but->dragtype= WM_DRAG_PATH; + but->icon= icon; /* no flag UI_HAS_ICON, so icon doesnt draw in button */ + but->dragpoin= (void *)path; + but->imb= imb; + but->imb_scale= scale; +} + PointerRNA *uiButGetOperatorPtrRNA(uiBut *but) { if(but->optype && !but->opptr) { diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 090f5d38279..5363cf8937c 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -20,9 +20,7 @@ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. + * Contributor(s): Blender Foundation * * ***** END GPL LICENSE BLOCK ***** */ diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 7273dc2360e..b84bdcd958e 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -89,6 +89,7 @@ typedef enum uiHandleButtonState { BUTTON_STATE_TEXT_EDITING, BUTTON_STATE_TEXT_SELECTING, BUTTON_STATE_MENU_OPEN, + BUTTON_STATE_WAIT_DRAG, BUTTON_STATE_EXIT } uiHandleButtonState; @@ -602,6 +603,53 @@ static void ui_apply_but_CHARTAB(bContext *C, uiBut *but, uiHandleButtonData *da } #endif +/* ****************** drag drop code *********************** */ + +static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, wmEvent *event) +{ + rcti rect; + int x= event->x, y= event->y; + + ui_window_to_block(ar, but->block, &x, &y); + + rect.xmin= but->x1; rect.xmax= but->x2; + rect.ymin= but->y1; rect.ymax= but->y2; + + if(but->imb); /* use button size itself */ + else if(but->flag & UI_ICON_LEFT) { + rect.xmax= rect.xmin + (rect.ymax-rect.ymin); + } + else { + int delta= (rect.xmax-rect.xmin) - (rect.ymax-rect.ymin); + rect.xmin += delta/2; + rect.xmax -= delta/2; + } + + return BLI_in_rcti(&rect, x, y); +} + +#define UI_DRAG_THRESHOLD 3 +static int ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event) +{ + /* prevent other WM gestures to start while we try to drag */ + WM_gestures_remove(C); + + if( ABS(data->dragstartx - event->x) + ABS(data->dragstarty - event->y) > UI_DRAG_THRESHOLD ) { + wmDrag *drag; + + button_activate_state(C, but, BUTTON_STATE_EXIT); + data->cancel= 1; + + drag= WM_event_start_drag(C, but->icon, but->dragtype, but->dragpoin, ui_get_but_val(but)); + if(but->imb) + WM_event_drag_image(drag, but->imb, but->imb_scale, but->x2-but->x1, but->y2-but->y1); + return 1; + } + + return 0; +} + +/* ********************** linklines *********************** */ static void ui_delete_active_linkline(uiBlock *block) { @@ -894,6 +942,30 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut but->editcumap= editcumap; } +/* ******************* drop event ******************** */ + +/* only call if event type is EVT_DROP */ +static void ui_but_drop(bContext *C, wmEvent *event, uiBut *but, uiHandleButtonData *data) +{ + wmDrag *wmd; + ListBase *drags= event->customdata; /* drop event type has listbase customdata by default */ + + for(wmd= drags->first; wmd; wmd= wmd->next) { + if(wmd->type==WM_DRAG_ID) { + /* align these types with UI_but_active_drop_name */ + if(ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { + ID *id= (ID *)wmd->poin; + + if(but->poin==NULL && but->rnapoin.data==NULL); + button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); + BLI_strncpy(data->str, id->name+2, data->maxlen); + button_activate_state(C, but, BUTTON_STATE_EXIT); + } + } + } + +} + /* ******************* copy and paste ******************** */ /* c = copy, v = paste */ @@ -1984,13 +2056,40 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, wmEv static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event) { + if(data->state == BUTTON_STATE_HIGHLIGHT) { + + /* first handle click on icondrag type button */ + if(event->type==LEFTMOUSE && but->dragpoin) { + if(ui_but_mouse_inside_icon(but, data->region, event)) { + button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG); + data->dragstartx= event->x; + data->dragstarty= event->y; + return WM_UI_HANDLER_BREAK; + } + } + if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val==KM_PRESS) { button_activate_state(C, but, BUTTON_STATE_EXIT); return WM_UI_HANDLER_BREAK; } } - + else if(data->state == BUTTON_STATE_WAIT_DRAG) { + + /* this function also ends state */ + if(ui_but_start_drag(C, but, data, event)) { + return WM_UI_HANDLER_BREAK; + } + + /* pass on release as press for other keymaps XXX hack alert! */ + if(event->type==LEFTMOUSE && event->val==KM_RELEASE) { + button_activate_state(C, but, BUTTON_STATE_EXIT); + event->val= KM_PRESS; + return WM_UI_HANDLER_CONTINUE; + } + + } + return WM_UI_HANDLER_CONTINUE; } @@ -2554,10 +2653,23 @@ static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut return retval; } + static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wmEvent *event) { if(data->state == BUTTON_STATE_HIGHLIGHT) { + + /* first handle click on icondrag type button */ + if(event->type==LEFTMOUSE && but->dragpoin && event->val==KM_PRESS) { + if(ui_but_mouse_inside_icon(but, data->region, event)) { + button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG); + data->dragstartx= event->x; + data->dragstarty= event->y; + return WM_UI_HANDLER_BREAK; + } + } + + /* regular open menu */ if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val==KM_PRESS) { button_activate_state(C, but, BUTTON_STATE_MENU_OPEN); return WM_UI_HANDLER_BREAK; @@ -2598,6 +2710,26 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wm } } } + else if(data->state == BUTTON_STATE_WAIT_DRAG) { + + /* this function also ends state */ + if(ui_but_start_drag(C, but, data, event)) { + return WM_UI_HANDLER_BREAK; + } + + /* outside icon quit, not needed if drag activated */ + if(0==ui_but_mouse_inside_icon(but, data->region, event)) { + button_activate_state(C, but, BUTTON_STATE_EXIT); + data->cancel= 1; + return WM_UI_HANDLER_BREAK; + } + + if(event->type==LEFTMOUSE && event->val==KM_RELEASE) { + button_activate_state(C, but, BUTTON_STATE_MENU_OPEN); + return WM_UI_HANDLER_BREAK; + } + + } return WM_UI_HANDLER_CONTINUE; } @@ -3747,6 +3879,10 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event) ui_but_copy_paste(C, but, data, (event->type == CKEY)? 'c': 'v'); return WM_UI_HANDLER_BREAK; } + /* handle drop */ + else if(event->type == EVT_DROP) { + ui_but_drop (C, event, but, data); + } /* handle keyframing */ else if(event->type == IKEY && event->val == KM_PRESS) { if(event->alt) @@ -3931,6 +4067,21 @@ int ui_button_is_active(ARegion *ar) return (ui_but_find_activated(ar) != NULL); } +/* returns TRUE if highlighted button allows drop of names */ +/* called in region context */ +int UI_but_active_drop_name(bContext *C) +{ + ARegion *ar= CTX_wm_region(C); + uiBut *but= ui_but_find_activated(ar); + + if(but) { + if(ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) + return 1; + } + + return 0; +} + static void ui_blocks_set_tooltips(ARegion *ar, int enable) { uiBlock *block; @@ -4018,8 +4169,8 @@ static uiBut *ui_but_find_mouse_over(wmWindow *win, ARegion *ar, int x, int y) uiBut *but, *butover= NULL; int mx, my; - if(!win->active) - return NULL; +// if(!win->active) +// return NULL; if(!ui_mouse_inside_region(ar, x, y)) return NULL; @@ -4029,7 +4180,10 @@ static uiBut *ui_but_find_mouse_over(wmWindow *win, ARegion *ar, int x, int y) ui_window_to_block(ar, block, &mx, &my); for(but=block->buttons.first; but; but= but->next) { - if(ELEM4(but->type, LABEL, ROUNDBOX, SEPR, LISTBOX)) + /* note, LABEL is included for hilights, this allows drags */ + if(but->type==LABEL && but->dragpoin==NULL) + continue; + if(ELEM3(but->type, ROUNDBOX, SEPR, LISTBOX)) continue; if(but->flag & UI_HIDDEN) continue; @@ -4047,8 +4201,8 @@ static uiBut *ui_list_find_mouse_over(wmWindow *win, ARegion *ar, int x, int y) uiBut *but; int mx, my; - if(!win->active) - return NULL; +// if(!win->active) +// return NULL; if(!ui_mouse_inside_region(ar, x, y)) return NULL; @@ -4095,8 +4249,9 @@ static void button_timers_tooltip_remove(bContext *C, uiBut *but) } } -static void button_tooltip_timer_reset(uiBut *but) +static void button_tooltip_timer_reset(bContext *C, uiBut *but) { + wmWindowManager *wm= CTX_wm_manager(C); uiHandleButtonData *data; data= but->active; @@ -4108,7 +4263,8 @@ static void button_tooltip_timer_reset(uiBut *but) if(U.flag & USER_TOOLTIPS) if(!but->block->tooltipdisabled) - data->tooltiptimer= WM_event_add_timer(data->wm, data->window, TIMER, BUTTON_TOOLTIP_DELAY); + if(!wm->drags.first) + data->tooltiptimer= WM_event_add_timer(data->wm, data->window, TIMER, BUTTON_TOOLTIP_DELAY); } static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state) @@ -4123,7 +4279,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s if(state == BUTTON_STATE_HIGHLIGHT) { but->flag &= ~UI_SELECT; - button_tooltip_timer_reset(but); + button_tooltip_timer_reset(C, but); /* automatic open pulldown block timer */ if(ELEM3(but->type, BLOCK, PULLDOWN, ICONTEXTROW)) { @@ -4190,6 +4346,11 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s WM_event_remove_ui_handler(&data->window->modalhandlers, ui_handler_region_menu, NULL, data); } } + + /* wait for mousemove to enable drag */ + if(state == BUTTON_STATE_WAIT_DRAG) { + but->flag &= ~UI_SELECT; + } data->state= state; @@ -4449,7 +4610,7 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but) else if(event->x!=event->prevx || event->y!=event->prevy) { /* re-enable tooltip on mouse move */ ui_blocks_set_tooltips(ar, 1); - button_tooltip_timer_reset(but); + button_tooltip_timer_reset(C, but); } break; @@ -4555,8 +4716,8 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but) retval= WM_UI_HANDLER_CONTINUE; } else { - ui_do_button(C, block, but, event); - retval= WM_UI_HANDLER_BREAK; + retval= ui_do_button(C, block, but, event); + // retval= WM_UI_HANDLER_BREAK; XXX why ? } if(data->state == BUTTON_STATE_EXIT) { diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 296b1e3ca57..6c4f5564fd7 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -613,6 +613,7 @@ static void init_iconfile_list(struct ListBase *list) for(; i>=0; i--){ MEM_freeN(dir[i].relname); + MEM_freeN(dir[i].path); if (dir[i].string) MEM_freeN(dir[i].string); } free(dir); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index cd89650d750..47892e45a02 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -46,6 +46,7 @@ struct uiLayout; struct bContextStore; struct Scene; struct ID; +struct ImBuf; /* ****************** general defines ************** */ @@ -226,8 +227,14 @@ struct uiBut { int opcontext; struct IDProperty *opproperties; struct PointerRNA *opptr; + + /* Draggable data, type is WM_DRAG_... */ + int dragtype; + void *dragpoin; + struct ImBuf *imb; + float imb_scale; - /* active button data */ + /* active button data */ struct uiHandleButtonData *active; char *editstr; diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 57102f4ad50..52ea0a99762 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1321,7 +1321,7 @@ void uiItemM(uiLayout *layout, bContext *C, char *name, int icon, char *menuname } /* label item */ -void uiItemL(uiLayout *layout, char *name, int icon) +static uiBut *uiItemL_(uiLayout *layout, char *name, int icon) { uiBlock *block= layout->root->block; uiBut *but; @@ -1342,8 +1342,25 @@ void uiItemL(uiLayout *layout, char *name, int icon) but= uiDefIconBut(block, LABEL, 0, icon, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); else but= uiDefBut(block, LABEL, 0, (char*)name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + + return but; +} + +void uiItemL(uiLayout *layout, char *name, int icon) +{ + uiItemL_(layout, name, icon); +} + +void uiItemLDrag(uiLayout *layout, PointerRNA *ptr, char *name, int icon) +{ + uiBut *but= uiItemL_(layout, name, icon); + + if(ptr && ptr->type) + if(RNA_struct_is_ID(ptr->type)) + uiButSetDragID(but, ptr->id.data); } + /* value item */ void uiItemV(uiLayout *layout, char *name, int icon, int argval) { diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index a90ddd991ca..264bc724bce 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -360,8 +360,9 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str but= uiDefBlockButN(block, id_search_menu, MEM_dupallocN(template), "", 0, 0, UI_UNIT_X*1.6, UI_UNIT_Y, "Browse ID data"); if(type) { but->icon= RNA_struct_ui_icon(type); - but->flag|= UI_HAS_ICON; - but->flag|= UI_ICON_LEFT; + /* default dragging of icon for id browse buttons */ + uiButSetDragID(but, id); + uiButSetFlag(but, UI_HAS_ICON|UI_ICON_LEFT); } if((idfrom && idfrom->lib)) @@ -2215,7 +2216,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe uiBlockSetEmboss(block, UI_EMBOSS); } else - uiItemL(sub, name, icon); + uiItemLDrag(sub, itemptr, name, icon); /* fails, backdrop LISTROW... */ /* free name */ if(namebuf) @@ -2299,6 +2300,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propna icon= list_item_icon_get(C, &itemptr, rnaicon); but= uiDefIconButR(block, LISTROW, 0, icon, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, ""); uiButSetFlag(but, UI_BUT_NO_TOOLTIP); + i++; } diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index a3c754c10e5..d9e8f6f55d2 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -755,6 +755,9 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect else alpha= 0.5f; } + /* extra feature allows more alpha blending */ + if(but->type==LABEL && but->a1==1.0f) alpha *= but->a2; + glEnable(GL_BLEND); if(icon && icon!=ICON_BLANK1) { @@ -784,8 +787,14 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect xs= (rect->xmin+rect->xmax- height)/2; ys= (rect->ymin+rect->ymax- height)/2; } - - UI_icon_draw_aspect(xs, ys, icon, aspect, alpha); + + /* to indicate draggable */ + if(but->dragpoin && (but->flag & UI_ACTIVE)) { + float rgb[3]= {1.25f, 1.25f, 1.25f}; + UI_icon_draw_aspect_color(xs, ys, icon, aspect, rgb); + } + else + UI_icon_draw_aspect(xs, ys, icon, aspect, alpha); } if(but->flag & UI_ICON_SUBMENU) { diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 050152821f5..90764388029 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -46,6 +46,7 @@ #include "BKE_depsgraph.h" #include "BKE_displist.h" #include "BKE_global.h" +#include "BKE_library.h" #include "BKE_material.h" #include "BKE_mesh.h" #include "BKE_report.h" @@ -62,6 +63,7 @@ #include "ED_mesh.h" #include "ED_object.h" +#include "ED_uvedit.h" #include "ED_view3d.h" #include "RE_render_ext.h" @@ -309,6 +311,68 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + Scene *scene= CTX_data_scene(C); + Base *base= ED_view3d_give_base_under_cursor(C, event->mval); + Image *ima; + Mesh *me; + Object *obedit; + int exitmode= 0; + char name[32]; + + /* check input variables */ + RNA_string_get(op->ptr, "name", name); + ima= (Image *)find_id("IM", name); + if(base==NULL || base->object->type!=OB_MESH || ima==NULL) { + BKE_report(op->reports, RPT_ERROR, "Not a Mesh or no Image."); + return OPERATOR_CANCELLED; + } + + /* turn mesh in editmode */ + /* BKE_mesh_get/end_editmesh: ED_uvedit_assign_image also calls this */ + + obedit= base->object; + me= obedit->data; + if(me->edit_mesh==NULL) { + make_editMesh(scene, obedit); + exitmode= 1; + } + if(me->edit_mesh==NULL) + return OPERATOR_CANCELLED; + + ED_uvedit_assign_image(scene, obedit, ima, NULL); + + if(exitmode) { + load_editMesh(scene, obedit); + free_editMesh(me->edit_mesh); + MEM_freeN(me->edit_mesh); + me->edit_mesh= NULL; + } + + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + + return OPERATOR_FINISHED; +} + +void MESH_OT_drop_named_image(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Assign Image to UV Texture"; + ot->description= "Assigns Image to active UV layer, or creates a UV layer"; + ot->idname= "MESH_OT_drop_named_image"; + + /* api callbacks */ + ot->poll= layers_poll; + ot->invoke= drop_named_image_invoke; + + /* flags */ + ot->flag= OPTYPE_UNDO; + + /* properties */ + RNA_def_string(ot->srna, "name", "Image", 24, "Name", "Image name to assign."); +} + static int uv_texture_remove_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index d06ad8cd384..950da02b50d 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -234,7 +234,7 @@ void MESH_OT_rip(struct wmOperatorType *ot); void MESH_OT_shape_propagate_to_all(struct wmOperatorType *ot); void MESH_OT_blend_from_shape(struct wmOperatorType *ot); -/* ******************* mesh_layers.c */ +/* ******************* mesh_data.c */ void MESH_OT_uv_texture_add(struct wmOperatorType *ot); void MESH_OT_uv_texture_remove(struct wmOperatorType *ot); @@ -242,6 +242,7 @@ void MESH_OT_vertex_color_add(struct wmOperatorType *ot); void MESH_OT_vertex_color_remove(struct wmOperatorType *ot); void MESH_OT_sticky_add(struct wmOperatorType *ot); void MESH_OT_sticky_remove(struct wmOperatorType *ot); +void MESH_OT_drop_named_image(struct wmOperatorType *ot); void MESH_OT_edgering_select(struct wmOperatorType *ot); void MESH_OT_loopcut(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index d3e639be9d3..c3bb8dd061d 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -147,7 +147,8 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_vertex_color_remove); WM_operatortype_append(MESH_OT_sticky_add); WM_operatortype_append(MESH_OT_sticky_remove); - + WM_operatortype_append(MESH_OT_drop_named_image); + WM_operatortype_append(MESH_OT_edgering_select); WM_operatortype_append(MESH_OT_loopcut); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index ee88a192e0a..dea8b13e9cc 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1693,6 +1693,70 @@ void OBJECT_OT_duplicate(wmOperatorType *ot) RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX); } +/* **************** add named object, for dragdrop ************* */ + +/* contextual operator dupli */ +static int add_named_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Base *basen, *base; + Object *ob; + int linked= RNA_boolean_get(op->ptr, "linked"); + int dupflag= (linked)? 0: U.dupflag; + char name[32]; + + /* find object, create fake base */ + RNA_string_get(op->ptr, "name", name); + ob= (Object *)find_id("OB", name); + if(ob==NULL) + return OPERATOR_CANCELLED; + + base= MEM_callocN(sizeof(Base), "duplibase"); + base->object= ob; + base->flag= ob->flag; + + /* prepare dupli */ + clear_id_newpoins(); + clear_sca_new_poins(); /* sensor/contr/act */ + + basen= object_add_duplicate_internal(scene, base, dupflag); + basen->lay= basen->object->lay= scene->lay; + + ED_object_location_from_view(C, basen->object->loc); + ED_base_object_activate(C, basen); + + copy_object_set_idnew(C, dupflag); + + DAG_scene_sort(scene); + DAG_ids_flush_update(0); + + MEM_freeN(base); + + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_add_named(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Named Object"; + ot->description = "Add named object."; + ot->idname= "OBJECT_OT_add_named"; + + /* api callbacks */ + ot->exec= add_named_exec; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data."); + RNA_def_string(ot->srna, "name", "Cube", 24, "Name", "Object name to add."); +} + + + /**************************** Join *************************/ static int join_poll(bContext *C) { diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index a11ead1fe9d..06768404d7e 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -69,6 +69,7 @@ void OBJECT_OT_make_single_user(struct wmOperatorType *ot); void OBJECT_OT_make_links_scene(struct wmOperatorType *ot); void OBJECT_OT_make_links_data(struct wmOperatorType *ot); void OBJECT_OT_move_to_layer(struct wmOperatorType *ot); +void OBJECT_OT_drop_named_material(struct wmOperatorType *ot); /* object_edit.c */ void OBJECT_OT_mode_set(struct wmOperatorType *ot); @@ -95,6 +96,7 @@ void OBJECT_OT_select_name(struct wmOperatorType *ot); /* object_add.c */ void OBJECT_OT_add(struct wmOperatorType *ot); +void OBJECT_OT_add_named(struct wmOperatorType *ot); void OBJECT_OT_curve_add(struct wmOperatorType *ot); void OBJECT_OT_surface_add(struct wmOperatorType *ot); void OBJECT_OT_metaball_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 80992887e97..b9935fafb74 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -121,6 +121,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_lamp_add); WM_operatortype_append(OBJECT_OT_camera_add); WM_operatortype_append(OBJECT_OT_add); + WM_operatortype_append(OBJECT_OT_add_named); WM_operatortype_append(OBJECT_OT_effector_add); WM_operatortype_append(OBJECT_OT_group_instance_add); WM_operatortype_append(OBJECT_OT_metaball_add); @@ -202,6 +203,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_hook_recenter); WM_operatortype_append(OBJECT_OT_bake_image); + WM_operatortype_append(OBJECT_OT_drop_named_material); } void ED_operatormacros_object(void) @@ -224,6 +226,15 @@ void ED_operatormacros_object(void) otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", PROP_EDIT_OFF); } + + /* XXX */ + ot= WM_operatortype_append_macro("OBJECT_OT_add_named_cursor", "Add named object at cursor", OPTYPE_UNDO|OPTYPE_REGISTER); + if(ot) { + RNA_def_string(ot->srna, "name", "Cube", 24, "Name", "Object name to add."); + + WM_operatortype_macro_define(ot, "VIEW3D_OT_cursor3d"); + WM_operatortype_macro_define(ot, "OBJECT_OT_add_named"); + } } static int object_mode_poll(bContext *C) @@ -308,7 +319,7 @@ void ED_keymap_object(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "OBJECT_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "OBJECT_OT_duplicate_move_linked", DKEY, KM_PRESS, KM_ALT, 0); - + WM_keymap_add_item(keymap, "OBJECT_OT_join", JKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "OBJECT_OT_convert", CKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "OBJECT_OT_proxy_make", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 46b90725d7f..7f4100c01ed 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -91,6 +91,7 @@ #include "ED_curve.h" #include "ED_object.h" #include "ED_screen.h" +#include "ED_view3d.h" #include "object_intern.h" @@ -1827,3 +1828,41 @@ void OBJECT_OT_make_single_user(wmOperatorType *ot) RNA_def_boolean(ot->srna, "texture", 0, "Textures", "Make textures local to each material"); RNA_def_boolean(ot->srna, "animation", 0, "Animation Data", "Make animation data local to each object"); } + +static int drop_named_material_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + Base *base= ED_view3d_give_base_under_cursor(C, event->mval); + Material *ma; + char name[32]; + + RNA_string_get(op->ptr, "name", name); + ma= (Material *)find_id("MA", name); + if(base==NULL || ma==NULL) + return OPERATOR_CANCELLED; + + assign_material(base->object, ma, 1); + + WM_event_add_notifier(C, NC_OBJECT|ND_SHADING, base->object); + return OPERATOR_FINISHED; +} + +/* used for dropbox */ +/* assigns to object under cursor, only first material slot */ +void OBJECT_OT_drop_named_material(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Drop Named Material on Object"; + ot->description = ""; + ot->idname= "OBJECT_OT_drop_named_material"; + + /* api callbacks */ + ot->invoke= drop_named_material_invoke; + ot->poll= ED_operator_scene_editable; + + /* flags */ + ot->flag= OPTYPE_UNDO; + + /* properties */ + RNA_def_string(ot->srna, "name", "Material", 24, "Name", "Material name to assign."); +} diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index a7a3754d16f..93f6542f9cb 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -624,8 +624,8 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int if(ar->next==NULL && alignment!=RGN_ALIGN_QSPLIT) alignment= RGN_ALIGN_NONE; - prefsizex= ar->type->minsizex; - prefsizey= ar->type->minsizey; + prefsizex= ar->sizex?ar->sizex:ar->type->prefsizex; + prefsizey= ar->sizey?ar->sizey:ar->type->prefsizey; /* hidden is user flag */ if(ar->flag & RGN_FLAG_HIDDEN); @@ -1230,11 +1230,11 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, char *contex if(vertical) { w= v2d->cur.xmax - v2d->cur.xmin; - em= (ar->type->minsizex)? 10: 20; + em= (ar->type->prefsizex)? 10: 20; } else { w= UI_PANEL_WIDTH; - em= (ar->type->minsizex)? 10: 20; + em= (ar->type->prefsizex)? 10: 20; } x= 0; diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 786f9ee9e3f..048ade764d5 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -468,6 +468,7 @@ static void screen_copy(bScreen *to, bScreen *from) sa->spacedata.first= sa->spacedata.last= NULL; sa->regionbase.first= sa->regionbase.last= NULL; sa->actionzones.first= sa->actionzones.last= NULL; + sa->handlers.first= sa->handlers.last= NULL; area_copy_data(sa, saf, 0); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index bc9e7239f01..7f6f1c34760 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1384,10 +1384,18 @@ static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event) rmd->origx= event->x; rmd->origy= event->y; rmd->maxsize = area_max_regionsize(rmd->sa, rmd->ar, rmd->edge); + + /* if not set we do now, otherwise it uses type */ + if(rmd->ar->sizex==0) + rmd->ar->sizex= rmd->ar->type->prefsizex; + if(rmd->ar->sizey==0) + rmd->ar->sizey= rmd->ar->type->prefsizey; + + /* now copy to regionmovedata */ if(rmd->edge=='l' || rmd->edge=='r') { - rmd->origval= rmd->ar->type->minsizex; + rmd->origval= rmd->ar->sizex; } else { - rmd->origval= rmd->ar->type->minsizey; + rmd->origval= rmd->ar->sizey; } CLAMP(rmd->maxsize, 0, 1000); @@ -1413,11 +1421,11 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event) delta= event->x - rmd->origx; if(rmd->edge=='l') delta= -delta; - rmd->ar->type->minsizex= rmd->origval + delta; - CLAMP(rmd->ar->type->minsizex, 0, rmd->maxsize); + rmd->ar->sizex= rmd->origval + delta; + CLAMP(rmd->ar->sizex, 0, rmd->maxsize); - if(rmd->ar->type->minsizex < 24) { - rmd->ar->type->minsizex= rmd->origval; + if(rmd->ar->sizex < 24) { + rmd->ar->sizex= rmd->origval; if(!(rmd->ar->flag & RGN_FLAG_HIDDEN)) ED_region_toggle_hidden(C, rmd->ar); } @@ -1428,11 +1436,11 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event) delta= event->y - rmd->origy; if(rmd->edge=='b') delta= -delta; - rmd->ar->type->minsizey= rmd->origval + delta; - CLAMP(rmd->ar->type->minsizey, 0, rmd->maxsize); + rmd->ar->sizey= rmd->origval + delta; + CLAMP(rmd->ar->sizey, 0, rmd->maxsize); - if(rmd->ar->type->minsizey < 24) { - rmd->ar->type->minsizey= rmd->origval; + if(rmd->ar->sizey < 24) { + rmd->ar->sizey= rmd->origval; if(!(rmd->ar->flag & RGN_FLAG_HIDDEN)) ED_region_toggle_hidden(C, rmd->ar); } diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 803a7aee8cc..26464dcfab8 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -475,7 +475,7 @@ void ED_spacetype_action(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype action region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; art->init= action_header_area_init; @@ -487,7 +487,7 @@ void ED_spacetype_action(void) /* regions: channels */ art= MEM_callocN(sizeof(ARegionType), "spacetype action region"); art->regionid = RGN_TYPE_CHANNELS; - art->minsizex= 200; + art->prefsizex= 200; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D; art->init= action_channel_area_init; diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index c1fec6cd1de..492080eda52 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -105,10 +105,12 @@ void ED_spacetypes_init(void) UI_view2d_operatortypes(); UI_buttons_operatortypes(); + /* register operators */ spacetypes = BKE_spacetypes_list(); - for(type=spacetypes->first; type; type=type->next) - type->operatortypes(); - + for(type=spacetypes->first; type; type=type->next) { + if(type->operatortypes) + type->operatortypes(); + } /* Macros's must go last since they reference other operators * maybe we'll need to have them go after python operators too? */ @@ -117,6 +119,14 @@ void ED_spacetypes_init(void) ED_operatormacros_node(); ED_operatormacros_object(); ED_operatormacros_file(); + + /* register dropboxes (can use macros) */ + spacetypes = BKE_spacetypes_list(); + for(type=spacetypes->first; type; type=type->next) { + if(type->dropboxes) + type->dropboxes(); + } + } /* called in wm.c */ diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 39990df34a7..d94170533cf 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -787,10 +787,10 @@ void buttons_context_draw(const bContext *C, uiLayout *layout) if(name) { if(!ELEM(sbuts->mainb, BCONTEXT_RENDER, BCONTEXT_SCENE) && ptr->type == &RNA_Scene) - uiItemL(row, "", icon); /* save some space */ + uiItemLDrag(row, ptr, "", icon); /* save some space */ else - uiItemL(row, name, icon); - + uiItemLDrag(row, ptr, name, icon); + if(name != namebuf) MEM_freeN(name); } diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 17f5c6bf7c3..6f52a84ce80 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -396,7 +396,7 @@ void ED_spacetype_buttons(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype buttons region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= BUTS_HEADERY; + art->prefsizey= BUTS_HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; art->init= buttons_header_area_init; diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index e9e87a865ef..ea1d6667d11 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -366,7 +366,7 @@ void ED_spacetype_console(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype console region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_HEADER; art->init= console_header_area_init; diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index af0bf9413df..5db17d8bc7c 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -320,8 +320,9 @@ static int get_file_icon(struct direntry *file) return ICON_FILE_BLANK; } -static void file_draw_icon(int sx, int sy, int icon, int width, int height) +static void file_draw_icon(uiBlock *block, char *path, int sx, int sy, int icon, int width, int height) { + uiBut *but; float x,y; float alpha=1.0f; @@ -329,10 +330,9 @@ static void file_draw_icon(int sx, int sy, int icon, int width, int height) y = (float)(sy-height); if (icon == ICON_FILE_BLANK) alpha = 0.375f; - - glEnable(GL_BLEND); - - UI_icon_draw_aspect(x, y, icon, 1.f, alpha); + + but= uiDefIconBut(block, LABEL, 0, icon, x, y, width, height, NULL, 0.0, 0.0, 0, 0, ""); + uiButSetDragPath(but, path); } @@ -364,62 +364,67 @@ void file_calc_previews(const bContext *C, ARegion *ar) UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height+V2D_SCROLL_HEIGHT); } -static void file_draw_preview(int sx, int sy, ImBuf *imb, FileLayout *layout, short dropshadow) +static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int sy, ImBuf *imb, FileLayout *layout, short dropshadow) { if (imb) { - float fx, fy; - float dx, dy; - int xco, yco; - float scaledx, scaledy; - float scale; - int ex, ey; - - if ( (imb->x > layout->prv_w) || (imb->y > layout->prv_h) ) { - if (imb->x > imb->y) { - scaledx = (float)layout->prv_w; - scaledy = ( (float)imb->y/(float)imb->x )*layout->prv_w; - scale = scaledx/imb->x; - } - else { - scaledy = (float)layout->prv_h; - scaledx = ( (float)imb->x/(float)imb->y )*layout->prv_h; - scale = scaledy/imb->y; - } - } else { - scaledx = (float)imb->x; - scaledy = (float)imb->y; - scale = 1.0; + uiBut *but; + float fx, fy; + float dx, dy; + int xco, yco; + float scaledx, scaledy; + float scale; + int ex, ey; + + if ( (imb->x > layout->prv_w) || (imb->y > layout->prv_h) ) { + if (imb->x > imb->y) { + scaledx = (float)layout->prv_w; + scaledy = ( (float)imb->y/(float)imb->x )*layout->prv_w; + scale = scaledx/imb->x; } - ex = (int)scaledx; - ey = (int)scaledy; - fx = ((float)layout->prv_w - (float)ex)/2.0f; - fy = ((float)layout->prv_h - (float)ey)/2.0f; - dx = (fx + 0.5f + layout->prv_border_x); - dy = (fy + 0.5f - layout->prv_border_y); - xco = (float)sx + dx; - yco = (float)sy - layout->prv_h + dy; - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - /* shadow */ - if (dropshadow) - uiDrawBoxShadow(220, xco, yco, xco + ex, yco + ey); - - glEnable(GL_BLEND); - - /* the image */ - glColor4f(1.0, 1.0, 1.0, 1.0); - glaDrawPixelsTexScaled(xco, yco, imb->x, imb->y, GL_UNSIGNED_BYTE, imb->rect, scale, scale); - - /* border */ - if (dropshadow) { - glColor4f(0.0f, 0.0f, 0.0f, 0.4f); - fdrawbox(xco, yco, xco + ex, yco + ey); + else { + scaledy = (float)layout->prv_h; + scaledx = ( (float)imb->x/(float)imb->y )*layout->prv_h; + scale = scaledy/imb->y; } - - glDisable(GL_BLEND); - imb = 0; + } else { + scaledx = (float)imb->x; + scaledy = (float)imb->y; + scale = 1.0; + } + ex = (int)scaledx; + ey = (int)scaledy; + fx = ((float)layout->prv_w - (float)ex)/2.0f; + fy = ((float)layout->prv_h - (float)ey)/2.0f; + dx = (fx + 0.5f + layout->prv_border_x); + dy = (fy + 0.5f - layout->prv_border_y); + xco = (float)sx + dx; + yco = (float)sy - layout->prv_h + dy; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + /* shadow */ + if (dropshadow) + uiDrawBoxShadow(220, xco, yco, xco + ex, yco + ey); + + glEnable(GL_BLEND); + + /* the image */ + glColor4f(1.0, 1.0, 1.0, 1.0); + glaDrawPixelsTexScaled(xco, yco, imb->x, imb->y, GL_UNSIGNED_BYTE, imb->rect, scale, scale); + + /* border */ + if (dropshadow) { + glColor4f(0.0f, 0.0f, 0.0f, 0.4f); + fdrawbox(xco, yco, xco + ex, yco + ey); } + + /* dragregion */ + but= uiDefBut(block, LABEL, 0, "", xco, yco, ex, ey, NULL, 0.0, 0.0, 0, 0, ""); + uiButSetDragImage(but, file->path, get_file_icon(file), imb, scale); + + glDisable(GL_BLEND); + imb = 0; + } } static void renamebutton_cb(bContext *C, void *arg1, char *oldname) @@ -491,6 +496,7 @@ void file_draw_list(const bContext *C, ARegion *ar) struct FileList* files = sfile->files; struct direntry *file; ImBuf *imb; + uiBlock *block = uiBeginBlock(C, ar, "FileNames", UI_EMBOSS); int numfiles; int numfiles_layout; int colorid = 0; @@ -526,10 +532,10 @@ void file_draw_list(const bContext *C, ARegion *ar) if (params->active_file == i) { if (file->flags & ACTIVE) colorid= TH_HILITE; else colorid = TH_BACK; - draw_tile(sx-2, sy-3, layout->tile_w+2, sfile->layout->tile_h+layout->tile_border_y, colorid,20); + draw_tile(sx, sy-3, layout->tile_w+4, sfile->layout->tile_h+layout->tile_border_y, colorid,20); } else if (file->flags & ACTIVE) { colorid = TH_HILITE; - draw_tile(sx-2, sy-3, layout->tile_w+2, sfile->layout->tile_h+layout->tile_border_y, colorid,0); + draw_tile(sx, sy-3, layout->tile_w+4, sfile->layout->tile_h+layout->tile_border_y, colorid,0); } } @@ -546,11 +552,11 @@ void file_draw_list(const bContext *C, ARegion *ar) is_icon = 1; } - file_draw_preview(sx, sy, imb, layout, !is_icon && (file->flags & IMAGEFILE)); + file_draw_preview(block, file, sx, sy, imb, layout, !is_icon && (file->flags & IMAGEFILE)); } else { - file_draw_icon(spos, sy-3, get_file_icon(file), ICON_DEFAULT_WIDTH, ICON_DEFAULT_WIDTH); - spos += ICON_DEFAULT_WIDTH + 4; + file_draw_icon(block, file->path, spos, sy-3, get_file_icon(file), ICON_DEFAULT_WIDTH, ICON_DEFAULT_WIDTH); + spos += ICON_DEFAULT_WIDTH + 4; } UI_ThemeColor4(TH_TEXT); @@ -558,15 +564,13 @@ void file_draw_list(const bContext *C, ARegion *ar) sw = file_string_width(file->relname); if (file->flags & EDITING) { int but_width = (FILE_IMGDISPLAY == params->display) ? layout->tile_w : layout->column_widths[COLUMN_NAME]; - uiBlock *block = uiBeginBlock(C, ar, "FileName", UI_EMBOSS); + uiBut *but = uiDefBut(block, TEX, 1, "", spos, sy-layout->tile_h-3, but_width, layout->textheight*2, file->relname, 1.0f, (float)FILE_MAX,0,0,""); uiButSetRenameFunc(but, renamebutton_cb, file); if ( 0 == uiButActiveOnly(C, block, but)) { file->flags &= ~EDITING; } - uiEndBlock(C, block); - uiDrawBlock(C, block); } else { float name_width = (FILE_IMGDISPLAY == params->display) ? layout->tile_w : sw; file_draw_string(spos, sy, file->relname, name_width, layout->tile_h, FILE_SHORTEN_END); @@ -621,6 +625,10 @@ void file_draw_list(const bContext *C, ARegion *ar) if (!sfile->loadimage_timer) sfile->loadimage_timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER1, 1.0/30.0); /* max 30 frames/sec. */ + + uiEndBlock(C, block); + uiDrawBlock(C, block); + } diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 647c1d2be18..93230c79b19 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -588,7 +588,7 @@ int file_exec(bContext *C, wmOperator *exec_op) RNA_string_set(op->ptr, "filename", sfile->params->file); BLI_strncpy(name, sfile->params->dir, sizeof(name)); RNA_string_set(op->ptr, "directory", name); - strcat(name, sfile->params->file); + strcat(name, sfile->params->file); // XXX unsafe if(RNA_struct_find_property(op->ptr, "relative_paths")) if(RNA_boolean_get(op->ptr, "relative_paths")) diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 7ccaa6e2789..dbe9417fd2a 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -440,18 +440,36 @@ int folderlist_clear_next(struct SpaceFile *sfile) return 1; } +/* not listbase itself */ void folderlist_free(ListBase* folderlist) { FolderList *folder; if (folderlist){ - for(folder= folderlist->last; folder; folder= folderlist->last) { - MEM_freeN(folder->foldername); - BLI_freelinkN(folderlist, folder); - } + for(folder= folderlist->first; folder; folder= folder->next) + MEM_freeN(folder->foldername); + BLI_freelistN(folderlist); } folderlist= NULL; } +ListBase *folderlist_duplicate(ListBase* folderlist) +{ + + if (folderlist) { + ListBase *folderlistn= MEM_callocN(sizeof(ListBase), "copy folderlist"); + FolderList *folder; + + BLI_duplicatelist(folderlistn, folderlist); + + for(folder= folderlistn->first; folder; folder= folder->next) { + folder->foldername= MEM_dupallocN(folder->foldername); + } + return folderlistn; + } + return NULL; +} + + static void filelist_read_main(struct FileList* filelist); static void filelist_read_library(struct FileList* filelist); static void filelist_read_dir(struct FileList* filelist); @@ -499,6 +517,8 @@ void filelist_free(struct FileList* filelist) filelist->filelist[i].image = 0; if (filelist->filelist[i].relname) MEM_freeN(filelist->filelist[i].relname); + if (filelist->filelist[i].path) + MEM_freeN(filelist->filelist[i].path); filelist->filelist[i].relname = 0; if (filelist->filelist[i].string) MEM_freeN(filelist->filelist[i].string); diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index a8d909f899e..157a2f5cd52 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -81,6 +81,7 @@ void filelist_hideparent(struct FileList* filelist, short hide); struct ListBase * folderlist_new(); void folderlist_free(struct ListBase* folderlist); +struct ListBase * folderlist_duplicate(ListBase* folderlist); void folderlist_popdir(struct ListBase* folderlist, char *dir); void folderlist_pushdir(struct ListBase* folderlist, const char *dir); int folderlist_clear_next(struct SpaceFile* sfile); diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index bf18c938a8a..e73a8c9a7fa 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -173,10 +173,10 @@ static SpaceLink *file_duplicate(SpaceLink *sl) if (sfileo->params) sfilen->files = filelist_new(sfileo->params->type); if(sfileo->folders_prev) - sfilen->folders_prev = MEM_dupallocN(sfileo->folders_prev); + sfilen->folders_prev = folderlist_duplicate(sfileo->folders_prev); if(sfileo->folders_next) - sfilen->folders_next = MEM_dupallocN(sfileo->folders_next); + sfilen->folders_next = folderlist_duplicate(sfileo->folders_next); if(sfileo->params) { sfilen->params= MEM_dupallocN(sfileo->params); @@ -531,7 +531,7 @@ void ED_spacetype_file(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype file region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_HEADER; art->init= file_header_area_init; art->draw= file_header_area_draw; @@ -541,7 +541,7 @@ void ED_spacetype_file(void) /* regions: ui */ art= MEM_callocN(sizeof(ARegionType), "spacetype file region"); art->regionid = RGN_TYPE_UI; - art->minsizey= 60; + art->prefsizey= 60; art->keymapflag= ED_KEYMAP_UI; art->listener= file_ui_area_listener; art->init= file_ui_area_init; @@ -551,7 +551,7 @@ void ED_spacetype_file(void) /* regions: channels (directories) */ art= MEM_callocN(sizeof(ARegionType), "spacetype file region"); art->regionid = RGN_TYPE_CHANNELS; - art->minsizex= 240; + art->prefsizex= 240; art->keymapflag= ED_KEYMAP_UI; art->listener= file_channel_area_listener; art->init= file_channel_area_init; diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index bfb2b0f666a..d6342011520 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -616,7 +616,7 @@ void ED_spacetype_ipo(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype graphedit region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; art->listener= graph_region_listener; art->init= graph_header_area_init; @@ -627,7 +627,7 @@ void ED_spacetype_ipo(void) /* regions: channels */ art= MEM_callocN(sizeof(ARegionType), "spacetype graphedit region"); art->regionid = RGN_TYPE_CHANNELS; - art->minsizex= 200+V2D_SCROLL_WIDTH; /* 200 is the 'standard', but due to scrollers, we want a bit more to fit the lock icons in */ + art->prefsizex= 200+V2D_SCROLL_WIDTH; /* 200 is the 'standard', but due to scrollers, we want a bit more to fit the lock icons in */ art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES; art->listener= graph_region_listener; art->init= graph_channel_area_init; @@ -638,7 +638,7 @@ void ED_spacetype_ipo(void) /* regions: UI buttons */ art= MEM_callocN(sizeof(ARegionType), "spacetype graphedit region"); art->regionid = RGN_TYPE_UI; - art->minsizex= 200; + art->prefsizex= 200; art->keymapflag= ED_KEYMAP_UI; art->listener= graph_region_listener; art->init= graph_buttons_area_init; diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 33b4e37dc8f..ad3407a7414 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -431,10 +431,14 @@ static void image_free(SpaceLink *sl) } -/* spacetype; init callback */ +/* spacetype; init callback, add handlers */ static void image_init(struct wmWindowManager *wm, ScrArea *sa) { + ListBase *lb= WM_dropboxmap_find("Image", SPACE_IMAGE, 0); + /* add drop boxes */ + WM_event_add_dropbox_handler(&sa->handlers, lb); + } static SpaceLink *image_duplicate(SpaceLink *sl) @@ -521,6 +525,31 @@ void image_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "IMAGE_OT_toolbox", SPACEKEY, KM_PRESS, 0, 0); } +/* dropboxes */ +static int image_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +{ + if(drag->type==WM_DRAG_PATH) + if(ELEM(drag->icon, ICON_FILE_IMAGE, ICON_FILE_BLANK)) /* rule might not work? */ + return 1; + return 0; +} + +static void image_drop_copy(wmDrag *drag, wmDropBox *drop) +{ + /* copy drag path to properties */ + RNA_string_set(drop->ptr, "path", drag->path); +} + +/* area+region dropbox definition */ +static void image_dropboxes(void) +{ + ListBase *lb= WM_dropboxmap_find("Image", SPACE_IMAGE, 0); + + WM_dropbox_add(lb, "IMAGE_OT_open", image_drop_poll, image_drop_copy); +} + + + static void image_refresh(const bContext *C, ScrArea *sa) { SpaceImage *sima= CTX_wm_space_image(C); @@ -685,6 +714,7 @@ static void image_main_area_init(wmWindowManager *wm, ARegion *ar) WM_event_add_keymap_handler(&ar->handlers, keymap); keymap= WM_keymap_find(wm->defaultconf, "Image", SPACE_IMAGE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + } static void image_main_area_draw(const bContext *C, ARegion *ar) @@ -825,6 +855,7 @@ void ED_spacetype_image(void) st->duplicate= image_duplicate; st->operatortypes= image_operatortypes; st->keymap= image_keymap; + st->dropboxes= image_dropboxes; st->refresh= image_refresh; st->listener= image_listener; st->context= image_context; @@ -842,7 +873,7 @@ void ED_spacetype_image(void) /* regions: listview/buttons */ art= MEM_callocN(sizeof(ARegionType), "spacetype image region"); art->regionid = RGN_TYPE_UI; - art->minsizex= 220; // XXX + art->prefsizex= 220; // XXX art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES; art->listener= image_buttons_area_listener; art->init= image_buttons_area_init; @@ -864,7 +895,7 @@ void ED_spacetype_image(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype image region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; art->init= image_header_area_init; art->draw= image_header_area_draw; diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index d9662339bb2..af6bec00171 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -204,7 +204,8 @@ void ED_spacetype_info(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype info region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; + art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; art->listener= info_header_listener; art->init= info_header_area_init; diff --git a/source/blender/editors/space_logic/space_logic.c b/source/blender/editors/space_logic/space_logic.c index a0ef6c395d4..abe20477914 100644 --- a/source/blender/editors/space_logic/space_logic.c +++ b/source/blender/editors/space_logic/space_logic.c @@ -357,7 +357,7 @@ void ED_spacetype_logic(void) /* regions: listview/buttons */ art= MEM_callocN(sizeof(ARegionType), "spacetype logic region"); art->regionid = RGN_TYPE_UI; - art->minsizex= 220; // XXX + art->prefsizex= 220; // XXX art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES; art->listener= logic_listener; art->init= logic_buttons_area_init; @@ -369,7 +369,7 @@ void ED_spacetype_logic(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype logic region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; art->init= logic_header_area_init; art->draw= logic_header_area_draw; diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index 77407769f3b..d4f330db303 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -531,7 +531,7 @@ void ED_spacetype_nla(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype nla region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; art->init= nla_header_area_init; @@ -542,7 +542,7 @@ void ED_spacetype_nla(void) /* regions: channels */ art= MEM_callocN(sizeof(ARegionType), "spacetype nla region"); art->regionid = RGN_TYPE_CHANNELS; - art->minsizex= 200; + art->prefsizex= 200; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D; art->init= nla_channel_area_init; @@ -554,7 +554,7 @@ void ED_spacetype_nla(void) /* regions: UI buttons */ art= MEM_callocN(sizeof(ARegionType), "spacetype nla region"); art->regionid = RGN_TYPE_UI; - art->minsizex= 200; + art->prefsizex= 200; art->keymapflag= ED_KEYMAP_UI; art->listener= nla_region_listener; art->init= nla_buttons_area_init; diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index dcd07690f0e..2229e19c251 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -376,7 +376,7 @@ void ED_spacetype_node(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype node region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; art->listener= node_region_listener; art->init= node_header_area_init; @@ -389,7 +389,7 @@ void ED_spacetype_node(void) /* regions: listview/buttons */ art= MEM_callocN(sizeof(ARegionType), "spacetype node region"); art->regionid = RGN_TYPE_UI; - art->minsizex= 180; // XXX + art->prefsizex= 180; // XXX art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES; art->listener= node_region_listener; art->init= node_buttons_area_init; diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index 84573d44a1d..5048c12c095 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -140,7 +140,7 @@ static void error() {} /* ******************** PROTOTYPES ***************** */ -static void outliner_draw_tree_element(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int startx, int *starty); +static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int startx, int *starty); static void outliner_do_object_operation(bContext *C, Scene *scene, SpaceOops *soops, ListBase *lb, void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *)); @@ -4087,8 +4087,39 @@ void OUTLINER_OT_keyingset_remove_selected(wmOperatorType *ot) /* ***************** DRAW *************** */ -static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElement *te) +/* make function calls a bit compacter */ +struct DrawIconArg { + uiBlock *block; + ID *id; + int xmax, x, y; + float alpha; +}; + +static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon) +{ + /* restrict collumn clip... it has been coded by simply overdrawing, doesnt work for buttons */ + if(arg->x >= arg->xmax) + UI_icon_draw(arg->x, arg->y, icon); + else { + uiBut *but= uiDefIconBut(arg->block, LABEL, 0, icon, arg->x-4, arg->y, ICON_DEFAULT_WIDTH, ICON_DEFAULT_WIDTH, NULL, 0.0, 0.0, 1.0, arg->alpha, ""); + if(arg->id) + uiButSetDragID(but, arg->id); + } + +} + +static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te, float alpha) { + struct DrawIconArg arg; + + /* make function calls a bit compacter */ + arg.block= block; + arg.id= tselem->id; + arg.xmax= xmax; + arg.x= x; + arg.y= y; + arg.alpha= alpha; + if(tselem->type) { switch( tselem->type) { case TSE_ANIM_DATA: @@ -4219,7 +4250,12 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen UI_icon_draw(x, y, ICON_OBJECT_DATA); break; case TSE_RNA_STRUCT: - UI_icon_draw(x, y, RNA_struct_ui_icon(te->rnaptr.type)); + if(RNA_struct_is_ID(te->rnaptr.type)) { + arg.id= (ID *)te->rnaptr.data; + tselem_draw_icon_uibut(&arg, RNA_struct_ui_icon(te->rnaptr.type)); + } + else + UI_icon_draw(x, y, RNA_struct_ui_icon(te->rnaptr.type)); break; default: UI_icon_draw(x, y, ICON_DOT); break; @@ -4228,92 +4264,92 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen else if (GS(tselem->id->name) == ID_OB) { Object *ob= (Object *)tselem->id; switch (ob->type) { - case OB_LAMP: - UI_icon_draw(x, y, ICON_OUTLINER_OB_LAMP); break; + case OB_LAMP: + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_LAMP); break; case OB_MESH: - UI_icon_draw(x, y, ICON_OUTLINER_OB_MESH); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_MESH); break; case OB_CAMERA: - UI_icon_draw(x, y, ICON_OUTLINER_OB_CAMERA); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_CAMERA); break; case OB_CURVE: - UI_icon_draw(x, y, ICON_OUTLINER_OB_CURVE); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_CURVE); break; case OB_MBALL: - UI_icon_draw(x, y, ICON_OUTLINER_OB_META); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_META); break; case OB_LATTICE: - UI_icon_draw(x, y, ICON_OUTLINER_OB_LATTICE); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_LATTICE); break; case OB_ARMATURE: - UI_icon_draw(x, y, ICON_OUTLINER_OB_ARMATURE); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_ARMATURE); break; case OB_FONT: - UI_icon_draw(x, y, ICON_OUTLINER_OB_FONT); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_FONT); break; case OB_SURF: - UI_icon_draw(x, y, ICON_OUTLINER_OB_SURFACE); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_SURFACE); break; case OB_EMPTY: - UI_icon_draw(x, y, ICON_OUTLINER_OB_EMPTY); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_OB_EMPTY); break; } } else { switch( GS(tselem->id->name)) { case ID_SCE: - UI_icon_draw(x, y, ICON_SCENE_DATA); break; + tselem_draw_icon_uibut(&arg, ICON_SCENE_DATA); break; case ID_ME: - UI_icon_draw(x, y, ICON_OUTLINER_DATA_MESH); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_MESH); break; case ID_CU: - UI_icon_draw(x, y, ICON_OUTLINER_DATA_CURVE); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_CURVE); break; case ID_MB: - UI_icon_draw(x, y, ICON_OUTLINER_DATA_META); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_META); break; case ID_LT: - UI_icon_draw(x, y, ICON_OUTLINER_DATA_LATTICE); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_LATTICE); break; case ID_LA: { Lamp *la= (Lamp *)tselem->id; switch(la->type) { case LA_LOCAL: - UI_icon_draw(x, y, ICON_LAMP_POINT); break; + tselem_draw_icon_uibut(&arg, ICON_LAMP_POINT); break; case LA_SUN: - UI_icon_draw(x, y, ICON_LAMP_SUN); break; + tselem_draw_icon_uibut(&arg, ICON_LAMP_SUN); break; case LA_SPOT: - UI_icon_draw(x, y, ICON_LAMP_SPOT); break; + tselem_draw_icon_uibut(&arg, ICON_LAMP_SPOT); break; case LA_HEMI: - UI_icon_draw(x, y, ICON_LAMP_HEMI); break; + tselem_draw_icon_uibut(&arg, ICON_LAMP_HEMI); break; case LA_AREA: - UI_icon_draw(x, y, ICON_LAMP_AREA); break; + tselem_draw_icon_uibut(&arg, ICON_LAMP_AREA); break; default: - UI_icon_draw(x, y, ICON_OUTLINER_DATA_LAMP); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_LAMP); break; } break; } case ID_MA: - UI_icon_draw(x, y, ICON_MATERIAL_DATA); break; + tselem_draw_icon_uibut(&arg, ICON_MATERIAL_DATA); break; case ID_TE: - UI_icon_draw(x, y, ICON_TEXTURE_DATA); break; + tselem_draw_icon_uibut(&arg, ICON_TEXTURE_DATA); break; case ID_IM: - UI_icon_draw(x, y, ICON_IMAGE_DATA); break; + tselem_draw_icon_uibut(&arg, ICON_IMAGE_DATA); break; case ID_SO: - UI_icon_draw(x, y, ICON_SPEAKER); break; + tselem_draw_icon_uibut(&arg, ICON_SPEAKER); break; case ID_AR: - UI_icon_draw(x, y, ICON_OUTLINER_DATA_ARMATURE); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_ARMATURE); break; case ID_CA: - UI_icon_draw(x, y, ICON_OUTLINER_DATA_CAMERA); break; + tselem_draw_icon_uibut(&arg, ICON_OUTLINER_DATA_CAMERA); break; case ID_KE: - UI_icon_draw(x, y, ICON_SHAPEKEY_DATA); break; + tselem_draw_icon_uibut(&arg, ICON_SHAPEKEY_DATA); break; case ID_WO: - UI_icon_draw(x, y, ICON_WORLD_DATA); break; + tselem_draw_icon_uibut(&arg, ICON_WORLD_DATA); break; case ID_AC: - UI_icon_draw(x, y, ICON_ACTION); break; + tselem_draw_icon_uibut(&arg, ICON_ACTION); break; case ID_NLA: - UI_icon_draw(x, y, ICON_NLA); break; + tselem_draw_icon_uibut(&arg, ICON_NLA); break; case ID_TXT: - UI_icon_draw(x, y, ICON_SCRIPT); break; + tselem_draw_icon_uibut(&arg, ICON_SCRIPT); break; case ID_GR: - UI_icon_draw(x, y, ICON_GROUP); break; + tselem_draw_icon_uibut(&arg, ICON_GROUP); break; case ID_LI: - UI_icon_draw(x, y, ICON_LIBRARY_DATA_DIRECT); break; + tselem_draw_icon_uibut(&arg, ICON_LIBRARY_DATA_DIRECT); break; } } } -static void outliner_draw_iconrow(bContext *C, Scene *scene, SpaceOops *soops, ListBase *lb, int level, int *offsx, int ys) +static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, SpaceOops *soops, ListBase *lb, int level, int xmax, int *offsx, int ys) { TreeElement *te; TreeStoreElem *tselem; @@ -4338,10 +4374,10 @@ static void outliner_draw_iconrow(bContext *C, Scene *scene, SpaceOops *soops, L uiSetRoundBox(15); glColor4ub(255, 255, 255, 100); uiRoundBox( (float)*offsx-0.5f, (float)ys-1.0f, (float)*offsx+OL_H-3.0f, (float)ys+OL_H-3.0f, OL_H/2.0f-2.0f); - glEnable(GL_BLEND); + glEnable(GL_BLEND); /* roundbox disables */ } - tselem_draw_icon((float)*offsx, (float)ys, tselem, te); + tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f); te->xs= (float)*offsx; te->ys= (float)ys; te->xend= (short)*offsx+OL_X; @@ -4352,12 +4388,12 @@ static void outliner_draw_iconrow(bContext *C, Scene *scene, SpaceOops *soops, L /* this tree element always has same amount of branches, so dont draw */ if(tselem->type!=TSE_R_LAYER) - outliner_draw_iconrow(C, scene, soops, &te->subtree, level+1, offsx, ys); + outliner_draw_iconrow(C, block, scene, soops, &te->subtree, level+1, xmax, offsx, ys); } } -static void outliner_draw_tree_element(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int startx, int *starty) +static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int startx, int *starty) { TreeElement *ten; TreeStoreElem *tselem; @@ -4366,7 +4402,12 @@ static void outliner_draw_tree_element(bContext *C, Scene *scene, ARegion *ar, S tselem= TREESTORE(te); if(*starty+2*OL_H >= ar->v2d.cur.ymin && *starty<= ar->v2d.cur.ymax) { - + int xmax= ar->v2d.cur.xmax; + + /* icons can be ui buts, we dont want it to overlap with restrict */ + if((soops->flag & SO_HIDE_RESTRICTCOLS)==0) + xmax-= OL_TOGW+ICON_DEFAULT_WIDTH; + glEnable(GL_BLEND); /* colors for active/selected data */ @@ -4439,8 +4480,9 @@ static void outliner_draw_tree_element(bContext *C, Scene *scene, ARegion *ar, S /* datatype icon */ if(!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))) { - // icons a bit higher - tselem_draw_icon((float)startx+offsx, (float)*starty+2, tselem, te); + // icons a bit higher + tselem_draw_icon(block, xmax, (float)startx+offsx, (float)*starty+2, tselem, te, 1.0f); + offsx+= OL_X; } else @@ -4472,6 +4514,7 @@ static void outliner_draw_tree_element(bContext *C, Scene *scene, ARegion *ar, S if(tselem->type==0 && te->idcode==ID_SCE); else if(tselem->type!=TSE_R_LAYER) { /* this tree element always has same amount of branches, so dont draw */ int tempx= startx+offsx; + // divider UI_ThemeColorShade(TH_BACK, -40); glRecti(tempx -10, *starty+4, tempx -8, *starty+OL_H-4); @@ -4479,8 +4522,8 @@ static void outliner_draw_tree_element(bContext *C, Scene *scene, ARegion *ar, S glEnable(GL_BLEND); glPixelTransferf(GL_ALPHA_SCALE, 0.5); - outliner_draw_iconrow(C, scene, soops, &te->subtree, 0, &tempx, *starty+2); - + outliner_draw_iconrow(C, block, scene, soops, &te->subtree, 0, xmax, &tempx, *starty+2); + glPixelTransferf(GL_ALPHA_SCALE, 1.0); glDisable(GL_BLEND); } @@ -4496,7 +4539,7 @@ static void outliner_draw_tree_element(bContext *C, Scene *scene, ARegion *ar, S if((tselem->flag & TSE_CLOSED)==0) { for(ten= te->subtree.first; ten; ten= ten->next) { - outliner_draw_tree_element(C, scene, ar, soops, ten, startx+OL_X, starty); + outliner_draw_tree_element(C, block, scene, ar, soops, ten, startx+OL_X, starty); } } } @@ -4575,7 +4618,7 @@ static void outliner_draw_selection(ARegion *ar, SpaceOops *soops, ListBase *lb, } -static void outliner_draw_tree(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops) +static void outliner_draw_tree(bContext *C, uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops) { TreeElement *te; int starty, startx; @@ -4607,7 +4650,7 @@ static void outliner_draw_tree(bContext *C, Scene *scene, ARegion *ar, SpaceOops starty= (int)ar->v2d.tot.ymax-OL_H; startx= 0; for(te= soops->tree.first; te; te= te->next) { - outliner_draw_tree_element(C, scene, ar, soops, te, startx, &starty); + outliner_draw_tree_element(C, block, scene, ar, soops, te, startx, &starty); } } @@ -5355,10 +5398,10 @@ void draw_outliner(const bContext *C) /* draw outliner stuff (background and hierachy lines) */ outliner_back(ar, soops); - outliner_draw_tree((bContext *)C, scene, ar, soops); + block= uiBeginBlock(C, ar, "outliner buttons", UI_EMBOSS); + outliner_draw_tree((bContext *)C, block, scene, ar, soops); /* draw icons and names */ - block= uiBeginBlock(C, ar, "outliner buttons", UI_EMBOSS); outliner_buttons(C, block, ar, soops, &soops->tree); if(ELEM(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF)) { diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index 568c0b353e3..c62f2fee66a 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -286,7 +286,7 @@ void ED_spacetype_outliner(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype time region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; art->init= outliner_header_area_init; diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c index b882a3313cd..89f5eefae88 100644 --- a/source/blender/editors/space_script/space_script.c +++ b/source/blender/editors/space_script/space_script.c @@ -219,7 +219,7 @@ void ED_spacetype_script(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype script region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_HEADER; art->init= script_header_area_init; diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 354b4712ce4..29995c89662 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -433,7 +433,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) static int sequencer_add_image_strip_invoke(bContext *C, wmOperator *op, wmEvent *event) { - sequencer_generic_invoke_xy__internal(C, op, event, 0); + sequencer_generic_invoke_xy__internal(C, op, event, SEQPROP_ENDFRAME); return WM_operator_filesel(C, op, event); //return sequencer_add_image_strip_exec(C, op); } @@ -457,7 +457,7 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL); - sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_FILES); + sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME|SEQPROP_ENDFRAME|SEQPROP_FILES); } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 25364aed5ca..d2b13ac7912 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -237,7 +237,7 @@ static void sequencer_free(SpaceLink *sl) /* spacetype; init callback */ static void sequencer_init(struct wmWindowManager *wm, ScrArea *sa) { - + } static SpaceLink *sequencer_duplicate(SpaceLink *sl) @@ -251,11 +251,13 @@ static SpaceLink *sequencer_duplicate(SpaceLink *sl) } + /* *********************** sequencer (main) region ************************ */ /* add handlers, stuff you only do once or on area/region changes */ static void sequencer_main_area_init(wmWindowManager *wm, ARegion *ar) { wmKeyMap *keymap; + ListBase *lb; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); @@ -265,6 +267,12 @@ static void sequencer_main_area_init(wmWindowManager *wm, ARegion *ar) /* own keymap */ keymap= WM_keymap_find(wm->defaultconf, "Sequencer", SPACE_SEQ, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + + /* add drop boxes */ + lb= WM_dropboxmap_find("Sequencer", SPACE_SEQ, RGN_TYPE_WINDOW); + + WM_event_add_dropbox_handler(&ar->handlers, lb); + } static void sequencer_main_area_draw(const bContext *C, ARegion *ar) @@ -275,6 +283,40 @@ static void sequencer_main_area_draw(const bContext *C, ARegion *ar) draw_timeline_seq(C, ar); } +/* ************* dropboxes ************* */ + +static int image_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +{ + if(drag->type==WM_DRAG_PATH) + if(ELEM(drag->icon, ICON_FILE_IMAGE, ICON_FILE_BLANK)) /* rule might not work? */ + return 1; + return 0; +} + +static int movie_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +{ + if(drag->type==WM_DRAG_PATH) + if(ELEM(drag->icon, ICON_FILE_MOVIE, ICON_FILE_BLANK)) /* rule might not work? */ + return 1; + return 0; +} + +static void sequencer_drop_copy(wmDrag *drag, wmDropBox *drop) +{ + /* copy drag path to properties */ + RNA_string_set(drop->ptr, "path", drag->path); +} + +/* this region dropbox definition */ +static void sequencer_dropboxes(void) +{ + ListBase *lb= WM_dropboxmap_find("Sequencer", SPACE_SEQ, RGN_TYPE_WINDOW); + + WM_dropbox_add(lb, "SEQUENCER_OT_image_strip_add", image_drop_poll, sequencer_drop_copy); + WM_dropbox_add(lb, "SEQUENCER_OT_movie_strip_add", movie_drop_poll, sequencer_drop_copy); +} + +/* ************* end drop *********** */ /* add handlers, stuff you only do once or on area/region changes */ static void sequencer_header_area_init(wmWindowManager *wm, ARegion *ar) @@ -421,7 +463,8 @@ void ED_spacetype_sequencer(void) st->duplicate= sequencer_duplicate; st->operatortypes= sequencer_operatortypes; st->keymap= sequencer_keymap; - + st->dropboxes= sequencer_dropboxes; + /* regions: main window */ art= MEM_callocN(sizeof(ARegionType), "spacetype sequencer region"); art->regionid = RGN_TYPE_WINDOW; @@ -435,7 +478,7 @@ void ED_spacetype_sequencer(void) /* preview */ art= MEM_callocN(sizeof(ARegionType), "spacetype sequencer region"); art->regionid = RGN_TYPE_PREVIEW; - art->minsizey = 240; // XXX + art->prefsizey = 240; // XXX art->init= sequencer_preview_area_init; art->draw= sequencer_preview_area_draw; art->listener= sequencer_preview_area_listener; @@ -445,7 +488,7 @@ void ED_spacetype_sequencer(void) /* regions: listview/buttons */ art= MEM_callocN(sizeof(ARegionType), "spacetype sequencer region"); art->regionid = RGN_TYPE_UI; - art->minsizex= 220; // XXX + art->prefsizex= 220; // XXX art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES; art->listener= sequencer_buttons_area_listener; art->init= sequencer_buttons_area_init; @@ -459,7 +502,7 @@ void ED_spacetype_sequencer(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype sequencer region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; art->init= sequencer_header_area_init; diff --git a/source/blender/editors/space_sound/space_sound.c b/source/blender/editors/space_sound/space_sound.c index 1cd5ab65c0f..f77afb6e168 100644 --- a/source/blender/editors/space_sound/space_sound.c +++ b/source/blender/editors/space_sound/space_sound.c @@ -246,7 +246,7 @@ void ED_spacetype_sound(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype sound region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_HEADER; art->init= sound_header_area_init; @@ -257,7 +257,7 @@ void ED_spacetype_sound(void) /* regions: channels */ art= MEM_callocN(sizeof(ARegionType), "spacetype sound region"); art->regionid = RGN_TYPE_CHANNELS; - art->minsizex= 80; + art->prefsizex= 80; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D; // art->init= sound_channel_area_init; diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index be90834a371..77e0efafd0b 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -433,7 +433,7 @@ void ED_spacetype_text(void) /* regions: properties */ art= MEM_callocN(sizeof(ARegionType), "spacetype text region"); art->regionid = RGN_TYPE_UI; - art->minsizex= UI_COMPACT_PANEL_WIDTH; + art->prefsizex= UI_COMPACT_PANEL_WIDTH; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D; art->init= text_properties_area_init; @@ -443,7 +443,7 @@ void ED_spacetype_text(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype text region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_HEADER; art->init= text_header_area_init; diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index 4f9f4975629..7b935ae916b 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -432,7 +432,7 @@ void ED_spacetype_time(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype time region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; art->init= time_header_area_init; diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c index f45e08be697..7b522482db1 100644 --- a/source/blender/editors/space_userpref/space_userpref.c +++ b/source/blender/editors/space_userpref/space_userpref.c @@ -175,7 +175,7 @@ void ED_spacetype_userpref(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype userpref region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_HEADER; art->listener= userpref_header_listener; art->init= userpref_header_area_init; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index b3bd31d53ac..da64c10b277 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -319,6 +319,7 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl) /* add handlers, stuff you only do once or on area/region changes */ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) { + ListBase *lb; wmKeyMap *keymap; /* object ops. */ @@ -386,8 +387,62 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) keymap= WM_keymap_find(wm->defaultconf, "3D View", SPACE_VIEW3D, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); + + /* add drop boxes */ + lb= WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW); + + WM_event_add_dropbox_handler(&ar->handlers, lb); + +} + +static int view3d_ob_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +{ + if(drag->type==WM_DRAG_ID) { + ID *id= (ID *)drag->poin; + if( GS(id->name)==ID_OB ) + return 1; + } + return 0; +} + +static int view3d_mat_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +{ + if(drag->type==WM_DRAG_ID) { + ID *id= (ID *)drag->poin; + if( GS(id->name)==ID_MA ) + return 1; + } + return 0; +} + +static int view3d_ima_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +{ + if(drag->type==WM_DRAG_ID) { + ID *id= (ID *)drag->poin; + if( GS(id->name)==ID_IM ) + return 1; + } + return 0; +} + +static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop) +{ + ID *id= (ID *)drag->poin; + RNA_string_set(drop->ptr, "name", id->name+2); } +/* region dropbox definition */ +static void view3d_dropboxes(void) +{ + ListBase *lb= WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW); + + WM_dropbox_add(lb, "OBJECT_OT_add_named_cursor", view3d_ob_drop_poll, view3d_id_drop_copy); + WM_dropbox_add(lb, "OBJECT_OT_drop_named_material", view3d_mat_drop_poll, view3d_id_drop_copy); + WM_dropbox_add(lb, "MESH_OT_drop_named_image", view3d_ima_drop_poll, view3d_id_drop_copy); +} + + + /* type callback, not region itself */ static void view3d_main_area_free(ARegion *ar) { @@ -822,6 +877,7 @@ void ED_spacetype_view3d(void) st->duplicate= view3d_duplicate; st->operatortypes= view3d_operatortypes; st->keymap= view3d_keymap; + st->dropboxes= view3d_dropboxes; st->context= view3d_context; /* regions: main window */ @@ -839,7 +895,7 @@ void ED_spacetype_view3d(void) /* regions: listview/buttons */ art= MEM_callocN(sizeof(ARegionType), "spacetype view3d region"); art->regionid = RGN_TYPE_UI; - art->minsizex= 180; // XXX + art->prefsizex= 180; // XXX art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES; art->listener= view3d_buttons_area_listener; art->init= view3d_buttons_area_init; @@ -851,8 +907,8 @@ void ED_spacetype_view3d(void) /* regions: tool(bar) */ art= MEM_callocN(sizeof(ARegionType), "spacetype view3d region"); art->regionid = RGN_TYPE_TOOLS; - art->minsizex= 160; // XXX - art->minsizey= 50; // XXX + art->prefsizex= 160; // XXX + art->prefsizey= 50; // XXX art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES; art->listener= view3d_buttons_area_listener; art->init= view3d_tools_area_init; @@ -864,8 +920,8 @@ void ED_spacetype_view3d(void) /* regions: tool properties */ art= MEM_callocN(sizeof(ARegionType), "spacetype view3d region"); art->regionid = RGN_TYPE_TOOL_PROPS; - art->minsizex= 0; - art->minsizey= 120; + art->prefsizex= 0; + art->prefsizey= 120; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES; art->listener= view3d_buttons_area_listener; art->init= view3d_tools_area_init; @@ -878,7 +934,7 @@ void ED_spacetype_view3d(void) /* regions: header */ art= MEM_callocN(sizeof(ARegionType), "spacetype view3d region"); art->regionid = RGN_TYPE_HEADER; - art->minsizey= HEADERY; + art->prefsizey= HEADERY; art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER; art->listener= view3d_header_area_listener; art->init= view3d_header_area_init; diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index f7f053b2195..6cad57f03d5 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1006,6 +1006,123 @@ static short mixed_bones_object_selectbuffer(ViewContext *vc, unsigned int *buff return 0; } +/* returns basact */ +static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int hits, short *mval, Base *startbase, int has_bones) +{ + Scene *scene= vc->scene; + View3D *v3d= vc->v3d; + Base *base, *basact= NULL; + static short lastmval[2]={-100, -100}; + int a, donearest= 0; + + /* define if we use solid nearest select or not */ + if(v3d->drawtype>OB_WIRE) { + donearest= 1; + if( ABS(mval[0]-lastmval[0])<3 && ABS(mval[1]-lastmval[1])<3) { + if(!has_bones) /* hrms, if theres bones we always do nearest */ + donearest= 0; + } + } + lastmval[0]= mval[0]; lastmval[1]= mval[1]; + + if(donearest) { + unsigned int min= 0xFFFFFFFF; + int selcol= 0, notcol=0; + + + if(has_bones) { + /* we skip non-bone hits */ + for(a=0; a<hits; a++) { + if( min > buffer[4*a+1] && (buffer[4*a+3] & 0xFFFF0000) ) { + min= buffer[4*a+1]; + selcol= buffer[4*a+3] & 0xFFFF; + } + } + } + else { + /* only exclude active object when it is selected... */ + if(BASACT && (BASACT->flag & SELECT) && hits>1) notcol= BASACT->selcol; + + for(a=0; a<hits; a++) { + if( min > buffer[4*a+1] && notcol!=(buffer[4*a+3] & 0xFFFF)) { + min= buffer[4*a+1]; + selcol= buffer[4*a+3] & 0xFFFF; + } + } + } + + base= FIRSTBASE; + while(base) { + if(base->lay & v3d->lay) { + if(base->selcol==selcol) break; + } + base= base->next; + } + if(base) basact= base; + } + else { + + base= startbase; + while(base) { + /* skip objects with select restriction, to prevent prematurely ending this loop + * with an un-selectable choice */ + if (base->object->restrictflag & OB_RESTRICT_SELECT) { + base=base->next; + if(base==NULL) base= FIRSTBASE; + if(base==startbase) break; + } + + if(base->lay & v3d->lay) { + for(a=0; a<hits; a++) { + if(has_bones) { + /* skip non-bone objects */ + if((buffer[4*a+3] & 0xFFFF0000)) { + if(base->selcol== (buffer[(4*a)+3] & 0xFFFF)) + basact= base; + } + } + else { + if(base->selcol== (buffer[(4*a)+3] & 0xFFFF)) + basact= base; + } + } + } + + if(basact) break; + + base= base->next; + if(base==NULL) base= FIRSTBASE; + if(base==startbase) break; + } + } + + return basact; +} + +/* mval comes from event->mval, only use within region handlers */ +Base *ED_view3d_give_base_under_cursor(bContext *C, short *mval) +{ + ViewContext vc; + Base *basact= NULL; + unsigned int buffer[4*MAXPICKBUF]; + int hits; + + /* setup view context for argument to callbacks */ + view3d_operator_needs_opengl(C); + view3d_set_viewcontext(C, &vc); + + hits= mixed_bones_object_selectbuffer(&vc, buffer, mval); + + if(hits>0) { + int a, has_bones= 0; + + for(a=0; a<hits; a++) if(buffer[4*a+3] & 0xFFFF0000) has_bones= 1; + + basact= mouse_select_eval_buffer(&vc, buffer, hits, mval, vc.scene->base.first, has_bones); + } + + return basact; +} /* mval is region coords */ static int mouse_select(bContext *C, short *mval, short extend, short obcenter, short enumerate) @@ -1070,89 +1187,7 @@ static int mouse_select(bContext *C, short *mval, short extend, short obcenter, 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; - - /* define if we use solid nearest select or not */ - if(v3d->drawtype>OB_WIRE) { - donearest= 1; - if( ABS(mval[0]-lastmval[0])<3 && ABS(mval[1]-lastmval[1])<3) { - if(!has_bones) /* hrms, if theres bones we always do nearest */ - donearest= 0; - } - } - lastmval[0]= mval[0]; lastmval[1]= mval[1]; - - if(donearest) { - unsigned int min= 0xFFFFFFFF; - int selcol= 0, notcol=0; - - - if(has_bones) { - /* we skip non-bone hits */ - for(a=0; a<hits; a++) { - if( min > buffer[4*a+1] && (buffer[4*a+3] & 0xFFFF0000) ) { - min= buffer[4*a+1]; - selcol= buffer[4*a+3] & 0xFFFF; - } - } - } - else { - /* only exclude active object when it is selected... */ - if(BASACT && (BASACT->flag & SELECT) && hits>1) notcol= BASACT->selcol; - - for(a=0; a<hits; a++) { - if( min > buffer[4*a+1] && notcol!=(buffer[4*a+3] & 0xFFFF)) { - min= buffer[4*a+1]; - selcol= buffer[4*a+3] & 0xFFFF; - } - } - } - - base= FIRSTBASE; - while(base) { - if(base->lay & v3d->lay) { - if(base->selcol==selcol) break; - } - base= base->next; - } - if(base) basact= base; - } - else { - - base= startbase; - while(base) { - /* skip objects with select restriction, to prevent prematurely ending this loop - * with an un-selectable choice */ - if (base->object->restrictflag & OB_RESTRICT_SELECT) { - base=base->next; - if(base==NULL) base= FIRSTBASE; - if(base==startbase) break; - } - - if(base->lay & v3d->lay) { - for(a=0; a<hits; a++) { - if(has_bones) { - /* skip non-bone objects */ - if((buffer[4*a+3] & 0xFFFF0000)) { - if(base->selcol== (buffer[(4*a)+3] & 0xFFFF)) - basact= base; - } - } - else { - if(base->selcol== (buffer[(4*a)+3] & 0xFFFF)) - basact= base; - } - } - } - - if(basact) break; - - base= base->next; - if(base==NULL) base= FIRSTBASE; - if(base==startbase) break; - } - } + basact= mouse_select_eval_buffer(&vc, buffer, hits, mval, startbase, has_bones); } if(has_bones && basact) { |