📄 arrange.cpp
字号:
// ----------------------------------------------------------//// Copyright (C) 2002 Brad Wasson <bard@systemtoolbox.com>//// This file is part of 3ddesktop.//// 3ddesktop 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, or (at your option)// any later version.//// 3ddesktop 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 3ddesktop; see the file COPYING. If not, write to// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.//#include <stdio.h>#include <stdlib.h>#include <string.h> // for memsetusing namespace std;#include <stack>#include "3ddesk.h"#include "arrange.hpp"#include "util.h"#define LINEAR_MOVE_TYPE Movement::MOVE_TYPE_WACK#define CYLINDER_MOVE_TYPE Movement::MOVE_TYPE_WACK#define VIEWMASTER_MOVE_TYPE Movement::MOVE_TYPE_WACK#define CAROUSEL_MOVE_TYPE Movement::MOVE_TYPE_WACK// ==============================================================// Arrangement - abstract base class // ==============================================================Arrangement::Arrangement (FaceSet *fs, Config *c){ // defaults z_offset_distance = 7.0; face_list = glGenLists(1); move_type = Movement::MOVE_TYPE_WACK; cfg = c; face_set = fs; msgout(DEBUG, "Arrangement constructor\n"); //memset(faces, 0, sizeof(faces));}Arrangement::~Arrangement (){ glDeleteLists(face_list, 1);}void Arrangement::set_active (int i){ if (face_set) face_set->set_active(i);}void Arrangement::set_current_face (int col, int row) { current_col = col; current_row = row;}int Arrangement::get_current_column(void) { return current_col;}int Arrangement::get_current_row(void) { return current_row;}int Arrangement::get_number_of_columns(void) { return n_columns;}int Arrangement::get_number_of_rows(void) { return n_rows;}float Arrangement::get_current_z_offset(void) { return z_offset;}void Arrangement::set_z_offset_distance(float zod) { z_offset_distance = zod;}int Arrangement::cant_exit_in_goto(void){ // if not zooming the it is true that we cant exit while in goto return !cfg->options->entry_exit_movement;}void Arrangement::goto_up(void){ goto_right();}void Arrangement::goto_down(void){ goto_left();}void Arrangement::goto_right(void) { current_col++; if (current_col == n_columns) current_col = 0; // cycle around if (goto_face_mv.at_destination()) { goto_face_mv.init (&goto_face_val, goto_face_val, goto_face_val - per_face_change, cfg->options->face_change_steps, move_type); } else { goto_face_mv.init (&goto_face_val, goto_face_val, goto_face_mv.destination() - per_face_change, cfg->options->face_change_steps, move_type); }}void Arrangement::goto_left(void) { if (current_col == 0) current_col = n_columns - 1; // cycle around else current_col--; if (goto_face_mv.at_destination()) { goto_face_mv.init (&goto_face_val, goto_face_val, goto_face_val + per_face_change, cfg->options->face_change_steps, move_type); } else { goto_face_mv.init (&goto_face_val, goto_face_val, goto_face_mv.destination() + per_face_change, cfg->options->face_change_steps, move_type); }}// this function "unrolls" a face to col and row "coords" it does not// check boundsfloat Arrangement::goto_face (int face){ int col = face % n_columns; int row = face / n_columns; return goto_face(col, row);}float Arrangement::goto_face (int col, int row) { desktop_coords_t g; g.column = col; g.row = row; return goto_face(g);}// this goto face assumes a circular arrangement// overload for otherfloat Arrangement::goto_face (desktop_coords_t dest) { if (dest.column < 0 || dest.column >= n_columns || dest.row < 0 || dest.row >= n_rows) { //msgout (DEBUG, "row / col goto out of range (%u x %u)\n", // dest.column, dest.row); return 0; } int newface = dest.column + (dest.row * n_columns); int current = current_col + (current_row * n_columns); int number = n_columns * n_rows; float new_rot; // eeek! figure out the shortest distance to the new face... there // must be a more elegant way! but for now this works... if (newface > current) { if ( (newface - current) < ((current + number) - newface) ) { // normal case new_rot = -per_face_change * (newface - current); } else { // "wrapped" new_rot = per_face_change * ((current + number) - newface); } } else { // newface < current if ( (current - newface) > ((newface + number) - current) ) { // "wrapped" new_rot = -per_face_change * ((newface + number) - current); } else { // normal case new_rot = per_face_change * (current - newface); } } if (goto_face_mv.at_destination()) goto_face_mv.init (&goto_face_val, goto_face_val, goto_face_val + new_rot, cfg->options->face_change_steps, move_type); else goto_face_mv.init (&goto_face_val, goto_face_val, goto_face_mv.destination() + new_rot, cfg->options->face_change_steps, move_type); current_col = dest.column; //newface; current_row = dest.row; return cfg->options->face_change_steps;}int Arrangement::in_goto (void){ return !goto_face_mv.at_destination();}void Arrangement::goto_random_face(void){ int which_one; do { which_one = get_randomi (0, (n_columns * n_rows) - 1); } while (which_one == (current_col + (current_row * n_rows))); goto_face (which_one);}void Arrangement::entry_movement_start(void) { if (!cfg->options->entry_exit_movement) return; z_off_mv.init (&z_offset, z_offset_close, get_distant_z_offset(), cfg->options->zoom_steps, Movement::MOVE_TYPE_SMOOTH);}void Arrangement::exit_movement_start(void) { if (!cfg->options->entry_exit_movement) return; z_off_mv.init(&z_offset, z_offset, z_offset_close, cfg->options->zoom_steps, Movement::MOVE_TYPE_WACK);}void Arrangement::exit_movement_cancel(void){ if (!cfg->options->entry_exit_movement) return; z_off_mv.init (&z_offset, z_offset, get_distant_z_offset(), cfg->options->zoom_steps, Movement::MOVE_TYPE_SMOOTH);}int Arrangement::is_entry_movement_done(void) { return (!cfg->options->entry_exit_movement || z_off_mv.at_destination());}int Arrangement::is_exit_movement_done(void) { return (!cfg->options->entry_exit_movement || z_off_mv.at_destination());}void Arrangement::entry_exit_move(void) { if (!cfg->options->entry_exit_movement) return; z_off_mv.change_a_bit();}void Arrangement::set_transparency (float t){ face_set->set_transparency (t);}void Arrangement::render(){ glCallList(face_list);}void Arrangement::make_display_list(void){ glMatrixMode(GL_MODELVIEW); glNewList(face_list,GL_COMPILE); face_set->render_all(); glEndList();}// ==============================================================// CarouselArrangement// ==============================================================CarouselArrangement::CarouselArrangement(VDesktops &vdesks, float fw, float fh, FaceSet *fs, Config *c) : Arrangement (fs, c){ X_Rot = 0; x_rot_final = 15.0; face_width = fw; face_height = fh; calculate_faces(vdesks); goto_face_mv.disable();}void CarouselArrangement::calculate_faces(VDesktops & vdesks){ vdesks.get_vdesktop_info (¤t_col, ¤t_row, &n_columns, &n_rows); // current_face becomes the unrolled current face current_face = current_col + (current_row * n_columns); // n_faces becomes the total number of desktops n_faces = n_columns * n_rows; side_angle = 360.0 / (float)n_faces; per_face_change = side_angle; goto_face_val = 360 - (side_angle * current_face); float circum = face_width * 1.5 * n_faces; radius = circum / (2.0 * PI); float my_angle = ((FOV / 2.0) * PI) / 180.0; // get_base_z_offset returns radius z_offset_close = z_offset = -(float)((face_height/2.0) / tan(my_angle) + get_base_z_offset()); int i; float half_face_height = face_height / 2.0; float half_face_width = face_width / 2.0; Point tl,tr,bl,br; for (i = 0; i < n_faces; i++) { tl.set (-half_face_width, half_face_height, 0); tr.set ( half_face_width, half_face_height, 0); bl.set (-half_face_width, -half_face_height, 0); br.set ( half_face_width, -half_face_height, 0); translate (tl.v, 0, 0, radius); rotate_y (tl.v, side_angle * i); translate (tr.v, 0, 0, radius); rotate_y (tr.v, side_angle * i); translate (bl.v, 0, 0, radius); rotate_y (bl.v, side_angle * i); translate (br.v, 0, 0, radius); rotate_y (br.v, side_angle * i); //msgout (DEBUG"[%i] = %f, %f, %f\n", i, tl.v[0], tl.v[1], tl.v[2]); // the palindromic serendipity of this rocks! face_set->set_face(i, tl, tr, bl, br);#if 0 msgout(DEBUG, "[%i] X tl=%f, tr=%f, br=%f\n", i, f->topleft.v[0], f->topright.v[0], f->bottomright.v[0]); msgout(DEBUG, "[%i] Y tl=%f, tr=%f, br=%f\n", i, f->topleft.v[1], f->topright.v[1], f->bottomright.v[1]); msgout(DEBUG, "[%i] Z tl=%f, tr=%f, br=%f\n", i, f->topleft.v[2], f->topright.v[2], f->bottomright.v[2]); msgout(DEBUG, "[%i] normal = %f, %f, %f\n\n", i, f->normal.v[0], f->normal.v[1], f->normal.v[2]);#endif } make_display_list();}int CarouselArrangement::get_type () { return FACE_TYPE_CAROUSEL;}#if 0// check bounds on istatic void check(int *i, int max) { if (*i == max + 1) *i = 1; if (*i == 0) *i = max;}void CarouselArrangement::render(){ //for (i = 0; i < n_columns * n_rows; i++) // faces[i]->render(); stack<int> nums; int max = n_columns * n_rows; int c = current_face + 1;; //faces[c-1]->render(); nums.push(c); int l = c - 1; check(&l, max); if (l == c) return; //faces[l-1]->render(); nums.push(l); int r = c + 1; check(&r, max); if (r == l) return; //faces[r-1]->render(); nums.push(r); while (1) { l--; check(&l, max); if (l == r) break; //faces[l-1]->render(); nums.push(l); r++; check(&r, max); if (l == r) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -