2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 //-----------------------------------------------------------------------------
25 // a class to provide basic services for 2D view of a world
26 // window <-> local 2D space transforms
28 // TODO: this one can be placed under an interface, and provided to the editor as a service
32 static void view_ZoomIn(GtkWidget *widget, gpointer data)
34 ((C2DView *) data)->ZoomIn();
37 static void view_ZoomOut(GtkWidget *widget, gpointer data)
39 ((C2DView *) data)->ZoomOut();
42 void C2DView::PreparePaint()
44 g_QglTable.m_pfn_qglClearColor(0, 0, 0, 0);
45 g_QglTable.m_pfn_qglViewport(0, 0, m_rect.right, m_rect.bottom);
46 g_QglTable.m_pfn_qglMatrixMode(GL_PROJECTION);
47 g_QglTable.m_pfn_qglLoadIdentity();
48 g_QglTable.m_pfn_qglOrtho(m_Mins[0], m_Maxs[0], m_Maxs[1], m_Mins[1], -1, 1);
51 void C2DView::SpaceForWindow(float c[2], int x, int y)
53 c[0] = ((float) (x)) / ((float) (m_rect.right - m_rect.left)) * (m_Maxs[0] - m_Mins[0]) + m_Mins[0];
54 c[1] = ((float) (y)) / ((float) (m_rect.bottom - m_rect.top)) * (m_Maxs[1] - m_Mins[1]) + m_Mins[1];
57 void C2DView::GridForWindow(float c[2], int x, int y)
59 SpaceForWindow(c, x, y);
63 c[0] /= m_GridStep[0];
64 c[1] /= m_GridStep[1];
65 c[0] = (float) floor(c[0] + 0.5f);
66 c[1] = (float) floor(c[1] + 0.5f);
67 c[0] *= m_GridStep[0];
68 c[1] *= m_GridStep[1];
71 void C2DView::WindowForSpace(int &x, int &y, const float c[2])
73 x = m_rect.left + (int) (((float) (m_rect.right - m_rect.left)) * (c[0] - m_Mins[0]) / (m_Maxs[0] - m_Mins[0]));
74 y = m_rect.top + (int) (((float) (m_rect.bottom - m_rect.top)) * (c[1] - m_Mins[1]) / (m_Maxs[1] - m_Mins[1]));
77 qboolean C2DView::DoesSelect(int x, int y, float c[2])
80 WindowForSpace(xc, yc, c);
81 if (abs(xc - x) <= 3 && abs(yc - y) <= 3) {
87 void C2DView::ZoomIn()
89 m_Mins[0] = 0.5f * (m_Mins[0] - m_Center[0]) + m_Center[0];
90 m_Mins[1] = 0.5f * (m_Mins[1] - m_Center[1]) + m_Center[1];
91 m_Maxs[0] = 0.5f * (m_Maxs[0] - m_Center[0]) + m_Center[0];
92 m_Maxs[1] = 0.5f * (m_Maxs[1] - m_Center[1]) + m_Center[1];
96 void C2DView::ZoomOut()
98 m_Mins[0] = 2.0f * (m_Mins[0] - m_Center[0]) + m_Center[0];
99 m_Mins[1] = 2.0f * (m_Mins[1] - m_Center[1]) + m_Center[1];
100 m_Maxs[0] = 2.0f * (m_Maxs[0] - m_Center[0]) + m_Center[0];
101 m_Maxs[1] = 2.0f * (m_Maxs[1] - m_Center[1]) + m_Center[1];
102 g_pToolWnd->Redraw();
105 bool C2DView::OnRButtonDown(int x, int y)
107 if (ViewState == View_Idle) {
108 m_xPosMove = x; // horizontal position of cursor
109 m_yPosMove = y; // vertical position of cursor
111 m_MinsMove[0] = m_Mins[0];
112 m_MinsMove[1] = m_Mins[1];
113 m_MaxsMove[0] = m_Maxs[0];
114 m_MaxsMove[1] = m_Maxs[1];
115 ViewState = View_Move;
123 bool C2DView::OnRButtonUp(int x, int y)
125 if (ViewState == View_Move) {
126 // maybe it's time for popup menu
128 GtkWidget *menu, *item;
132 item = ui::MenuItem("Validate (RETURN)");
133 item.connect("activate", G_CALLBACK(Textool_Validate), NULL);
135 gtk_menu_append(GTK_MENU(menu), item);
137 item = ui::MenuItem("Zoom in (INSERT)");
138 item.connect("activate", G_CALLBACK(view_ZoomIn), this);
140 gtk_menu_append(GTK_MENU(menu), item);
142 item = ui::MenuItem("Zoom out (DELETE)");
143 item.connect("activate", G_CALLBACK(view_ZoomOut), this);
145 gtk_menu_append(GTK_MENU(menu), item);
147 item = ui::MenuItem("Cancel (ESC)");
148 item.connect("activate", G_CALLBACK(Textool_Cancel), NULL);
150 gtk_menu_append(GTK_MENU(menu), item);
152 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 1, GDK_CURRENT_TIME);
156 ViewState = View_Idle;
162 bool C2DView::OnMouseMove(int xPos, int yPos)
164 if (ViewState == View_Move) {
167 V[0] = ((float) (xPos - m_xPosMove)) * (m_MaxsMove[0] - m_MinsMove[0]) / ((float) (m_rect.left - m_rect.right));
168 V[1] = ((float) (yPos - m_yPosMove)) * (m_MaxsMove[1] - m_MinsMove[1]) / ((float) (m_rect.top - m_rect.bottom));
169 // update m_Mins m_Maxs and m_Center
170 m_Mins[0] = m_MinsMove[0] + V[0];
171 m_Mins[1] = m_MinsMove[1] + V[1];
172 m_Maxs[0] = m_MaxsMove[0] + V[0];
173 m_Maxs[1] = m_MaxsMove[1] + V[1];
174 m_Center[0] = 0.5f * (m_Mins[0] + m_Maxs[0]);
175 m_Center[1] = 0.5f * (m_Mins[1] + m_Maxs[1]);
176 // no popup menu if we moved
178 // send a repaint message
179 g_pToolWnd->Redraw();
185 bool C2DView::OnKeyDown(char *s)
187 if (ViewState == View_Idle) {
188 if (!strcmp(s, "Insert")) {
192 if (!strcmp(s, "Delete")) {