Files
test/source/blender/editors/space_view3d/view3d_toolbar.c
Matt Ebb 251ef0a47f Changes to Brush texture workflow
This changes how textures are accessed from Brushes, with the intention of simplifying 
the workflow, and reducing the amount of clicking. Rather than the previous texture slots 
(which didn't work as a stack anyway), brushes now have a single texture linked. Rather 
than taking time having to set up your slots in advance, you can now select and change 
textures directly as you sculpt/paint on the fly. For complex brushes, node textures can 
be used, or for fast access, it's easy to make a duplicate of your brush with the texture 
you like and assign a hotkey.

Brush textures can now be chosen from a new Textures panel in the brush tool 
properties - click on the thumbnail to open a texture selector. This is done using a new 
variation on the ID template - the number of rows and columns to display in the popup 
can be customised in the UI scripts.
2010-01-03 08:37:18 +00:00

333 lines
8.1 KiB
C

/**
* $Id:
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2009 Blender Foundation.
* All rights reserved.
*
*
* Contributor(s): Blender Foundation
*
* ***** END GPL LICENSE BLOCK *****
*/
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <float.h>
#include "DNA_ID.h"
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_camera_types.h"
#include "DNA_lamp_types.h"
#include "DNA_lattice_types.h"
#include "DNA_meta_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
#include "BLI_rand.h"
#include "BKE_action.h"
#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
#include "BKE_idprop.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_global.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_utildefines.h"
#include "BIF_gl.h"
#include "WM_api.h"
#include "WM_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "ED_armature.h"
#include "ED_curve.h"
#include "ED_image.h"
#include "ED_keyframing.h"
#include "ED_mesh.h"
#include "ED_object.h"
#include "ED_particle.h"
#include "ED_screen.h"
#include "ED_transform.h"
#include "ED_types.h"
#include "ED_util.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
#include "view3d_intern.h" // own include
/* ******************* view3d space & buttons ************** */
/* op->invoke */
static void redo_cb(bContext *C, void *arg_op, void *arg2)
{
wmOperator *lastop= arg_op;
if(lastop) {
int retval;
printf("operator redo %s\n", lastop->type->name);
ED_undo_pop_op(C, lastop);
retval= WM_operator_repeat(C, lastop);
if((retval & OPERATOR_FINISHED)==0) {
printf("operator redo failed %s\n", lastop->type->name);
ED_undo_redo(C);
}
}
}
static wmOperator *view3d_last_operator(const bContext *C)
{
wmWindowManager *wm= CTX_wm_manager(C);
wmOperator *op;
/* only for operators that are registered and did an undo push */
for(op= wm->operators.last; op; op= op->prev)
if((op->type->flag & OPTYPE_REGISTER) && (op->type->flag & OPTYPE_UNDO))
break;
return op;
}
static void view3d_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOperator *op)
{
wmWindowManager *wm= CTX_wm_manager(C);
PointerRNA ptr;
if(!op->properties) {
IDPropertyTemplate val = {0};
op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
}
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
if(op->type->ui) {
op->layout= pa->layout;
op->type->ui((bContext*)C, op);
op->layout= NULL;
}
else
uiDefAutoButsRNA(C, pa->layout, &ptr, 1);
}
static void view3d_panel_operator_redo_header(const bContext *C, Panel *pa)
{
wmOperator *op= view3d_last_operator(C);
if(op) BLI_strncpy(pa->drawname, op->type->name, sizeof(pa->drawname));
else BLI_strncpy(pa->drawname, "Operator", sizeof(pa->drawname));
}
static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
{
wmOperator *op= view3d_last_operator(C);
uiBlock *block;
if(op==NULL)
return;
if(WM_operator_poll((bContext*)C, op->type) == 0)
return;
block= uiLayoutGetBlock(pa->layout);
uiBlockSetFunc(block, redo_cb, op, NULL);
if(op->macro.first) {
for(op= op->macro.first; op; op= op->next)
view3d_panel_operator_redo_buts(C, pa, op);
}
else {
view3d_panel_operator_redo_buts(C, pa, op);
}
}
/* ******************* */
typedef struct CustomTool {
struct CustomTool *next, *prev;
char opname[OP_MAX_TYPENAME];
char context[OP_MAX_TYPENAME];
} CustomTool;
static void operator_call_cb(struct bContext *C, void *arg_listbase, void *arg2)
{
wmOperatorType *ot= arg2;
if(ot) {
CustomTool *ct= MEM_callocN(sizeof(CustomTool), "CustomTool");
BLI_addtail(arg_listbase, ct);
BLI_strncpy(ct->opname, ot->idname, OP_MAX_TYPENAME);
BLI_strncpy(ct->context, CTX_data_mode_string(C), OP_MAX_TYPENAME);
}
}
static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items)
{
wmOperatorType *ot = WM_operatortype_first();
for(; ot; ot= ot->next) {
if(BLI_strcasestr(ot->name, str)) {
if(WM_operator_poll((bContext*)C, ot)) {
if(0==uiSearchItemAdd(items, ot->name, ot, 0))
break;
}
}
}
}
/* ID Search browse menu, open */
static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
{
static char search[OP_MAX_TYPENAME];
wmEvent event;
wmWindow *win= CTX_wm_window(C);
uiBlock *block;
uiBut *but;
/* clear initial search string, then all items show */
search[0]= 0;
block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
/* fake button, it holds space for search items */
uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, OP_MAX_TYPENAME, 10, 0, 150, 19, 0, 0, "");
uiButSetSearchFunc(but, operator_search_cb, arg_listbase, operator_call_cb, NULL);
uiBoundsBlock(block, 6);
uiBlockSetDirection(block, UI_DOWN);
uiEndBlock(C, block);
event= *(win->eventstate); /* XXX huh huh? make api call */
event.type= EVT_BUT_OPEN;
event.val= KM_PRESS;
event.customdata= but;
event.customdatafree= FALSE;
wm_event_add(win, &event);
return block;
}
static void view3d_panel_tool_shelf(const bContext *C, Panel *pa)
{
SpaceLink *sl= CTX_wm_space_data(C);
SpaceType *st= NULL;
uiLayout *col;
const char *context= CTX_data_mode_string(C);
if(sl)
st= BKE_spacetype_from_id(sl->spacetype);
if(st && st->toolshelf.first) {
CustomTool *ct;
for(ct= st->toolshelf.first; ct; ct= ct->next) {
if(0==strncmp(context, ct->context, OP_MAX_TYPENAME)) {
col= uiLayoutColumn(pa->layout, 1);
uiItemFullO(col, NULL, 0, ct->opname, NULL, WM_OP_INVOKE_REGION_WIN, 0);
}
}
}
col= uiLayoutColumn(pa->layout, 1);
uiDefBlockBut(uiLayoutGetBlock(pa->layout), tool_search_menu, &st->toolshelf, "Add Tool", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Add Tool in shelf, gets saved in files");
}
void view3d_toolbar_register(ARegionType *art)
{
PanelType *pt;
pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel tools");
strcpy(pt->idname, "VIEW3D_PT_tool_shelf");
strcpy(pt->label, "Tool Shelf");
pt->draw= view3d_panel_tool_shelf;
BLI_addtail(&art->paneltypes, pt);
}
void view3d_tool_props_register(ARegionType *art)
{
PanelType *pt;
pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel last operator");
strcpy(pt->idname, "VIEW3D_PT_last_operator");
strcpy(pt->label, "Operator");
pt->draw_header= view3d_panel_operator_redo_header;
pt->draw= view3d_panel_operator_redo;
BLI_addtail(&art->paneltypes, pt);
}
/* ********** operator to open/close toolbar region */
static int view3d_toolbar(bContext *C, wmOperator *op)
{
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= view3d_has_tools_region(sa);
if(ar)
ED_region_toggle_hidden(C, ar);
return OPERATOR_FINISHED;
}
void VIEW3D_OT_toolbar(wmOperatorType *ot)
{
ot->name= "Toolbar";
ot->description= "Toggles toolbar display.";
ot->idname= "VIEW3D_OT_toolbar";
ot->exec= view3d_toolbar;
ot->poll= ED_operator_view3d_active;
/* flags */
ot->flag= 0;
}