Example #1
0
/* Callback for button press in the directory tree area */
static int
dirtree_select_cb( GtkWidget *ctree_w, GdkEventButton *ev_button )
{
	GNode *dnode;
	int row;

	/* If About presentation is up, end it */
	about( ABOUT_END );

	if (globals.fsv_mode == FSV_SPLASH)
		return FALSE;

	gtk_clist_get_selection_info( GTK_CLIST(ctree_w), ev_button->x, ev_button->y, &row, NULL );
	if (row < 0)
		return FALSE;

	dnode = (GNode *)gtk_clist_get_row_data( GTK_CLIST(ctree_w), row );
	if (dnode == NULL)
		return FALSE;

	/* A single-click from button 1 highlights the node, shows the
	 * name, and updates the file list if necessary. (and also selects
	 * the row, but GTK+ does that automatically for us) */
	if ((ev_button->button == 1) && (ev_button->type == GDK_BUTTON_PRESS)) {
		geometry_highlight_node( dnode, FALSE );
		window_statusbar( SB_RIGHT, node_absname( dnode ) );
		if (dnode != dirtree_current_dnode)
			filelist_populate( dnode );
		dirtree_current_dnode = dnode;
		return FALSE;
	}

	/* A double-click from button 1 gets the camera moving */
	if ((ev_button->button == 1) && (ev_button->type == GDK_2BUTTON_PRESS)) {
		camera_look_at( dnode );
		/* Preempt the forthcoming tree expand/collapse
		 * (the standard action spawned by a double-click) */
		gtk_signal_emit_stop_by_name( GTK_OBJECT(ctree_w), "button_press_event" );
		return TRUE;
	}

	/* A click from button 3 selects the row, highlights the node,
	 * shows the name, updates the file list if necessary, and brings
	 * up a context-sensitive menu */
	if (ev_button->button == 3) {
		gtk_clist_select_row( GTK_CLIST(ctree_w), row, 0 );
		geometry_highlight_node( dnode, FALSE );
		window_statusbar( SB_RIGHT, node_absname( dnode ) );
		if (dnode != dirtree_current_dnode)
			filelist_populate( dnode );
		dirtree_current_dnode = dnode;
		context_menu( dnode, ev_button );
		return FALSE;
	}

	return FALSE;
}
Example #2
0
/* Callback for a click in the file list area */
static int
filelist_select_cb( GtkWidget *clist_w, GdkEventButton *ev_button )
{
	GNode *node;
	int row;

	/* If About presentation is up, end it */
	about( ABOUT_END );

	if (globals.fsv_mode == FSV_SPLASH)
		return FALSE;

	gtk_clist_get_selection_info( GTK_CLIST(clist_w), ev_button->x, ev_button->y, &row, NULL );
	if (row < 0)
		return FALSE;

	node = (GNode *)gtk_clist_get_row_data( GTK_CLIST(clist_w), row );
	if (node == NULL)
		return FALSE;

	/* A single-click from button 1 highlights the node and shows the
	 * name (and also selects the row, but GTK+ does that for us) */
	if ((ev_button->button == 1) && (ev_button->type == GDK_BUTTON_PRESS)) {
		geometry_highlight_node( node, FALSE );
		window_statusbar( SB_RIGHT, node_absname( node ) );
		return FALSE;
	}

	/* A double-click from button 1 gets the camera moving */
	if ((ev_button->button == 1) && (ev_button->type == GDK_2BUTTON_PRESS)) {
		camera_look_at( node );
		return FALSE;
	}

	/* A click from button 3 selects the row, highlights the node,
	 * shows the name, and pops up a context-sensitive menu */
	if (ev_button->button == 3) {
		gtk_clist_select_row( GTK_CLIST(clist_w), row, 0 );
		geometry_highlight_node( node, FALSE );
		window_statusbar( SB_RIGHT, node_absname( node ) );
		context_menu( node, ev_button );
		return FALSE;
	}

	return FALSE;
}
Example #3
0
/* This callback catches all events for the viewport */
int
viewport_cb( GtkWidget *gl_area_w, GdkEvent *event )
{
	GdkEventButton *ev_button;
	GdkEventMotion *ev_motion;
	GNode *node;
	double dx, dy;
	unsigned int face_id;
	int x, y;
	boolean btn1, btn2, btn3;
	boolean ctrl_key;

	/* Handle low-level GL area widget events */
	switch (event->type) {
		case GDK_EXPOSE:
		ogl_refresh( );
		return FALSE;

		case GDK_CONFIGURE:
		ogl_resize( );
		return FALSE;

		default:
		/* Event is probably coming from the mouse */
		break;
	}

	if (event->type == GDK_BUTTON_PRESS) {
		/* Exit the About presentation if it is up */
		if (about( ABOUT_END )) {
			indicated_node = NULL;
			return FALSE;
		}
	}

	/* If we're in splash screen mode, proceed no further */
	if (globals.fsv_mode == FSV_SPLASH)
		return FALSE;

	/* Mouse-related events */
	switch (event->type) {
		case GDK_BUTTON_PRESS:
		ev_button = (GdkEventButton *)event;
		btn1 = ev_button->button == 1;
		btn2 = ev_button->button == 2;
		btn3 = ev_button->button == 3;
		ctrl_key = ev_button->state & GDK_CONTROL_MASK;
		x = (int)ev_button->x;
		y = (int)ev_button->y;
		if (camera_moving( )) {
			/* Yipe! Impatient user */
			camera_pan_finish( );
			indicated_node = NULL;
		}
		else if (!ctrl_key) {
			if (btn2)
				indicated_node = NULL;
			else
				indicated_node = node_at_location( x, y, &face_id );
			if (indicated_node == NULL) {
				geometry_highlight_node( NULL, FALSE );
				window_statusbar( SB_RIGHT, "" );
			}
			else {
				if (geometry_should_highlight( indicated_node, face_id ) || btn1)
					geometry_highlight_node( indicated_node, btn1 );
				else
					geometry_highlight_node( NULL, FALSE );
				window_statusbar( SB_RIGHT, node_absname( indicated_node ) );
				if (btn3) {
					/* Bring up context-sensitive menu */
					context_menu( indicated_node, ev_button );
					filelist_show_entry( indicated_node );
				}
			}
		}
		prev_x = x;
		prev_y = y;
		break;

		case GDK_2BUTTON_PRESS:
		/* Ignore second click of a double-click */
		break;

		case GDK_BUTTON_RELEASE:
		ev_button = (GdkEventButton *)event;
		btn1 = ev_button->state & GDK_BUTTON1_MASK;
		ctrl_key = ev_button->state & GDK_CONTROL_MASK;
		if (btn1 && !ctrl_key && !camera_moving( ) && (indicated_node != NULL))
			camera_look_at( indicated_node );
		gui_cursor( gl_area_w, -1 );
		break;

		case GDK_MOTION_NOTIFY:
		ev_motion = (GdkEventMotion *)event;
		btn1 = ev_motion->state & GDK_BUTTON1_MASK;
		btn2 = ev_motion->state & GDK_BUTTON2_MASK;
		btn3 = ev_motion->state & GDK_BUTTON3_MASK;
		ctrl_key = ev_motion->state & GDK_CONTROL_MASK;
		x = (int)ev_motion->x;
		y = (int)ev_motion->y;
		if (!camera_moving( ) && !gtk_events_pending( )) {
			if (btn2) {
				/* Dolly the camera */
				gui_cursor( gl_area_w, GDK_DOUBLE_ARROW );
				dy = MOUSE_SENSITIVITY * (y - prev_y);
				camera_dolly( - dy );
				indicated_node = NULL;
			}
			else if (ctrl_key && btn1) {
				/* Revolve the camera */
				gui_cursor( gl_area_w, GDK_FLEUR );
				dx = MOUSE_SENSITIVITY * (x - prev_x);
				dy = MOUSE_SENSITIVITY * (y - prev_y);
				camera_revolve( dx, dy );
				indicated_node = NULL;
			}
			else if (!ctrl_key && (btn1 || btn3)) {
				/* Pointless dragging */
				if (indicated_node != NULL) {
					node = node_at_location( x, y, &face_id );
					if (node != indicated_node)
						indicated_node = NULL;
				}
			}
                        else
				indicated_node = node_at_location( x, y, &face_id );
			/* Update node highlighting */
			if (indicated_node == NULL) {
				geometry_highlight_node( NULL, FALSE );
				window_statusbar( SB_RIGHT, "" );
			}
			else {
				if (geometry_should_highlight( indicated_node, face_id ) || btn1)
					geometry_highlight_node( indicated_node, btn1 );
				else
					geometry_highlight_node( NULL, FALSE);
				window_statusbar( SB_RIGHT, node_absname( indicated_node ) );
			}
			prev_x = x;
			prev_y = y;
		}
		break;

		case GDK_LEAVE_NOTIFY:
		/* The mouse has left the viewport */
		geometry_highlight_node( NULL, FALSE );
		window_statusbar( SB_RIGHT, "" );
		gui_cursor( gl_area_w, -1 );
		indicated_node = NULL;
		break;

		default:
		/* Ignore event */
		break;
	}

	return FALSE;
}
Example #4
0
static void draw_screen()
{
	static double last_frame_time;
	static int frame_index;
	static float frame_rates[FRAME_INDEX_MAX];
	static float frame_times[FRAME_INDEX_MAX];

	double start_time = time_now_double();

	glClearColor(0.0, 0.0, 0.0, 0.0);

	graph_dev_start_frame();

	sng_set_foreground(WHITE);
	sng_abs_xy_draw_string("F1 FOR HELP", NANO_FONT, SCREEN_WIDTH - 100, 10);

	static struct entity_context *cx;
	if (!cx)
		cx = entity_context_new(50, 50);

	if (wireframe != oldwireframe) {
		oldwireframe = wireframe;
		if (wireframe)
			set_renderer(cx, WIREFRAME_RENDERER | BLACK_TRIS);
		else
			set_renderer(cx, FLATSHADING_RENDERER);
	}

	float r = target_mesh->radius / tan(FOV / 3.0); /* 50% size for middle zoom */
	float r_cam = r * lobby_zoom / 255.0;
	
	camera_set_parameters(cx, 0.1f, r * 2.2, SCREEN_WIDTH, SCREEN_HEIGHT, FOV);
	camera_set_pos(cx, r_cam, 0, 0);
	camera_look_at(cx, 0, 0, 0);
	camera_assign_up_direction(cx, 0, 1, 0);

	union vec3 light_pos = { { 1.01 * r, 0, 0 } };
	quat_rot_vec_self(&light_pos, &light_orientation);
	set_lighting(cx, light_pos.v.x, light_pos.v.y, light_pos.v.z);

	calculate_camera_transform(cx);

	struct entity *e = add_entity(cx, target_mesh, 0, 0, 0, WHITE);
	struct entity *ae = NULL;
	if (planet_mode) {
		update_entity_material(e, &planet_material);
		if (draw_atmosphere) {
			ae = add_entity(cx, atmosphere_mesh, 0, 0, 0, WHITE);
			update_entity_scale(ae, 1.03);
			update_entity_material(ae, &atmosphere_material);
		}
	}
	update_entity_orientation(e, &lobby_orientation);

	if (isDraggingLight) {
		union vec3 light_dir = { { 10.75 * r_cam, 0, 0 } };
		quat_rot_vec_self(&light_dir, &light_orientation);
		sng_set_foreground(WHITE);
		render_line(cx, light_dir.v.x, light_dir.v.y, light_dir.v.z, 0, 0, 0);

		e = add_entity(cx, light_mesh, light_dir.v.x, light_dir.v.y, light_dir.v.z, WHITE);
	} else {
		e = add_entity(cx, light_mesh, light_pos.v.x, light_pos.v.y, light_pos.v.z, WHITE);
	}

	render_entities(cx);

	remove_all_entity(cx);

	if (helpmode)
		draw_help_screen(0);

	if (display_frame_stats > 0) {
		float avg_frame_rate = 0;
		float avg_frame_time = 0;
		int i;
		for (i = 0; i < FRAME_INDEX_MAX; i++) {
			avg_frame_rate += frame_rates[i];
			avg_frame_time += frame_times[i];
		}
		avg_frame_rate /= (float)FRAME_INDEX_MAX;
		avg_frame_time /= (float)FRAME_INDEX_MAX;

		sng_set_foreground(WHITE);
		char stat_buffer[30];
		sprintf(stat_buffer, "fps %5.2f", 1.0/avg_frame_rate);
		sng_abs_xy_draw_string(stat_buffer, NANO_FONT, 2, 10);
		sprintf(stat_buffer, "t %0.2f ms", avg_frame_time * 1000.0);
		sng_abs_xy_draw_string(stat_buffer, NANO_FONT, 92, 10);
	}
	if (display_frame_stats > 1)
		graph_dev_display_debug_menu_show();

	graph_dev_end_frame();

	glFinish();

	/*
	 * Swap the buffers. This this tells the driver to
	 * render the next frame from the contents of the
	 * back-buffer, and to set all rendering operations
	 * to occur on what was the front-buffer.
	 *
	 * Double buffering prevents nasty visual tearing
	 * from the application drawing on areas of the
	 * screen that are being updated at the same time.
	 */
	SDL_GL_SwapBuffers();

	if (display_frame_stats > 0) {
		double end_time = time_now_double();

		frame_rates[frame_index] = start_time - last_frame_time;
		frame_times[frame_index] = end_time - start_time;
		frame_index = (frame_index + 1) % FRAME_INDEX_MAX;
		last_frame_time = start_time;
	}
}