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

📄 dom_events.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Cyril Concolato 2004 *					All rights reserved * *  This file is part of GPAC / DOM 3 Events sub-project * *  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 <gpac/internal/scenegraph_dev.h>#include <gpac/xml.h>#ifndef GPAC_DISABLE_SVG#include <gpac/scenegraph_svg.h>#include <gpac/events.h>#include <gpac/nodes_svg_sa.h>#include <gpac/nodes_svg_sani.h>#include <gpac/nodes_svg_da.h>static void gf_smil_handle_event(GF_Node *anim, GF_FieldInfo *info, GF_DOM_Event *evt, Bool is_end);GF_Err gf_dom_listener_add(GF_Node *node, GF_Node *listener){	if (!node || !listener) return GF_BAD_PARAM;	if ((listener->sgprivate->tag!=TAG_SVG_listener)#ifdef GPAC_ENABLE_SVG_SANI		&& (listener->sgprivate->tag!=TAG_SVG_SA_listener)#endif#ifdef GPAC_ENABLE_SVG_SANI		&& (listener->sgprivate->tag!=TAG_SVG_SANI_listener)#endif		) return GF_BAD_PARAM;	if (!node->sgprivate->interact) GF_SAFEALLOC(node->sgprivate->interact, struct _node_interactive_ext);	if (!node->sgprivate->interact->events) node->sgprivate->interact->events = gf_list_new();	/*only one observer per listener*/	if (listener->sgprivate->UserPrivate!=NULL) return GF_NOT_SUPPORTED;	listener->sgprivate->UserPrivate = node;	return gf_list_add(node->sgprivate->interact->events, listener);}GF_Err gf_dom_listener_del(GF_Node *node, GF_Node *listener){	if (!node || !node->sgprivate->interact || !node->sgprivate->interact->events || !listener) return GF_BAD_PARAM;	return (gf_list_del_item(node->sgprivate->interact->events, listener)<0) ? GF_BAD_PARAM : GF_OK;}GF_EXPORTu32 gf_dom_listener_count(GF_Node *node){	if (!node || !node->sgprivate->interact || !node->sgprivate->interact->events) return 0;	return gf_list_count(node->sgprivate->interact->events);}GF_EXPORTGF_Node *gf_dom_listener_get(GF_Node *node, u32 i){	if (!node || !node->sgprivate->interact) return 0;	return (GF_Node *)gf_list_get(node->sgprivate->interact->events, i);}typedef struct{	GF_Node *obs;	GF_Node *listener;} DOMAddListener;void gf_dom_listener_post_add(GF_Node *obs, GF_Node *listener){	DOMAddListener *l;	l = (DOMAddListener*)malloc(sizeof(DOMAddListener));	l->listener = listener;	l->obs = obs;	gf_list_add(obs->sgprivate->scenegraph->listeners_to_add, l);}void gf_dom_listener_process_add(GF_SceneGraph *sg){	u32 i, count;	count = gf_list_count(sg->listeners_to_add);	for (i=0; i<count; i++) {		DOMAddListener *l = (DOMAddListener *)gf_list_get(sg->listeners_to_add, i);		gf_dom_listener_add(l->obs, l->listener);		free(l);	}	gf_list_reset(sg->listeners_to_add);}void gf_sg_handle_dom_event(GF_Node *hdl, GF_DOM_Event *event){#ifdef GPAC_HAS_SPIDERMONKEY	if (hdl->sgprivate->scenegraph->svg_js) 		if (hdl->sgprivate->scenegraph->svg_js->handler_execute(hdl, event)) return;#endif	/*no clue what this is*/	GF_LOG(GF_LOG_WARNING, GF_LOG_COMPOSE, ("[DOM Events    ] Unknown event handler\n"));}static void svg_process_event(GF_Node *listen, GF_DOM_Event *event){	GF_Node *hdl_node;	switch (listen->sgprivate->tag) {#ifdef GPAC_ENABLE_SVG_SA	case TAG_SVG_SA_listener:		hdl_node = ((SVG_SA_listenerElement *)listen)->handler.target;		break;#endif#ifdef GPAC_ENABLE_SVG_SANI	case TAG_SVG_SANI_listener:		hdl_node = ((SVG_SANI_listenerElement *)listen)->handler.target;		break;#endif	case TAG_SVG_listener:	{		GF_FieldInfo info;		if (gf_svg_get_attribute_by_tag(listen, TAG_SVG_ATT_handler, 0, 0, &info) == GF_OK) {			XMLRI *iri = (XMLRI *)info.far_ptr;			if (!iri->target && iri->string) {				iri->target = gf_sg_find_node_by_name(listen->sgprivate->scenegraph, iri->string+1);			}			hdl_node = iri->target;		} else {			return;		}	}		break;	default:		return;	}	if (!hdl_node) return;	GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[DOM Events    ] Time %f - Processing event type: %s\n", gf_node_get_scene_time((GF_Node *)listen), gf_dom_event_get_name(event->type)));	switch (hdl_node->sgprivate->tag) {#ifdef GPAC_ENABLE_SVG_SA_BASE#ifdef GPAC_ENABLE_SVG_SA	case TAG_SVG_SA_handler:#endif#ifdef GPAC_ENABLE_SVG_SANI	case TAG_SVG_SANI_handler:#endif	{		SVG_SA_handlerElement *handler = (SVG_SA_handlerElement *) hdl_node;		if (gf_svg_sa_is_animation_tag(handler->sgprivate->tag) && handler->anim && handler->timing->runtime) {			if (event->type == GF_EVENT_BATTERY) {				handler->timing->runtime->fraction = gf_divfix(INT2FIX(event->batteryLevel), INT2FIX(100));			} else if (event->type == GF_EVENT_CPU) {				handler->timing->runtime->fraction = gf_divfix(INT2FIX(event->cpu_percentage), INT2FIX(100));			}			switch (handler->timing->runtime->evaluate_status) {			case SMIL_TIMING_EVAL_NONE:				handler->timing->runtime->evaluate_status = SMIL_TIMING_EVAL_FRACTION;			case SMIL_TIMING_EVAL_FRACTION:				handler->timing->runtime->fraction = (handler->timing->runtime->fraction>FIX_ONE?FIX_ONE:handler->timing->runtime->fraction);				handler->timing->runtime->fraction = (handler->timing->runtime->fraction<0?0:handler->timing->runtime->fraction);				handler->timing->runtime->evaluate_status = SMIL_TIMING_EVAL_FRACTION;				break;			}	//		printf("event handled %f\n",FLT2FIX(handler->timing->runtime->fraction));			return;		}#if 0		/*laser-like handling*/		if (handler->timing) {			u32 i, count;			GF_List *times;			SMIL_Time *resolved;			GF_FieldInfo info;			if (listen->lsr_timeAttribute==LASeR_TIMEATTRIBUTE_END) times = handler->timing->end;			else times = handler->timing->begin;			/*solve*/			GF_SAFEALLOC(resolved, SMIL_Time);			resolved->type = SMIL_TIME_CLOCK;			resolved->clock = gf_node_get_scene_time((GF_Node *)handler) + listen->lsr_delay;			resolved->dynamic_type=2;			count = gf_list_count(times);			for (i=0; i<count; i++) {				SMIL_Time *proto = gf_list_get(times, i);				if ( (proto->type == SMIL_TIME_INDEFINITE) 					|| ( (proto->type == SMIL_TIME_CLOCK) && (proto->clock > resolved->clock) ) 					) 					break;			}			gf_list_insert(times, resolved, i);			memset(&info , 0, sizeof(GF_FieldInfo));			info.fieldType = SMIL_Times_datatype;			info.far_ptr = &times;			gf_node_changed((GF_Node*)handler, &info);			return;		}#endif		if (!handler->handle_event) return;		if (handler->ev_event.type != event->type) return;		handler->handle_event((GF_Node*)handler, event);	} 		break;#endif	/*GPAC_ENABLE_SVG_SA_BASE*/	case TAG_SVG_handler:	{		GF_FieldInfo info;		SVG_handlerElement *handler = (SVG_handlerElement *) hdl_node;		if (!handler->handle_event) return;		if (gf_svg_get_attribute_by_tag(hdl_node, TAG_SVG_ATT_ev_event, 0, 0, &info) == GF_OK) {			XMLEV_Event *ev_event = (XMLEV_Event *)info.far_ptr;			if (ev_event->type != event->type) return;			handler->handle_event(hdl_node, event);		} else {			handler->handle_event(hdl_node, event);		}	}		break;	case TAG_SVG_conditional:		if ( ((SVG_Element*)hdl_node)->children)			gf_node_render(((SVG_Element*)hdl_node)->children->node, NULL);		break;	default:		return;	}}static Bool sg_fire_dom_event(GF_Node *node, GF_DOM_Event *event){	if (!node) return 0;	if (node->sgprivate->interact && node->sgprivate->interact->events) {		u32 i, count, post_count;		count = gf_list_count(node->sgprivate->interact->events);		for (i=0; i<count; i++) {			GF_Node *handler = NULL;			XMLEV_Event *listened_event;			GF_Node *listen = (GF_Node *)gf_list_get(node->sgprivate->interact->events, i);			switch (listen->sgprivate->tag) {#ifdef GPAC_ENABLE_SVG_SA_BASE#ifdef GPAC_ENABLE_SVG_SA			case TAG_SVG_SA_listener:#endif#ifdef GPAC_ENABLE_SVG_SANI			case TAG_SVG_SANI_listener:#endif				listened_event = &((SVG_SA_listenerElement *)listen)->event;				handler = ((SVG_SA_listenerElement *)listen)->handler.target;				break;#endif /*GPAC_ENABLE_SVG_SA_BASE*/			case TAG_SVG_listener:			{				SVGAllAttributes atts;				gf_svg_flatten_attributes((SVG_Element*)listen, &atts);				listened_event = atts.event;				if (atts.handler) handler = atts.handler->target;			}				break;			default:				continue;			}			if (listened_event->type <= GF_EVENT_MOUSEMOVE) event->has_ui_events=1;			if (listened_event->type != event->type) continue;			if (listened_event->parameter && (listened_event->parameter != event->detail)) continue;			event->currentTarget = node;						/*load event cannot bubble and can only be called once (on load :) ), remove it			to release some resources*/			if (event->type==GF_EVENT_LOAD) {				svg_process_event(listen, event);				gf_list_rem(node->sgprivate->interact->events, i);				count--;				i--;				/*delete listener first, since it may be a child of the handler*/				gf_node_replace((GF_Node *) listen, NULL, 0);				if (handler) gf_node_replace(handler, NULL, 0);			} else {				assert(node->sgprivate->num_instances);				/*protect node*/				node->sgprivate->num_instances++;				/*exec event*/				svg_process_event(listen, event);				/*the event has destroyed ourselves, abort propagation				THIS IS NOT DOM compliant, the event should propagate on the original target+ancestors path*/				if (node->sgprivate->num_instances==1) {					/*unprotect node event*/					gf_node_unregister(node, NULL);					return 0;				}				node->sgprivate->num_instances--;			}			/*canceled*/			if (event->event_phase==4) {				gf_dom_listener_process_add(node->sgprivate->scenegraph);				return 0;			}			/*if listeners have been removed, update count*/			post_count = gf_list_count(node->sgprivate->interact->events);			if (post_count < count) {				s32 pos = gf_list_find(node->sgprivate->interact->events, listen);				if (pos>=0) i = pos;				/*FIXME this is not going to work in all cases...*/				else i--;				count = post_count;			}		}		/*propagation stoped*/		if (event->event_phase>=3) {			gf_dom_listener_process_add(node->sgprivate->scenegraph);			return 0;		}	}	gf_dom_listener_process_add(node->sgprivate->scenegraph);	return 1;}static void gf_sg_dom_event_bubble(GF_Node *node, GF_DOM_Event *event){	if (sg_fire_dom_event(node, event)) 		gf_sg_dom_event_bubble(gf_node_get_parent(node, 0), event);}void gf_sg_dom_stack_parents(GF_Node *node, GF_List *stack){	if (!node) return;	if (node->sgprivate->interact && node->sgprivate->interact->events) gf_list_insert(stack, node, 0);	gf_sg_dom_stack_parents(gf_node_get_parent(node, 0), stack);}GF_EXPORTBool gf_dom_event_fire(GF_Node *node, GF_Node *parent_use, GF_DOM_Event *event){

⌨️ 快捷键说明

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