2.5: work on bringing back SpaceTime options

- RMB select, also with SHIFT
- RMB tweak for translate
- SHIFT+D dupli
- BKEY border select/deselect
- AKEY (de)select all
- XKEY delete
- GKEY grab

Added some XXX comments for future todos, especially for when other
spaces come back with time markers.

Also added ED_util for putting in all to-be-cleaned cruft

Context conflict: input methods for Markers can conflict with other
spacetypes. It was solved in pre-2.5 with manually tweaking it all over, 
but I would prefer one keymap for all marker stuff. Needs some thinking... 
could be solved with a boundbox check for bottom part of 2d window.

Tweak issue: both tweak styles are possible:
- Hold mouse button, move, operator ends on mouse release
- Hold mouse button, move, operator ends on mouse click

Problem is that modally handled operators use fixed keymaps... like ESC,
SPACE, ENTER, or press/release mousebutton for 'assign'. There's a lot 
to say for making this all consistant, or become part of 1 general keymap?
Should also be possibe to define 'tweak' defaults for Tablet different 
than for mouse...
This commit is contained in:
2008-11-29 15:10:31 +00:00
parent f07f6f6fa0
commit 78218d89d6
19 changed files with 885 additions and 63 deletions

View File

@@ -238,6 +238,7 @@ PULIB += $(OCGDIR)/blender/ed_outliner/libed_outliner.a
PULIB += $(OCGDIR)/blender/ed_time/libed_time.a
PULIB += $(OCGDIR)/blender/ed_view3d/libed_view3d.a
PULIB += $(OCGDIR)/blender/ed_interface/libed_interface.a
PULIB += $(OCGDIR)/blender/ed_util/libed_util.a
PULIB += $(OCGDIR)/blender/ed_datafiles/libed_datafiles.a
PULIB += $(OCGDIR)/blender/windowmanager/libwindowmanager.a
PULIB += $(OCGDIR)/blender/python/$(DEBUG_DIR)libpython.a

View File

@@ -29,6 +29,6 @@
# Bounces make to subdirectories.
SOURCEDIR = source/blender/editors
DIRS = datafiles screen space_outliner space_time space_view3d interface
DIRS = datafiles screen space_outliner space_time space_view3d interface util
include nan_subdirs.mk

View File

@@ -3,6 +3,7 @@ Import ('env')
SConscript(['datafiles/SConscript',
'util/SConscript',
'interface/SConscript',
'mesh/SConscript',
'object/SConscript',

View File

@@ -36,13 +36,10 @@ enum {
struct wmOperatorType;
void draw_markers_time(const bContext *C, int flag);
/* operators */
void ED_MARKER_OT_add(struct wmOperatorType *ot);
/* register operators, called in ED_operatortypes_screen() */
void ED_marker_operatortypes(void);
#endif /* ED_MARKERS_H */

View File

@@ -25,9 +25,9 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef ED_AREA_H
#define ED_AREA_H
#ifndef ED_MESH_H
#define ED_MESH_H
#endif /* ED_AREA_H */
#endif /* ED_MESH_H */

View File

@@ -43,6 +43,7 @@ void ED_region_do_listen(ARegion *ar, struct wmNotifier *note);
void ED_region_do_draw(struct bContext *C, ARegion *ar);
void ED_region_do_refresh(struct bContext *C, ARegion *ar);
void ED_region_exit(struct bContext *C, ARegion *ar);
void ED_region_pixelspace(struct bContext *C, ARegion *ar);
/* spaces */
void ED_spacetypes_init(void);

View File

@@ -0,0 +1,34 @@
/**
* $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) 2008 Blender Foundation.
* All rights reserved.
*
*
* Contributor(s): Blender Foundation
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef ED_UTIL_H
#define ED_UTIL_H
void apply_keyb_grid(float *val, float fac1, float fac2, float fac3, int invert);
#endif /* ED_UTIL_H */

View File

@@ -90,6 +90,15 @@ static void region_draw_emboss(ARegion *ar)
glDisable( GL_BLEND );
}
void ED_region_pixelspace(bContext *C, ARegion *ar)
{
int width= ar->winrct.xmax-ar->winrct.xmin+1;
int height= ar->winrct.ymax-ar->winrct.ymin+1;
wmOrtho2(C->window, -0.375, (float)width-0.375, -0.375, (float)height-0.375);
wmLoadIdentity(C->window);
}
void ED_region_do_listen(ARegion *ar, wmNotifier *note)
{
@@ -161,6 +170,9 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
region_draw_emboss(ar);
}
/* XXX test: add convention to end regions always in pixel space, for drawing of borders/gestures etc */
ED_region_pixelspace(C, ar);
ar->do_draw= 0;
}

View File

@@ -1213,7 +1213,7 @@ void ED_SCR_OT_area_join(wmOperatorType *ot)
RNA_def_property_int_default(prop, -100);
}
/* ************** border select operator (test only) ***************************** */
/* ************** border select operator (template) ***************************** */
/* operator state vars used: (added by default WM callbacks)
xmin, ymin
@@ -1233,7 +1233,7 @@ callbacks:
poll() has to be filled in by user for context
*/
#if 0
static int border_select_do(bContext *C, wmOperator *op)
{
int event_type= RNA_int_get(op->ptr, "event_type");
@@ -1263,9 +1263,13 @@ void ED_SCR_OT_border_select(wmOperatorType *ot)
/* rna */
RNA_def_property(ot->srna, "event_type", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "xmin", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "xmax", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "ymin", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "ymax", PROP_INT, PROP_NONE);
}
#endif
/* **************** Assigning operatortypes to global list, adding handlers **************** */
@@ -1283,11 +1287,8 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(ED_SCR_OT_area_rip);
/* tools shared by more space types */
WM_operatortype_append(ED_MARKER_OT_add);
ED_marker_operatortypes();
/* for test only */
WM_operatortype_append(ED_SCR_OT_border_select);
}
/* called in spacetypes.c */
@@ -1301,8 +1302,5 @@ void ED_keymap_screen(wmWindowManager *wm)
WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_area_join", EVT_ACTIONZONE, 0, 0, 0); /* action tria */
WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_area_rip", RKEY, KM_PRESS, KM_ALT, 0);
/* for test only */
WM_keymap_verify_item(&wm->screenkeymap, "ED_SCR_OT_border_select", BKEY, KM_PRESS, 0, 0);
}

View File

@@ -27,6 +27,7 @@
*/
#include <stdlib.h>
#include <math.h>
#include "MEM_guardedalloc.h"
@@ -34,6 +35,7 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_view2d_types.h"
#include "DNA_userdef_types.h"
#include "DNA_windowmanager_types.h"
#include "RNA_access.h"
@@ -42,6 +44,7 @@
#include "BLI_blenlib.h"
#include "BKE_global.h"
#include "BKE_utildefines.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -55,7 +58,36 @@
#include "UI_resources.h"
#include "ED_markers.h"
#include "ED_screen.h"
#include "ED_types.h"
#include "ED_util.h"
/* ************* Marker API **************** */
static ListBase *context_get_markers(const bContext *C)
{
#if 0
/* XXX get them from pose */
if ((slink->spacetype == SPACE_ACTION) && (saction->flag & SACTION_POSEMARKERS_MOVE)) {
if (saction->action)
markers= &saction->action->markers;
else
markers= NULL;
}
else
#endif
return &C->scene->markers;
}
static View2D *context_get_view2d(const bContext *C)
{
/* XXX solve, get from view2d api? */
SpaceTime *stime= C->area->spacedata.first;
return &stime->v2d;
}
/* ************* Marker Drawing ************ */
@@ -128,81 +160,370 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
glScalef(xscale, yscale, 1.0);
}
/* Draw Scene-Markers in time window (XXX make generic) */
/* Draw Scene-Markers in time window */
void draw_markers_time(const bContext *C, int flag)
{
ListBase *markers= context_get_markers(C);
View2D *v2d= context_get_view2d(C);
TimeMarker *marker;
SpaceTime *stime= C->area->spacedata.first;
View2D *v2d= &stime->v2d;
/* unselected markers are drawn at the first time */
for (marker= C->scene->markers.first; marker; marker= marker->next) {
for (marker= markers->first; marker; marker= marker->next) {
if (!(marker->flag & SELECT)) draw_marker(v2d, marker, C->scene->r.cfra, flag);
}
/* selected markers are drawn later */
for (marker= C->scene->markers.first; marker; marker= marker->next) {
for (marker= markers->first; marker; marker= marker->next) {
if (marker->flag & SELECT) draw_marker(v2d, marker, C->scene->r.cfra, flag);
}
}
/* ************* Marker API **************** */
/* ************************** add markers *************************** */
/* add TimeMarker at curent frame */
static int ed_marker_add(bContext *C, wmOperator *op)
{
ListBase *markers= context_get_markers(C);
TimeMarker *marker;
int frame= C->scene->r.cfra;
/* two markers can't be at the same place */
for(marker= C->scene->markers.first; marker; marker= marker->next)
for(marker= markers->first; marker; marker= marker->next)
if(marker->frame == frame)
return OPERATOR_CANCELLED;
/* deselect all */
for(marker= C->scene->markers.first; marker; marker= marker->next)
for(marker= markers->first; marker; marker= marker->next)
marker->flag &= ~SELECT;
marker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
marker->flag= SELECT;
marker->frame= frame;
BLI_addtail(&(C->scene->markers), marker);
BLI_addtail(markers, marker);
//BIF_undo_push("Add Marker");
return OPERATOR_FINISHED;
}
/* remove selected TimeMarkers */
void ed_marker_remove(bContext *C)
static void ED_MARKER_OT_add(wmOperatorType *ot)
{
TimeMarker *marker, *nmarker;
short changed= 0;
/* identifiers */
ot->name= "Add Time Marker";
ot->idname= "ED_MARKER_OT_add";
for(marker= C->scene->markers.first; marker; marker= nmarker) {
nmarker= marker->next;
if(marker->flag & SELECT) {
BLI_freelinkN(&(C->scene->markers), marker);
changed= 1;
/* api callbacks */
ot->exec= ed_marker_add;
ot->poll= ED_operator_areaactive;
}
/* ************************** transform markers *************************** */
/* operator state vars used:
frs: delta movement
functions:
init() check selection, add customdata with old values and some lookups
apply() do the actual movement
exit() cleanup, send notifier
cancel() to escpae from modal
callbacks:
exec() calls init, apply, exit
invoke() calls init, adds modal handler
modal() accept modal events while doing it, ends with apply and exit, or cancel
*/
typedef struct MarkerMove {
SpaceLink *slink;
ListBase *markers;
int event_type; /* store invoke-event, to verify */
int *oldframe, evtx, firstx;
short swinid;
} MarkerMove;
/* copy selection to temp buffer */
/* return 0 if not OK */
static int ed_marker_move_init(bContext *C, wmOperator *op)
{
ListBase *markers= context_get_markers(C);
MarkerMove *mm;
TimeMarker *marker;
int totmark, a;
for (marker= markers->first; marker; marker= marker->next)
if (marker->flag & SELECT) totmark++;
if (totmark==0) return 0;
op->customdata= mm= MEM_callocN(sizeof(MarkerMove), "Markermove");
mm->slink= C->area->spacedata.first;
mm->markers= markers;
mm->oldframe= MEM_callocN(totmark*sizeof(int), "MarkerMove oldframe");
for (a=0, marker= markers->first; marker; marker= marker->next) {
if (marker->flag & SELECT) {
mm->oldframe[a]= marker->frame;
a++;
}
}
// if (changed)
// BIF_undo_push("Remove Marker");
return 1;
}
/* free stuff */
static void ed_marker_move_exit(bContext *C, wmOperator *op)
{
MarkerMove *mm= op->customdata;
MEM_freeN(mm->oldframe);
MEM_freeN(op->customdata);
op->customdata= NULL;
}
static int ed_marker_move_invoke(bContext *C, wmOperator *op, wmEvent *evt)
{
if(ed_marker_move_init(C, op)) {
MarkerMove *mm= op->customdata;
mm->evtx= evt->x;
mm->firstx= evt->x;
mm->swinid= C->region->swinid;
mm->event_type= evt->type;
/* add temp handler */
WM_event_add_modal_handler(&C->window->handlers, op);
/* reset frs delta */
RNA_int_set(op->ptr, "frs", 0);
return OPERATOR_RUNNING_MODAL;
}
return OPERATOR_CANCELLED;
}
/* note, init has to be called succesfully */
static void ed_marker_move_apply(bContext *C, wmOperator *op)
{
MarkerMove *mm= op->customdata;
TimeMarker *marker;
int a, offs;
offs= RNA_int_get(op->ptr, "frs");
for (a=0, marker= mm->markers->first; marker; marker= marker->next) {
if (marker->flag & SELECT) {
marker->frame= mm->oldframe[a] + offs;
a++;
}
}
}
/* only for modal */
static void ed_marker_move_cancel(bContext *C, wmOperator *op)
{
MarkerMove *mm= op->customdata;
RNA_int_set(op->ptr, "frs", 0);
ed_marker_move_apply(C, op);
ed_marker_move_exit(C, op);
WM_event_remove_modal_handler(&C->window->handlers, op);
WM_event_add_notifier(C->wm, C->window, mm->swinid, WM_NOTE_AREA_REDRAW, 0, NULL);
}
/* duplicate selected TimeMarkers */
void ed_marker_duplicate(bContext *C)
/* for tweak handlers, check configuration for how to interpret events */
int WM_modal_tweak_check(wmEvent *evt, int tweak_event)
{
/* user preset?? dunno... */
int tweak_modal= 1;
switch(tweak_event) {
case EVT_TWEAK_L:
case EVT_TWEAK_M:
case EVT_TWEAK_R:
if(evt->val==tweak_modal)
return 1;
default:
/* this case is when modal callcback didnt get started with a tweak */
if(evt->val)
return 1;
}
return 0;
}
static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
{
MarkerMove *mm= op->customdata;
View2D *v2d= context_get_view2d(C);
TimeMarker *marker, *selmarker=NULL;
float dx, fac;
char str[256];
switch(evt->type) {
case ESCKEY:
ed_marker_move_cancel(C, op);
return OPERATOR_CANCELLED;
case LEFTMOUSE:
case MIDDLEMOUSE:
case RIGHTMOUSE:
if(WM_modal_tweak_check(evt, mm->event_type)) {
ed_marker_move_exit(C, op);
WM_event_remove_modal_handler(&C->window->handlers, op);
WM_event_add_notifier(C->wm, C->window, mm->swinid, WM_NOTE_AREA_REDRAW, 0, NULL);
return OPERATOR_FINISHED;
}
break;
case MOUSEMOVE:
dx= v2d->mask.xmax-v2d->mask.xmin;
dx= (v2d->cur.xmax-v2d->cur.xmin)/dx;
if (evt->x != mm->evtx) { /* XXX maybe init for firsttime */
int a, offs, totmark=0;
mm->evtx= evt->x;
fac= ((float)(evt->x - mm->firstx)*dx);
if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND))
apply_keyb_grid(&fac, 0.0, FPS, 0.1*FPS, 0);
else
apply_keyb_grid(&fac, 0.0, 1.0, 0.1, U.flag & USER_AUTOGRABGRID);
offs= (int)fac;
RNA_int_set(op->ptr, "frs", offs);
ed_marker_move_apply(C, op);
/* cruft below is for header print */
for (a=0, marker= mm->markers->first; marker; marker= marker->next) {
if (marker->flag & SELECT) {
selmarker= marker;
a++; totmark++;
}
}
if (totmark==1) {
/* we print current marker value */
if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND)) {
SpaceTime *stime= (SpaceTime *)mm->slink;
if (stime->flag & TIME_DRAWFRAMES)
sprintf(str, "Marker %d offset %d", selmarker->frame, offs);
else
sprintf(str, "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs));
}
else if (mm->slink->spacetype == SPACE_ACTION) {
#if 0
XXX if (saction->flag & SACTION_DRAWTIME)
sprintf(str, "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs));
else
sprintf(str, "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs));
#endif
}
else {
sprintf(str, "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs));
}
}
else {
/* we only print the offset */
if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND)) {
SpaceTime *stime= (SpaceTime *)mm->slink;
if (stime->flag & TIME_DRAWFRAMES)
sprintf(str, "Marker offset %d ", offs);
else
sprintf(str, "Marker offset %.2f ", FRA2TIME(offs));
}
#if 0
XXX else if (mm->slink->spacetype == SPACE_ACTION) {
if (saction->flag & SACTION_DRAWTIME)
sprintf(str, "Marker offset %.2f ", FRA2TIME(offs));
else
sprintf(str, "Marker offset %.2f ", (double)(offs));
}
#endif
else {
sprintf(str, "Marker offset %.2f ", (double)(offs));
}
}
WM_event_add_notifier(C->wm, C->window, mm->swinid, WM_NOTE_AREA_REDRAW, 0, NULL);
// headerprint(str); XXX
}
}
return OPERATOR_RUNNING_MODAL;
}
static int ed_marker_move_exec(bContext *C, wmOperator *op)
{
if(ed_marker_move_init(C, op)) {
ed_marker_move_apply(C, op);
ed_marker_move_exit(C, op);
return OPERATOR_FINISHED;
}
return OPERATOR_CANCELLED;
}
static void ED_MARKER_OT_move(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Move Time Marker";
ot->idname= "ED_MARKER_OT_move";
/* api callbacks */
ot->exec= ed_marker_move_exec;
ot->invoke= ed_marker_move_invoke;
ot->modal= ed_marker_move_modal;
ot->poll= ED_operator_areaactive;
/* rna storage */
RNA_def_property(ot->srna, "frs", PROP_INT, PROP_NONE);
}
/* ************************** duplicate markers *************************** */
/* operator state vars used:
frs: delta movement
functions:
apply() do the actual duplicate
callbacks:
exec() calls apply, move_exec
invoke() calls apply, move_invoke
modal() uses move_modal
*/
/* duplicate selected TimeMarkers */
static void ed_marker_duplicate_apply(bContext *C, wmOperator *op)
{
ListBase *markers= context_get_markers(C);
TimeMarker *marker, *newmarker;
/* go through the list of markers, duplicate selected markers and add duplicated copies
* to the begining of the list (unselect original markers) */
for(marker= C->scene->markers.first; marker; marker= marker->next) {
for(marker= markers->first; marker; marker= marker->next) {
if(marker->flag & SELECT){
/* unselect selected marker */
marker->flag &= ~SELECT;
@@ -212,30 +533,330 @@ void ed_marker_duplicate(bContext *C)
newmarker->frame= marker->frame;
BLI_strncpy(newmarker->name, marker->name, sizeof(marker->name));
/* new marker is added to the begining of list */
BLI_addhead(&(C->scene->markers), newmarker);
BLI_addhead(markers, newmarker);
}
}
}
static int ed_marker_duplicate_exec(bContext *C, wmOperator *op)
{
ed_marker_duplicate_apply(C, op);
ed_marker_move_exec(C, op); /* assumes frs delta set */
return OPERATOR_FINISHED;
}
static int ed_marker_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *evt)
{
ed_marker_duplicate_apply(C, op);
return ed_marker_move_invoke(C, op, evt);
}
static void ED_MARKER_OT_duplicate(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Duplicate Time Marker";
ot->idname= "ED_MARKER_OT_duplicate";
/* api callbacks */
ot->exec= ed_marker_duplicate_exec;
ot->invoke= ed_marker_duplicate_invoke;
ot->modal= ed_marker_move_modal;
ot->poll= ED_operator_areaactive;
/* rna storage */
RNA_def_property(ot->srna, "frs", PROP_INT, PROP_NONE);
}
/* ************************** selection ************************************/
/* select/deselect TimeMarker at current frame */
static void select_timeline_marker_frame(int frame, unsigned char shift)
{
TimeMarker *marker;
int select=0;
for(marker= G.scene->markers.first; marker; marker= marker->next) {
/* if Shift is not set, then deselect Markers */
if(!shift) marker->flag &= ~SELECT;
/* this way a not-shift select will allways give 1 selected marker */
if((marker->frame == frame) && (!select)) {
if(marker->flag & SELECT)
marker->flag &= ~SELECT;
else
marker->flag |= SELECT;
select = 1;
}
}
}
static int find_nearest_marker_time(ListBase *markers, float dx)
{
TimeMarker *marker, *nearest= NULL;
float dist, min_dist= 1000000;
for(marker= markers->first; marker; marker= marker->next) {
dist = ABS((float)marker->frame - dx);
if(dist < min_dist){
min_dist= dist;
nearest= marker;
}
}
// transform_markers('g', 0);
if(nearest) return nearest->frame;
else return (int)floor(dx); /* hrmf? */
}
void ED_MARKER_OT_add(wmOperatorType *ot)
static int ed_marker_select(bContext *C, wmEvent *evt, int extend)
{
ListBase *markers= context_get_markers(C);
View2D *v2d= context_get_view2d(C);
float viewx;
int x, y, cfra;
x= evt->x - C->region->winrct.xmin;
y= evt->y - C->region->winrct.ymin;
UI_view2d_region_to_view(v2d, x, y, &viewx, NULL);
cfra= find_nearest_marker_time(markers, viewx);
if (extend)
select_timeline_marker_frame(cfra, 1);
else
select_timeline_marker_frame(cfra, 0);
/* XXX notifier for markers... */
WM_event_add_notifier(C->wm, C->window, C->region->swinid, WM_NOTE_AREA_REDRAW, 0, NULL);
return OPERATOR_PASS_THROUGH;
}
static int ed_marker_select_extend_invoke(bContext *C, wmOperator *op, wmEvent *evt)
{
return ed_marker_select(C, evt, 1);
}
static int ed_marker_select_invoke(bContext *C, wmOperator *op, wmEvent *evt)
{
return ed_marker_select(C, evt, 0);
}
static void ED_MARKER_OT_mouseselect(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add Time Marker";
ot->idname= "ED_MARKER_OT_add";
ot->name= "Select Time Marker";
ot->idname= "ED_MARKER_OT_mouseselect";
/* api callbacks */
ot->exec= ed_marker_add;
ot->invoke= ed_marker_select_invoke;
ot->poll= ED_operator_areaactive;
}
static void ED_MARKER_OT_mouseselect_extend(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Extend Select Time Marker";
ot->idname= "ED_MARKER_OT_mouseselect_extend";
/* api callbacks */
ot->invoke= ed_marker_select_extend_invoke;
ot->poll= ED_operator_areaactive;
}
/* *************************** border select markers **************** */
/* operator state vars used: (added by default WM callbacks)
xmin, ymin
xmax, ymax
customdata: the wmGesture pointer, with subwindow
callbacks:
exec() has to be filled in by user
invoke() default WM function
adds modal handler
modal() default WM function
accept modal events while doing it, calls exec(), handles ESC and border drawing
poll() has to be filled in by user for context
*/
static int ed_marker_border_select_exec(bContext *C, wmOperator *op)
{
View2D *v2d= context_get_view2d(C);
ListBase *markers= context_get_markers(C);
wmGesture *gesture= op->customdata;
TimeMarker *marker;
float xminf, xmaxf, yminf, ymaxf;
int event_type= RNA_int_get(op->ptr, "event_type");
int xmin= RNA_int_get(op->ptr, "xmin");
int xmax= RNA_int_get(op->ptr, "xmax");
int ymin= RNA_int_get(op->ptr, "ymin");
int ymax= RNA_int_get(op->ptr, "ymax");
UI_view2d_region_to_view(v2d, xmin, ymin, &xminf, &yminf);
UI_view2d_region_to_view(v2d, xmax, ymax, &xmaxf, &ymaxf);
/* XXX disputable */
if(yminf > 30.0f || ymaxf < 0.0f)
return 0;
/* XXX marker context */
for(marker= markers->first; marker; marker= marker->next) {
if ((marker->frame > xminf) && (marker->frame <= xmaxf)) {
switch (event_type) {
case LEFTMOUSE:
if ((marker->flag & SELECT) == 0)
marker->flag |= SELECT;
break;
case RIGHTMOUSE:
if (marker->flag & SELECT)
marker->flag &= ~SELECT;
break;
}
}
}
/* XXX notifier for markers..., XXX swinid??? */
WM_event_add_notifier(C->wm, C->window, gesture->swinid, WM_NOTE_AREA_REDRAW, 0, NULL);
return 1;
}
static void ED_MARKER_OT_border_select(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Marker Border select";
ot->idname= "ED_MARKER_OT_border_select";
/* api callbacks */
ot->exec= ed_marker_border_select_exec;
ot->invoke= WM_border_select_invoke;
ot->modal= WM_border_select_modal;
ot->poll= ED_operator_areaactive;
/* rna */
RNA_def_property(ot->srna, "event_type", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "xmin", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "xmax", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "ymin", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "ymax", PROP_INT, PROP_NONE);
}
/* *********************** (de)select all ***************** */
static int ed_marker_select_all_exec(bContext *C, wmOperator *op)
{
ListBase *markers= context_get_markers(C);
TimeMarker *marker;
int select= RNA_int_get(op->ptr, "select_type");
if(RNA_int_get(op->ptr, "select_swap")) {
for(marker= markers->first; marker; marker= marker->next) {
if(marker->flag & SELECT)
break;
}
if(marker)
select= 0;
else
select= 1;
}
for(marker= markers->first; marker; marker= marker->next) {
if(select)
marker->flag |= SELECT;
else
marker->flag &= ~SELECT;
}
/* XXX notifier for markers... */
WM_event_add_notifier(C->wm, C->window, C->region->swinid, WM_NOTE_AREA_REDRAW, 0, NULL);
return OPERATOR_FINISHED;
}
static int ed_marker_select_all_invoke(bContext *C, wmOperator *op, wmEvent *evt)
{
RNA_int_set(op->ptr, "select_swap", 1);
return ed_marker_select_all_exec(C, op);
}
static void ED_MARKER_OT_select_all(wmOperatorType *ot)
{
/* identifiers */
ot->name= "(De)select all markers";
ot->idname= "ED_MARKER_OT_select_all";
/* api callbacks */
ot->exec= ed_marker_select_all_exec;
ot->invoke= ed_marker_select_all_invoke;
ot->poll= ED_operator_areaactive;
/* rna */
RNA_def_property(ot->srna, "select_swap", PROP_INT, PROP_NONE);
RNA_def_property(ot->srna, "select_type", PROP_INT, PROP_NONE);
}
/* ******************************* remove marker ***************** */
/* remove selected TimeMarkers */
static int ed_marker_delete_exec(bContext *C, wmOperator *op)
{
ListBase *markers= context_get_markers(C);
TimeMarker *marker, *nmarker;
short changed= 0;
for(marker= markers->first; marker; marker= nmarker) {
nmarker= marker->next;
if(marker->flag & SELECT) {
BLI_freelinkN(markers, marker);
changed= 1;
}
}
/* XXX notifier for markers... */
if(changed)
WM_event_add_notifier(C->wm, C->window, C->region->swinid, WM_NOTE_AREA_REDRAW, 0, NULL);
return OPERATOR_FINISHED;
}
static void ED_MARKER_OT_delete(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Delete Markers";
ot->idname= "ED_MARKER_OT_delete";
/* api callbacks */
ot->exec= ed_marker_delete_exec;
ot->poll= ED_operator_areaactive;
}
/* ************************** registration **********************************/
void marker_operatortypes(void)
/* called in ED_operatortypes_screen() */
void ED_marker_operatortypes(void)
{
WM_operatortype_append(ED_MARKER_OT_add);
WM_operatortype_append(ED_MARKER_OT_move);
WM_operatortype_append(ED_MARKER_OT_duplicate);
WM_operatortype_append(ED_MARKER_OT_mouseselect);
WM_operatortype_append(ED_MARKER_OT_mouseselect_extend);
WM_operatortype_append(ED_MARKER_OT_border_select);
WM_operatortype_append(ED_MARKER_OT_select_all);
WM_operatortype_append(ED_MARKER_OT_delete);
}

View File

@@ -187,11 +187,20 @@ void time_keymap(wmWindowManager *wm)
{
WM_keymap_verify_item(&wm->timekeymap, "ED_TIME_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
/* markers (XXX move to function?) */
WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_add", MKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_move", EVT_TWEAK_R, KM_ANY, 0, 0);
WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_mouseselect", RIGHTMOUSE, KM_PRESS, 0, 0);
WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_mouseselect_extend", RIGHTMOUSE, KM_PRESS, KM_SHIFT, 0);
WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_border_select", BKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_select_all", AKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(&wm->timekeymap, "ED_MARKER_OT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(&wm->timekeymap, "WM_OT_tweak_gesture", RIGHTMOUSE, KM_PRESS, 0, 0); /* generates event */
//WM_keymap_add_item(&wm->screenkeymap, "ED_SCR_OT_area_split", EVT_TWEAK, EVT_GESTURE_S, 0, 0);
WM_keymap_add_item(&wm->timekeymap, "ED_MARKER_OT_move", GKEY, KM_PRESS, 0, 0);
/* generates event, in end to make select work */
WM_keymap_verify_item(&wm->timekeymap, "WM_OT_tweak_gesture", RIGHTMOUSE, KM_PRESS, 0, 0);
}

View File

@@ -0,0 +1,54 @@
#
# $Id: Makefile 14 2002-10-13 15:57:19Z hans $
#
# ***** 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) 2007 Blender Foundation
# All rights reserved.
#
# The Original Code is: all of this file.
#
# Contributor(s): none yet.
#
# ***** END GPL LICENSE BLOCK *****
#
# Makes module object directory and bounces make to subdirectories.
LIBNAME = ed_util
DIR = $(OCGDIR)/blender/$(LIBNAME)
include nan_compile.mk
CFLAGS += $(LEVEL_1_C_WARNINGS)
CPPFLAGS += -I$(NAN_GLEW)/include
CPPFLAGS += -I$(OPENGL_HEADERS)
# not very neat....
CPPFLAGS += -I../../windowmanager
CPPFLAGS += -I../../blenloader
CPPFLAGS += -I../../blenkernel
CPPFLAGS += -I../../blenlib
CPPFLAGS += -I../../makesdna
CPPFLAGS += -I../../makesrna
CPPFLAGS += -I../../imbuf
CPPFLAGS += -I../../python
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
# own include
CPPFLAGS += -I../include

View File

@@ -0,0 +1,10 @@
#!/usr/bin/python
Import ('env')
sources = env.Glob('*.c')
incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../makesrna'
env.BlenderLib ( 'bf_editors_util', sources, Split(incs), [], libtype=['core','intern'], priority=[35, 40] )

View File

@@ -0,0 +1,68 @@
/**
* $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) 2008 Blender Foundation.
* All rights reserved.
*
*
* Contributor(s): Blender Foundation
*
* ***** END GPL LICENSE BLOCK *****
*/
#include <stdlib.h>
#include <math.h>
#include "MEM_guardedalloc.h"
#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
#include "BKE_global.h"
/* ********* general editor util funcs, not BKE stuff please! ********* */
/* ***** XXX: functions are using old blender names, cleanup later ***** */
/* now only used in 2d spaces, like time, ipo, nla, sima... */
/* XXX clean G.qual */
void apply_keyb_grid(float *val, float fac1, float fac2, float fac3, int invert)
{
/* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
int ctrl;
if(invert) {
if(G.qual & LR_CTRLKEY) ctrl= 0;
else ctrl= 1;
}
else ctrl= (G.qual & LR_CTRLKEY);
if(ctrl && (G.qual & LR_SHIFTKEY)) {
if(fac3!= 0.0) *val= fac3*floor(*val/fac3 +.5);
}
else if(ctrl) {
if(fac2!= 0.0) *val= fac2*floor(*val/fac2 +.5);
}
else {
if(fac1!= 0.0) *val= fac1*floor(*val/fac1 +.5);
}
}

View File

@@ -218,7 +218,7 @@ typedef struct UserDef {
struct ColorBand coba_weight; /* from texture.h */
} UserDef;
extern UserDef U; /* from usiblender.c !!!! */
extern UserDef U; /* from blenkernel blender.c */
/* ***************** USERDEF ****************** */

View File

@@ -166,9 +166,9 @@ typedef struct wmOperator {
wmOperatorType *type;
char idname[64]; /* used to retrieve type pointer */
/* custom storage, dna pointer */
/* custom storage, only while operator runs, not saved */
void *customdata;
/* or IDproperty list */
/* IDproperty list */
IDProperty *properties;
/* runtime */

View File

@@ -110,6 +110,7 @@ int wm_gesture_evaluate(bContext *C, wmGesture *gesture)
else if(theta==-2) val= EVT_GESTURE_S;
else if(theta==-3) val= EVT_GESTURE_SW;
#if 0
/* debug */
if(val==1) printf("tweak north\n");
if(val==2) printf("tweak north-east\n");
@@ -119,7 +120,7 @@ int wm_gesture_evaluate(bContext *C, wmGesture *gesture)
if(val==6) printf("tweak south-west\n");
if(val==7) printf("tweak west\n");
if(val==8) printf("tweak north-west\n");
#endif
return val;
}
}

View File

@@ -38,9 +38,10 @@
#include "BKE_blender.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_idprop.h"
#include "BKE_utildefines.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -81,7 +82,7 @@ void WM_operatortype_append(void (*opfunc)(wmOperatorType*))
BLI_addtail(&global_ops, ot);
}
/* ************ default ops, exported *********** */
/* ************ default op callbacks, exported *********** */
int WM_operator_confirm(bContext *C, wmOperator *op, wmEvent *event)
{
@@ -159,6 +160,11 @@ static void border_select_apply(bContext *C, wmOperator *op, int event_type)
wmGesture *gesture= op->customdata;
rcti *rect= gesture->customdata;
if(rect->xmin > rect->xmax)
SWAP(int, rect->xmin, rect->xmax);
if(rect->ymin > rect->ymax)
SWAP(int, rect->ymin, rect->ymax);
/* operator arguments and storage. */
RNA_int_set(op->ptr, "xmin", rect->xmin);
RNA_int_set(op->ptr, "ymin", rect->ymin);
@@ -282,7 +288,12 @@ static int tweak_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
wmEvent event;
event= *(C->window->eventstate);
event.type= EVT_TWEAK;
if(gesture->event_type==LEFTMOUSE)
event.type= EVT_TWEAK_L;
else if(gesture->event_type==RIGHTMOUSE)
event.type= EVT_TWEAK_R;
else
event.type= EVT_TWEAK_M;
event.val= val;
/* mouse coords! */
wm_event_add(C->window, &event);
@@ -342,7 +353,7 @@ void wm_operatortype_init(void)
void wm_window_keymap(wmWindowManager *wm)
{
/* note, this doesn't replace existing keymap items */
WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_window_duplicate", AKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_window_duplicate", AKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_window_fullscreen_toggle", FKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(&wm->windowkeymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0);

View File

@@ -260,8 +260,12 @@
/* **************** BLENDER GESTURE EVENTS ********************* */
#define EVT_ACTIONZONE 0x5001
#define EVT_TWEAK 0x5002
#define EVT_GESTURE 0x5003
/* tweak events, for L M R mousebuttons */
#define EVT_TWEAK_L 0x5002
#define EVT_TWEAK_M 0x5003
#define EVT_TWEAK_R 0x5004
#define EVT_GESTURE 0x5005
/* value of tweaks and line gestures, note, KM_ANY (-1) works for this case too */
#define EVT_GESTURE_N 1