📄 render2d.c
字号:
cursor_type = evt.has_ui_events ? GF_CURSOR_TOUCH : GF_CURSOR_NORMAL; } else { /*mouse out*/ if (sr->grab_node) { memset(&evt, 0, sizeof(GF_DOM_Event)); evt.clientX = evt.screenX = FIX2INT(X); evt.clientY = evt.screenY = FIX2INT(Y); evt.bubbles = 1; evt.cancelable = 1; evt.key_flags = sr->compositor->key_states; evt.type = GF_EVENT_MOUSEOUT; ret += gf_dom_event_fire(sr->grab_node->node, sr->grab_use, &evt); } sr->grab_node = NULL; sr->grab_ctx = NULL; sr->grab_use = NULL; /*dispatch event to root SVG*/ memset(&evt, 0, sizeof(GF_DOM_Event)); evt.clientX = evt.screenX = FIX2INT(X); evt.clientY = evt.screenY = FIX2INT(Y); evt.bubbles = 1; evt.cancelable = 1; evt.key_flags = sr->compositor->key_states; evt.type = event->type; ret += gf_dom_event_fire(gf_sg_get_root_node(sr->compositor->scene), NULL, &evt); } if (sr->last_sensor != cursor_type) { R2DSETCURSOR(cursor_type); sr->last_sensor = cursor_type; } } else if (event->type==GF_EVENT_TEXTINPUT) { } else if ((event->type>=GF_EVENT_KEYUP) && (event->type<=GF_EVENT_LONGKEYPRESS)) { GF_Node *target; memset(&evt, 0, sizeof(GF_DOM_Event)); evt.key_flags = event->key.flags; evt.bubbles = 1; evt.cancelable = 1; evt.type = event->type; evt.detail = event->key.key_code; evt.key_hw_code = event->key.hw_code; target = sr->focus_node; if (!target) target = gf_sg_get_root_node(sr->compositor->scene); ret += gf_dom_event_fire(target, NULL, &evt); if (event->type==GF_EVENT_KEYDOWN) { switch (event->key.key_code) { case GF_KEY_ENTER: evt.type = GF_EVENT_ACTIVATE; evt.detail = 0; ret += gf_dom_event_fire(target, NULL, &evt); break; case GF_KEY_TAB: ret += svg_focus_switch_ring(sr, (event->key.flags & GF_KEY_MOD_SHIFT) ? 1 : 0); break; case GF_KEY_UP: case GF_KEY_DOWN: case GF_KEY_LEFT: case GF_KEY_RIGHT: ret += svg_focus_navigate(sr, event->key.key_code); break; } } /* else if (event->event_type==GF_EVENT_CHAR) { } else { evt.type = ((event->event_type==GF_EVENT_VKEYDOWN) || (event->event_type==GF_EVENT_KEYDOWN)) ? GF_EVENT_KEYDOWN : GF_EVENT_KEYUP; evt.detail = event->key.virtual_code; }*/ } return ret;}#endifBool R2D_ExecuteEvent(GF_VisualRenderer *vr, GF_Event *event){ u32 i, type, count; Bool act; s32 key_inv; Fixed key_trans; GF_Event evt; SensorContext *sc; DrawableContext *ctx, *prev_ctx; Render2D *sr = (Render2D *)vr->user_priv; evt = *event; if (event->type<=GF_EVENT_MOUSEWHEEL) { R2D_MapCoordsToAR(sr, &evt.mouse.x, &evt.mouse.y); }#ifndef GPAC_DISABLE_SVG /*DOM-style events*/ if (sr->use_dom_events) { if (R2D_ExecuteDOMEvent(vr, event, INT2FIX(evt.mouse.x), INT2FIX(evt.mouse.y) )) { sr->grabbed = 0; return 1; } goto browser_event; }#endif /*only process mouse events for MPEG-4/VRML*/ if (event->type>=GF_EVENT_MOUSEWHEEL) goto browser_event; if (sr->is_tracking) { /*in case a node is inserted at the depth level of a node previously tracked (rrrhhhaaaa...) */ if (sr->grab_ctx && sr->grab_ctx->drawable != sr->grab_node) { sr->is_tracking = 0; sr->grab_ctx = NULL; } } prev_ctx = sr->grab_ctx; if (!sr->is_tracking) { ctx = VS2D_PickSensitiveNode(sr->surface, INT2FIX(evt.mouse.x), INT2FIX(evt.mouse.y) ); sr->grab_ctx = ctx; if (ctx) sr->grab_node = ctx->drawable; } else { ctx = sr->grab_ctx; } //3- mark all sensors of the context to skip deactivation if (ctx) { SensorContext *sc = ctx->sensor; type = GF_CURSOR_NORMAL; while (sc) { sc->h_node->skip_second_pass = 1; if (!sc->next) { switch (gf_node_get_tag(sc->h_node->owner)) { case TAG_MPEG4_Anchor: type = GF_CURSOR_ANCHOR; break; case TAG_MPEG4_PlaneSensor2D: type = GF_CURSOR_PLANE; break; case TAG_MPEG4_DiscSensor: type = GF_CURSOR_ROTATE; break; case TAG_MPEG4_ProximitySensor2D: type = GF_CURSOR_PROXIMITY; break; case TAG_MPEG4_TouchSensor: type = GF_CURSOR_TOUCH; break;#ifndef GPAC_DISABLE_SVG#ifdef GPAC_ENABLE_SVG_SA case TAG_SVG_SA_a: #endif case TAG_SVG_a: type = GF_CURSOR_ANCHOR; break;#endif default: type = GF_CURSOR_TOUCH; break; } } sc = sc->next; } //also notify the app we're above a sensor if (type != GF_CURSOR_NORMAL) { if (sr->last_sensor != type) { GF_Event evt; evt.type = GF_EVENT_SET_CURSOR; evt.cursor.cursor_type = type; sr->compositor->video_out->ProcessEvent(sr->compositor->video_out, &evt); sr->last_sensor = type; } } } if (!ctx && (sr->last_sensor != GF_CURSOR_NORMAL)) { R2DSETCURSOR(GF_CURSOR_NORMAL); sr->last_sensor = GF_CURSOR_NORMAL; } /*deactivate all other registered sensors*/ count = gf_list_count(sr->sensors); for (i=0; i< count; i++) { SensorHandler *sh = (SensorHandler *)gf_list_get(sr->sensors, i); act = ! sh->skip_second_pass; sh->skip_second_pass = 0; if (act) sh->OnUserEvent(sh, &evt, NULL, NULL); if (count != gf_list_count(sr->sensors)) { count--; i-= 1; } } /*some sensors may not register with us, we still call them*/ if (prev_ctx && (prev_ctx != ctx)) { sc = prev_ctx->sensor; while (sc) { sc->h_node->OnUserEvent(sc->h_node, &evt, NULL, NULL); sc = sc->next; } } /*activate current one if any*/ if (ctx) { sc = ctx->sensor; while (sc) { sc->h_node->skip_second_pass = 0; if (sc->h_node->OnUserEvent(sc->h_node, &evt, ctx, &sc->matrix)) break; sc = sc->next; } return 1; }browser_event: /*no object, perform zoom & pan*/ if (!(sr->compositor->interaction_level & GF_INTERACT_NAVIGATION) || !sr->navigate_mode || sr->navigation_disabled) return 0; key_inv = 1; key_trans = 2*FIX_ONE; if (sr->compositor->key_states & GF_KEY_MOD_SHIFT) key_trans *= 4; switch (event->type) { case GF_EVENT_MOUSEDOWN: if (event->mouse.button==GF_MOUSE_LEFT) { sr->grab_x = evt.mouse.x; sr->grab_y = evt.mouse.y; sr->grabbed = 1; } break; case GF_EVENT_MOUSEUP: if (event->mouse.button==GF_MOUSE_LEFT) sr->grabbed = 0; break; case GF_EVENT_MOUSEWHEEL: if (sr->navigate_mode == GF_NAVIGATE_SLIDE) { Fixed new_zoom = sr->zoom; if (event->mouse.wheel_pos > 0) new_zoom += FIX_ONE/20; else new_zoom -= FIX_ONE/20; R2D_SetUserTransform(sr, new_zoom, sr->trans_x, sr->trans_y, 0); } break; case GF_EVENT_MOUSEMOVE: if (sr->grabbed && (sr->navigate_mode == GF_NAVIGATE_SLIDE)) { Fixed dx, dy; dx = INT2FIX(evt.mouse.x - sr->grab_x); dy = INT2FIX(evt.mouse.y - sr->grab_y); if (! sr->top_effect->is_pixel_metrics) { dx /= sr->cur_width; dy /= sr->cur_height; } if (sr->compositor->key_states & GF_KEY_MOD_SHIFT) { dx *= 2; dy *= 2; } /*set zoom*/ if (sr->compositor->key_states & GF_KEY_MOD_CTRL) { Fixed new_zoom = sr->zoom; if (new_zoom > FIX_ONE/2) new_zoom += dy/10; else new_zoom += dy*new_zoom/10; R2D_SetUserTransform(sr, new_zoom, sr->trans_x, sr->trans_y, 0); } /*set pan*/ else { R2D_SetUserTransform(sr, sr->zoom, sr->trans_x+dx, sr->trans_y+dy, 0); } sr->grab_x = evt.mouse.x; sr->grab_y = evt.mouse.y; } break; case GF_EVENT_KEYDOWN: switch (event->key.key_code) { case GF_KEY_HOME: if (!sr->grabbed) R2D_SetUserTransform(sr, FIX_ONE, 0, 0, 0); break; case GF_KEY_LEFT: key_inv = -1; case GF_KEY_RIGHT: sr->trans_x += key_inv*key_trans; R2D_SetUserTransform(sr, sr->zoom, sr->trans_x + key_inv*key_trans, sr->trans_y, 0); break; case GF_KEY_DOWN: key_inv = -1; case GF_KEY_UP: if (sr->compositor->key_states & GF_KEY_MOD_CTRL) { Fixed new_zoom = sr->zoom; if (new_zoom > FIX_ONE) new_zoom += key_inv*FIX_ONE/10; else new_zoom += key_inv*FIX_ONE/20; R2D_SetUserTransform(sr, new_zoom, sr->trans_x, sr->trans_y, 0); } else { R2D_SetUserTransform(sr, sr->zoom, sr->trans_x, sr->trans_y + key_inv*key_trans, 0); } break; case GF_KEY_VOLUMEDOWN: key_inv = -1; case GF_KEY_VOLUMEUP: { Fixed new_zoom = sr->zoom; if (new_zoom > FIX_ONE) new_zoom += key_inv*FIX_ONE/10; else new_zoom += key_inv*FIX_ONE/20; R2D_SetUserTransform(sr, new_zoom, sr->trans_x, sr->trans_y, 0); } break; } break; } return 0;}void R2D_DrawScene(GF_VisualRenderer *vr){ GF_Window rc; u32 i; GF_Err e; GF_SceneGraph *sg; RenderEffect2D static_eff; Render2D *sr = (Render2D *)vr->user_priv; GF_Node *top_node = gf_sg_get_root_node(sr->compositor->scene); if (!top_node && !sr->surface->last_had_back && !sr->surface->cur_context) { //GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 2D] Scene has no root node, nothing to draw\n")); return; } if (top_node && !sr->main_surface_setup) { sr->use_dom_events = 0; sr->main_surface_setup = 1; sr->surface->center_coords = 1; /*by default we set the focus on the content*/ //sr->focus_node = NULL; svg_focus_switch_ring(sr, 0); sr->top_effect->is_pixel_metrics = gf_sg_use_pixel_metrics(sr->compositor->scene); sr->top_effect->min_hsize = INT2FIX(MIN(sr->compositor->scene_width, sr->compositor->scene_height)) / 2;#ifndef GPAC_DISABLE_SVG { u32 node_tag = gf_node_get_tag(top_node); if ( ((node_tag>=GF_NODE_RANGE_FIRST_SVG) && (node_tag<=GF_NODE_RANGE_LAST_SVG)) #ifdef GPAC_ENABLE_SVG_SA || ((node_tag>=GF_NODE_RANGE_FIRST_SVG_SA) && (node_tag<=GF_NODE_RANGE_LAST_SVG_SA))#endif#ifdef GPAC_ENABLE_SVG_SANI || ((node_tag>=GF_NODE_RANGE_FIRST_SVG_SANI) && (node_tag<=GF_NODE_RANGE_LAST_SVG_SANI))#endif ) { sr->surface->center_coords = 0; sr->main_surface_setup = 2; sr->use_dom_events = 1; sr->top_effect->is_pixel_metrics = 1; } }#endif GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 2D] Main scene setup - Using DOM events: %d - pixel metrics %d - center coords %d\n", sr->use_dom_events, sr->top_effect->is_pixel_metrics, sr->surface->center_coords)); } memcpy(&static_eff, sr->top_effect, sizeof(RenderEffect2D)); sr->surface->width = sr->cur_width; sr->surface->height = sr->cur_height;#if 0 { GF_SystemRTInfo rti; gf_sys_get_rti(0, &rti, GF_RTI_SYSTEM_MEMORY_ONLY); fprintf(stdout, "Memory usage before DrawScene: %d\n", rti.gpac_memory); }#endif e = VS2D_InitDraw(sr->surface, sr->top_effect); if (e) return; GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 2D] Traversing scene tree (top node %s)\n", top_node ? gf_node_get_class_name(top_node) : "none"));#ifndef GPAC_DISABLE_SVG i = gf_sys_clock();#endif gf_node_render(top_node, sr->top_effect); GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 2D] Traversing scene done in %d ms\n", gf_sys_clock() - i)); i=0; while ((sg = (GF_SceneGraph*)gf_list_enum(sr->compositor->extra_scenes, &i))) { GF_Node *n = gf_sg_get_root_node(sg); if (n) gf_node_render(n, sr->top_effect); } VS2D_TerminateDraw(sr->surface, sr->top_effect); memcpy(sr->top_effect, &static_eff, sizeof(RenderEffect2D)); sr->top_effect->invalidate_all = 0; GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 2D] Rendering done - flushing output\n")); /*and flush*/ rc.x = rc.y = 0; rc.w = sr->compositor->width; rc.h = sr->compositor->height; sr->compositor->video_out->Flush(sr->compositor->video_out, &rc); sr->frame_num++;#if 0 { GF_SystemRTInfo rti; gf_sys_get_rti(0, &rti, GF_RTI_SYSTEM_MEMORY_ONLY); fprintf(stdout, "Memory usage after DrawScene: %d\n", rti.gpac_memory); }#endif /*reset all flags of all nodes registered on all extra surfaces this must be done once all surfaces have been drawn, otherwise we won't detect the changes for nodes drawn on # surfaces*/ for (i=1; i<gf_list_count(sr->surfaces_2D); i++) { VisualSurface2D *surf = gf_list_get(sr->surfaces_2D, i); DrawableContext *ctx = surf->context; while (ctx && ctx->drawable) { if (ctx->flags & CTX_HAS_APPEARANCE) gf_node_dirty_reset(ctx->appear); ctx = ctx->next; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -