⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sensor_stacks.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / 2D rendering module * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC 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 Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include "stacks2d.h"static void unregister_sensor(GF_Renderer *comp, SensorHandler *hdl){	R2D_UnregisterSensor(comp, hdl);	if (comp->interaction_sensors) comp->interaction_sensors--;}typedef struct {	SensorHandler hdl;	Bool mouse_down;	Fixed start_angle;	Bool last_not_over;	GF_Matrix2D inv_init_matrix;	GF_Renderer *compositor;} DiscSensorStack;static void DestroyDiscSensor(GF_Node *node, void *rs, Bool is_destroy){	if (is_destroy) {		DiscSensorStack *st = (DiscSensorStack *) gf_node_get_private(node);		unregister_sensor(st->compositor, &st->hdl);		free(st);	}}static Bool ds_is_enabled(SensorHandler *sh){	return ((M_DiscSensor *) sh->owner)->enabled;}static Fixed ds_point_to_angle(DiscSensorStack *st, M_DiscSensor *ds, Fixed X, Fixed Y){	Fixed result = gf_atan2(Y, X) - st->start_angle + ds->offset;	if (ds->minAngle < ds->maxAngle) {		/*FIXME this doesn't work properly*/		if (result < ds->minAngle) result = ds->minAngle;		if (result > ds->maxAngle) result = ds->maxAngle;	}	return result;}static Bool OnDiscSensor(SensorHandler *sh, GF_Event *evt, DrawableContext *ctx, GF_Matrix2D *sensor_matrix){	Fixed X, Y;	M_DiscSensor *ds = (M_DiscSensor *)sh->owner;	DiscSensorStack *stack = (DiscSensorStack *) gf_node_get_private(sh->owner);	Render2D *sr = (Render2D *)stack->compositor->visual_renderer->user_priv;		if (! ds->enabled) return 0;		if (ctx== NULL) {		if (stack->last_not_over) {			if ((evt->type == GF_EVENT_MOUSEUP) && (evt->mouse.button==GF_MOUSE_LEFT)) {				R2D_UnregisterSensor(stack->compositor, &stack->hdl);				sr->is_tracking = 0;				stack->mouse_down = 0;				if (ds->isActive) {					ds->isActive = 0;					gf_node_event_out_str(sh->owner, "isActive");				}			}			if (!stack->mouse_down)				R2D_UnregisterSensor(stack->compositor, &stack->hdl);			return 0;		}		stack->last_not_over = 1;		return 0;	}	stack->last_not_over = 0;	X = INT2FIX(evt->mouse.x);	Y = INT2FIX(evt->mouse.y);	if ((evt->type == GF_EVENT_MOUSEDOWN) && (evt->mouse.button==GF_MOUSE_LEFT) && !stack->mouse_down) {		stack->mouse_down = 1;		/*store inverse of initial matrix*/		gf_mx2d_copy(stack->inv_init_matrix, *sensor_matrix);		gf_mx2d_inverse(&stack->inv_init_matrix);		gf_mx2d_apply_coords(&stack->inv_init_matrix, &X, &Y);		stack->start_angle = gf_atan2(Y, X);		ds->isActive = 1;		gf_node_event_out_str(sh->owner, "isActive");		R2D_RegisterSensor(stack->compositor, &stack->hdl);		}	else if ((evt->type == GF_EVENT_MOUSEUP) && (evt->mouse.button==GF_MOUSE_LEFT) && stack->mouse_down) {		R2D_UnregisterSensor(stack->compositor, &stack->hdl);		sr->is_tracking = 0;		stack->mouse_down = 0;				gf_mx2d_apply_coords(&stack->inv_init_matrix, &X, &Y);		if (ds->autoOffset) {			ds->offset = ds->rotation_changed;			/*that's an exposedField*/			gf_node_event_out_str(sh->owner, "offset");		}		ds->isActive = 0;		gf_node_event_out_str(sh->owner, "isActive");		gf_mx2d_init(stack->inv_init_matrix);	}	else if ((evt->type == GF_EVENT_MOUSEMOVE) && stack->mouse_down) {		sr->is_tracking = 1;		gf_mx2d_apply_coords(&stack->inv_init_matrix, &X, &Y);		ds->rotation_changed = ds_point_to_angle(stack, ds, X, Y);		gf_node_event_out_str(sh->owner, "rotation_changed");	   	ds->trackPoint_changed.x = X;	   	ds->trackPoint_changed.y = Y;		gf_node_event_out_str(sh->owner, "trackPoint_changed");	}	return 0;}SensorHandler *r2d_ds_get_handler(GF_Node *n){	DiscSensorStack *st = (DiscSensorStack *)gf_node_get_private(n);	return &st->hdl;}void R2D_InitDiscSensor(Render2D *sr, GF_Node *node){	DiscSensorStack *st;	GF_SAFEALLOC(st, DiscSensorStack);	st->hdl.IsEnabled = ds_is_enabled;	st->hdl.OnUserEvent = OnDiscSensor;	st->hdl.owner = node;	st->compositor = sr->compositor;	sr->compositor->interaction_sensors++;	gf_node_set_private(node, st);	gf_node_set_callback_function(node, DestroyDiscSensor);}typedef struct {	SensorHandler hdl;	Bool mouse_down;	SFVec2f start_drag;	Bool last_not_over;	GF_Matrix2D init_matrix;	GF_Renderer *compositor;} PS2DStack;static void DestroyPlaneSensor2D(GF_Node *node, void *rs, Bool is_destroy){	if (is_destroy) {		PS2DStack *st = (PS2DStack *) gf_node_get_private(node);		unregister_sensor(st->compositor, &st->hdl);		free(st);	}}static Bool ps2D_is_enabled(SensorHandler *sh){	return ((M_PlaneSensor2D *) sh->owner)->enabled;}static SFVec2f get_translation(PS2DStack *stack, M_PlaneSensor2D *ps, Fixed X, Fixed Y, GF_Matrix2D *inversed_sensor_matrix){	SFVec2f res;	Fixed a, b;	a = stack->start_drag.x;	b = stack->start_drag.y;	gf_mx2d_apply_coords(&stack->init_matrix, &a, &b);	gf_mx2d_apply_coords(inversed_sensor_matrix, &a, &b);	res.x = X - a + ps->offset.x;	res.y = Y - b + ps->offset.y;	/*clip*/	if (ps->minPosition.x <= ps->maxPosition.x) {		if (res.x < ps->minPosition.x) res.x = ps->minPosition.x;		if (res.x > ps->maxPosition.x) res.x = ps->maxPosition.x;	}	if (ps->minPosition.y <= ps->maxPosition.y) {		if (res.y < ps->minPosition.y) res.y = ps->minPosition.y;		if (res.y > ps->maxPosition.y) res.y = ps->maxPosition.y;	}	return res;}static Bool OnPlaneSensor2D(SensorHandler *sh, GF_Event *evt, DrawableContext *ctx, GF_Matrix2D *sensor_matrix){	Fixed X, Y;	GF_Matrix2D inv;	M_PlaneSensor2D *ps = (M_PlaneSensor2D *)sh->owner;	PS2DStack *stack = (PS2DStack *) gf_node_get_private(sh->owner);	Render2D *sr = (Render2D *)stack->compositor->visual_renderer->user_priv;		if (!ps->enabled) return 0;	// this function is called when the mouse is not on a object	if (ctx == NULL) {		if (stack->last_not_over) {			if ((evt->type == GF_EVENT_MOUSEUP) && (evt->mouse.button==GF_MOUSE_LEFT)) {				sr->is_tracking = 0;				stack->mouse_down = 0;				if (ps->isActive) {					ps->isActive = 0;					gf_node_event_out_str(sh->owner, "isActive");				}			}			if (!stack->mouse_down) {				R2D_UnregisterSensor(stack->compositor, &stack->hdl);			}			return 0;		}		stack->last_not_over = 1;		return 0;	}	stack->last_not_over = 0;	gf_mx2d_copy(inv, *sensor_matrix);	gf_mx2d_inverse(&inv);	X = INT2FIX(evt->mouse.x);	Y = INT2FIX(evt->mouse.y);	gf_mx2d_apply_coords(&inv, &X, &Y);	if ((evt->type == GF_EVENT_MOUSEDOWN) && (evt->mouse.button==GF_MOUSE_LEFT) && !stack->mouse_down) {		stack->mouse_down = 1;		gf_mx2d_copy(stack->init_matrix, *sensor_matrix);		stack->start_drag.x = X;		stack->start_drag.y = Y;		R2D_RegisterSensor(stack->compositor, &stack->hdl);		ps->isActive = 1;		gf_node_event_out_str(sh->owner, "isActive");	}	if (evt->type == GF_EVENT_MOUSEUP && (evt->mouse.button==GF_MOUSE_LEFT) && stack->mouse_down) {		R2D_UnregisterSensor(stack->compositor, &stack->hdl);		sr->is_tracking = 0;		stack->mouse_down = 0;		if (ps->isActive) {			ps->isActive = 0;			gf_node_event_out_str(sh->owner, "isActive");		}				if (ps->autoOffset) {			ps->offset = get_translation(stack, ps, X, Y, &inv);			gf_node_event_out_str(sh->owner, "offset");		}		return 0;	}	if ( (evt->type == GF_EVENT_MOUSEMOVE) && stack->mouse_down) {		sr->is_tracking = 1;		ps->trackPoint_changed.x = X;		ps->trackPoint_changed.y = Y;		gf_node_event_out_str(sh->owner, "trackPoint_changed");				ps->translation_changed = get_translation(stack, ps, X, Y, &inv);		gf_node_event_out_str(sh->owner, "translation_changed");	}	return 0;}SensorHandler *r2d_ps2D_get_handler(GF_Node *n){	PS2DStack *st = (PS2DStack *)gf_node_get_private(n);	return &st->hdl;}void R2D_InitPlaneSensor2D(Render2D *sr, GF_Node *node){	PS2DStack *st;	GF_SAFEALLOC(st, PS2DStack);	st->hdl.IsEnabled = ps2D_is_enabled;	st->hdl.OnUserEvent = OnPlaneSensor2D;	st->hdl.owner = node;	st->compositor = sr->compositor;	st->compositor->interaction_sensors++;	gf_node_set_private(node, st);	gf_node_set_callback_function(node, DestroyPlaneSensor2D);}typedef struct {	SensorHandler hdl;	Double last_time;	Bool in_area, just_entered, has_left;	GF_Matrix2D init_matrix;	GF_Renderer *compositor;} Prox2DStack;static void DestroyProximitySensor2D(GF_Node *node, void *rs, Bool is_destroy){	if (is_destroy) {		Prox2DStack *st = (Prox2DStack *) gf_node_get_private(node);		unregister_sensor(st->compositor, &st->hdl);		free(st);	}}static Bool prox2D_is_enabled(SensorHandler *sh){	return ((M_ProximitySensor2D *) sh->owner)->enabled;}static Bool prox2D_is_in_sensor(Prox2DStack *st, M_ProximitySensor2D *ps, Fixed X, Fixed Y){	if (X < ps->center.x - ps->size.x/2) return 0;	if (X > ps->center.x + ps->size.x/2) return 0;	if (Y < ps->center.y - ps->size.y/2) return 0;	if (Y > ps->center.y + ps->size.y/2) return 0;	return 1;}static Bool OnProximitySensor2D(SensorHandler *sh, GF_Event *evt, DrawableContext *ctx, GF_Matrix2D *sensor_matrix){	Fixed X, Y;	GF_Matrix2D mat;	M_ProximitySensor2D *ps = (M_ProximitySensor2D *)sh->owner;	Prox2DStack *stack = (Prox2DStack *) gf_node_get_private(sh->owner);		if (! ps->enabled) return 0;		if (ctx) {		X = INT2FIX(evt->mouse.x);		Y = INT2FIX(evt->mouse.y);		gf_mx2d_copy(mat, *sensor_matrix);		gf_mx2d_inverse(&mat);		gf_mx2d_apply_coords(&mat, &X, &Y);		stack->last_time = gf_node_get_scene_time(sh->owner);		//don't use transform since we just reverted our coords		if (prox2D_is_in_sensor(stack, ps, X, Y)) {			stack->has_left = 0;			ps->position_changed.x = X;			ps->position_changed.y = Y;			gf_node_event_out_str(sh->owner, "position_changed");			if(! stack->just_entered) {				stack->just_entered = 1;				stack->in_area = 1;				ps->isActive = 1;				gf_node_event_out_str(sh->owner, "isActive");				ps->enterTime = stack->last_time;				gf_node_event_out_str(sh->owner, "enterTime");				R2D_RegisterSensor(stack->compositor, &stack->hdl);			}			return 0;		}	}	if (stack->in_area) {		if (stack->has_left) {			stack->in_area = 0;			stack->just_entered = 0;			ps->exitTime = stack->last_time;			gf_node_event_out_str(sh->owner, "exitTime");			ps->isActive = 0;			gf_node_event_out_str(sh->owner, "isActive");			R2D_UnregisterSensor(stack->compositor, &stack->hdl);			return 0;		}		stack->has_left = 1;	}	return 0;}SensorHandler *r2d_prox2D_get_handler(GF_Node *n){	Prox2DStack *st = (Prox2DStack *)gf_node_get_private(n);	return &st->hdl;}void R2D_InitProximitySensor2D(Render2D *sr, GF_Node *node){	Prox2DStack *st;	GF_SAFEALLOC(st, Prox2DStack);	st->hdl.IsEnabled = prox2D_is_enabled;	st->hdl.OnUserEvent = OnProximitySensor2D;	st->hdl.owner = node;	st->compositor = sr->compositor;	st->compositor->interaction_sensors++;	gf_node_set_private(node, st);	gf_node_set_callback_function(node, DestroyProximitySensor2D);}typedef struct {	SensorHandler hdl;	Bool mouse_down;	GF_Renderer *compositor;} TouchSensorStack;static void DestroyTouchSensor(GF_Node *node, void *rs, Bool is_destroy){	if (is_destroy) {		TouchSensorStack *st = (TouchSensorStack *) gf_node_get_private(node);		unregister_sensor(st->compositor, &st->hdl);		free(st);	}}static Bool ts_is_enabled(SensorHandler *sh){	return ((M_TouchSensor *) sh->owner)->enabled;}static Bool OnTouchSensor(SensorHandler *sh, GF_Event *evt, DrawableContext *ctx, GF_Matrix2D *sensor_matrix){	Fixed X, Y;	GF_Matrix2D inv;	M_TouchSensor *ts = (M_TouchSensor *)sh->owner;	TouchSensorStack *stack = (TouchSensorStack *) gf_node_get_private(sh->owner);	if (! ts->enabled) return 0;	if (ctx == NULL) {		if (ts->isOver) {			ts->isOver = 0;			gf_node_event_out_str(sh->owner, "isOver");		}		if (ts->isActive) {			if ((evt->type == GF_EVENT_MOUSEUP) && (evt->mouse.button==GF_MOUSE_LEFT)) {				ts->isOver = 0;				gf_node_event_out_str(sh->owner, "isOver");				ts->isActive = 0;				gf_node_event_out_str(sh->owner, "isActive");								/*no touchTime - VRML quote :"the pointing device shall be over the geometry (isOver is TRUE)"*/				stack->mouse_down = 0;				R2D_UnregisterSensor(stack->compositor, &stack->hdl);			}		} else {			stack->mouse_down = 0;			R2D_UnregisterSensor(stack->compositor, &stack->hdl);		}		return 0;	}	if ((evt->type == GF_EVENT_MOUSEMOVE) && !ts->isOver) {		ts->isOver = 1;		gf_node_event_out_str(sh->owner, "isOver");		R2D_RegisterSensor(stack->compositor, &stack->hdl);	}	if ((evt->type == GF_EVENT_MOUSEDOWN) && (evt->mouse.button==GF_MOUSE_LEFT) && !stack->mouse_down) {		ts->isActive = 1;		gf_node_event_out_str(sh->owner, "isActive");		stack->mouse_down = 1;	}	// If the button is first released, then generate an isActive = FALSE event, and ungrab all movement events.	if ((evt->type == GF_EVENT_MOUSEUP) && (evt->mouse.button==GF_MOUSE_LEFT) && stack->mouse_down) {		ts->isActive = 0;		gf_node_event_out_str(sh->owner, "isActive");		stack->mouse_down = 0;		ts->touchTime = gf_node_get_scene_time(sh->owner);		gf_node_event_out_str(sh->owner, "touchTime");	}	X = INT2FIX(evt->mouse.x);	Y = INT2FIX(evt->mouse.y);	gf_mx2d_copy(inv, *sensor_matrix);	gf_mx2d_inverse(&inv);	gf_mx2d_apply_coords(&inv, &X, &Y);	ts->hitPoint_changed.x = X;	ts->hitPoint_changed.y = Y;	ts->hitPoint_changed.z = 0;	gf_node_event_out_str(sh->owner, "hitPoint_changed");#if 0	X = ev->x;	Y = ev->y;	gf_mx2d_apply_coords(&ctx->transform, &X, &Y);		ts->hitTexCoord_changed.x = gf_divfix(X-ctx->unclip.x, ctx->unclip.width);	if (ts->hitTexCoord_changed.x < 0) ts->hitTexCoord_changed.x = 0;	else if (ts->hitTexCoord_changed.x > FIX_ONE) ts->hitTexCoord_changed.x = FIX_ONE;	ts->hitTexCoord_changed.y = (ctx->unclip.y-Y) / ctx->unclip.height;	if (ts->hitTexCoord_changed.y < 0) ts->hitTexCoord_changed.y = 0;	else if (ts->hitTexCoord_changed.y > FIX_ONE) ts->hitTexCoord_changed.y = FIX_ONE;	gf_node_event_out_str(sh->owner, "hitTexCoord_changed");#endif	return 0;}SensorHandler *r2d_touch_sensor_get_handler(GF_Node *n){	TouchSensorStack *ts = (TouchSensorStack *)gf_node_get_private(n);	return &ts->hdl;}void R2D_InitTouchSensor(Render2D *sr, GF_Node *node){	TouchSensorStack *st;	GF_SAFEALLOC(st, TouchSensorStack);	st->hdl.IsEnabled = ts_is_enabled;	st->hdl.OnUserEvent = OnTouchSensor;	st->hdl.owner = node;	st->compositor = sr->compositor;	st->compositor->interaction_sensors++;	gf_node_set_private(node, st);	gf_node_set_callback_function(node, DestroyTouchSensor);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -