]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - plugins/textool/2DView.cpp
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / plugins / textool / 2DView.cpp
1 /*\r
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \r
7 GtkRadiant is free software; you can redistribute it and/or modify\r
8 it under the terms of the GNU General Public License as published by\r
9 the Free Software Foundation; either version 2 of the License, or\r
10 (at your option) any later version.\r
11 \r
12 GtkRadiant is distributed in the hope that it will be useful,\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 GNU General Public License for more details.\r
16 \r
17 You should have received a copy of the GNU General Public License\r
18 along with GtkRadiant; if not, write to the Free Software\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
20 */\r
21 \r
22 //-----------------------------------------------------------------------------\r
23 //\r
24 // DESCRIPTION:\r
25 // a class to provide basic services for 2D view of a world\r
26 // window <-> local 2D space transforms\r
27 // snap to grid\r
28 // TODO: this one can be placed under an interface, and provided to the editor as a service\r
29 \r
30 #include "StdAfx.h"\r
31 \r
32 static void view_ZoomIn (GtkWidget* widget, gpointer data)\r
33 {\r
34   ((C2DView*)data)->ZoomIn ();\r
35 }\r
36 \r
37 static void view_ZoomOut (GtkWidget* widget, gpointer data)\r
38 {\r
39   ((C2DView*)data)->ZoomOut ();\r
40 }\r
41 \r
42 void C2DView::PreparePaint()\r
43 {\r
44   g_QglTable.m_pfn_qglClearColor( 0, 0, 0, 0 );\r
45   g_QglTable.m_pfn_qglViewport( 0, 0, m_rect.right, m_rect.bottom );\r
46   g_QglTable.m_pfn_qglMatrixMode( GL_PROJECTION );\r
47   g_QglTable.m_pfn_qglLoadIdentity();\r
48   g_QglTable.m_pfn_qglOrtho( m_Mins[0], m_Maxs[0], m_Maxs[1], m_Mins[1], -1, 1 );       \r
49 }\r
50 \r
51 void C2DView::SpaceForWindow( float c[2], int x, int y)\r
52 {\r
53   c[0] = ((float)(x))/((float)(m_rect.right-m_rect.left))*(m_Maxs[0]-m_Mins[0])+m_Mins[0];\r
54   c[1] = ((float)(y))/((float)(m_rect.bottom-m_rect.top))*(m_Maxs[1]-m_Mins[1])+m_Mins[1];\r
55 }\r
56 \r
57 void C2DView::GridForWindow( float c[2], int x, int y)\r
58 {\r
59   SpaceForWindow( c, x, y );\r
60   if ( !m_bDoGrid )\r
61     return;\r
62   c[0] /= m_GridStep[0];\r
63   c[1] /= m_GridStep[1];\r
64   c[0] = (float)floor( c[0] + 0.5f );\r
65   c[1] = (float)floor( c[1] + 0.5f );\r
66   c[0] *= m_GridStep[0];\r
67   c[1] *= m_GridStep[1];\r
68 }\r
69 \r
70 void C2DView::WindowForSpace( int &x, int &y, const float c[2] )\r
71 {\r
72   x = m_rect.left + (int)( ((float)(m_rect.right-m_rect.left))*(c[0]-m_Mins[0])/(m_Maxs[0]-m_Mins[0]) );\r
73   y = m_rect.top + (int)( ((float)(m_rect.bottom-m_rect.top))*(c[1]-m_Mins[1])/(m_Maxs[1]-m_Mins[1]) );\r
74 }\r
75 \r
76 qboolean C2DView::DoesSelect( int x, int y, float c[2] )\r
77 {\r
78   int xc,yc;\r
79   WindowForSpace( xc, yc, c );\r
80   if ( abs(xc-x)<=3 && abs(yc-y)<=3 )\r
81     return true;\r
82   return false;\r
83 }\r
84 \r
85 void C2DView::ZoomIn()\r
86 {\r
87   m_Mins[0] = 0.5f * ( m_Mins[0] - m_Center[0] ) + m_Center[0];\r
88   m_Mins[1] = 0.5f * ( m_Mins[1] - m_Center[1] ) + m_Center[1];\r
89   m_Maxs[0] = 0.5f * ( m_Maxs[0] - m_Center[0] ) + m_Center[0];\r
90   m_Maxs[1] = 0.5f * ( m_Maxs[1] - m_Center[1] ) + m_Center[1];\r
91   g_pToolWnd->Redraw ();\r
92 }\r
93 \r
94 void C2DView::ZoomOut()\r
95 {\r
96   m_Mins[0] = 2.0f * ( m_Mins[0] - m_Center[0] ) + m_Center[0];\r
97   m_Mins[1] = 2.0f * ( m_Mins[1] - m_Center[1] ) + m_Center[1];\r
98   m_Maxs[0] = 2.0f * ( m_Maxs[0] - m_Center[0] ) + m_Center[0];\r
99   m_Maxs[1] = 2.0f * ( m_Maxs[1] - m_Center[1] ) + m_Center[1];\r
100   g_pToolWnd->Redraw ();\r
101 }\r
102 \r
103 bool C2DView::OnRButtonDown (int x, int y)\r
104 {\r
105   if (ViewState == View_Idle)\r
106   {\r
107     m_xPosMove = x; // horizontal position of cursor\r
108     m_yPosMove = y; // vertical position of cursor\r
109     // store\r
110     m_MinsMove[0] = m_Mins[0]; m_MinsMove[1] = m_Mins[1];\r
111     m_MaxsMove[0] = m_Maxs[0]; m_MaxsMove[1] = m_Maxs[1];\r
112     ViewState = View_Move;\r
113     // set popup to true\r
114     m_bPopup = true;\r
115     return true;\r
116   }\r
117   return false;\r
118 }\r
119 \r
120 bool C2DView::OnRButtonUp (int x, int y)\r
121 {\r
122   if (ViewState == View_Move)\r
123   {\r
124     // maybe it's time for popup menu\r
125     if (m_bPopup)\r
126     {\r
127       GtkWidget *menu, *item;\r
128 \r
129       menu = gtk_menu_new ();\r
130 \r
131       item = gtk_menu_item_new_with_label ("Validate (RETURN)");\r
132       gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (Textool_Validate), NULL);\r
133       gtk_widget_show (item);\r
134       gtk_menu_append (GTK_MENU (menu), item);\r
135 \r
136       item = gtk_menu_item_new_with_label ("Zoom in (INSERT)");\r
137       gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (view_ZoomIn), this);\r
138       gtk_widget_show (item);\r
139       gtk_menu_append (GTK_MENU (menu), item);\r
140 \r
141       item = gtk_menu_item_new_with_label ("Zoom out (DELETE)");\r
142       gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (view_ZoomOut), this);\r
143       gtk_widget_show (item);\r
144       gtk_menu_append (GTK_MENU (menu), item);\r
145 \r
146       item = gtk_menu_item_new_with_label ("Cancel (ESC)");\r
147       gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (Textool_Cancel), NULL);\r
148       gtk_widget_show (item);\r
149       gtk_menu_append (GTK_MENU (menu), item);\r
150 \r
151       gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 1, GDK_CURRENT_TIME);\r
152     }\r
153 \r
154     // back to Idle mode\r
155     ViewState = View_Idle;\r
156     return true;\r
157   }\r
158   return false;\r
159 }\r
160 \r
161 bool C2DView::OnMouseMove (int xPos, int yPos)\r
162 {\r
163   if (ViewState == View_Move)\r
164   {\r
165     float V[2];\r
166     // V is the offset\r
167     V[0] = ((float)( xPos - m_xPosMove )) * ( m_MaxsMove[0] - m_MinsMove[0] ) / ((float)( m_rect.left - m_rect.right ));\r
168     V[1] = ((float)( yPos - m_yPosMove )) * ( m_MaxsMove[1] - m_MinsMove[1] ) / ((float)( m_rect.top - m_rect.bottom ));\r
169     // update m_Mins m_Maxs and m_Center\r
170     m_Mins[0] = m_MinsMove[0] + V[0];\r
171     m_Mins[1] = m_MinsMove[1] + V[1];\r
172     m_Maxs[0] = m_MaxsMove[0] + V[0];\r
173     m_Maxs[1] = m_MaxsMove[1] + V[1];\r
174     m_Center[0] = 0.5f * ( m_Mins[0] + m_Maxs[0] );\r
175     m_Center[1] = 0.5f * ( m_Mins[1] + m_Maxs[1] );\r
176     // no popup menu if we moved\r
177     m_bPopup = false;\r
178     // send a repaint message\r
179     g_pToolWnd->Redraw ();\r
180     return true;\r
181   }\r
182   return false;\r
183 }\r
184 \r
185 bool C2DView::OnKeyDown (char *s)\r
186 {\r
187   if (ViewState == View_Idle)\r
188   {\r
189     if (!strcmp(s,"Insert"))\r
190     {\r
191       ZoomOut();\r
192       return true;\r
193     }\r
194     if (!strcmp(s,"Delete"))\r
195     {\r
196       ZoomIn();\r
197       return true;\r
198     }\r
199   }\r
200   return false;\r
201 }\r
202 \r