~ubuntu-branches/ubuntu/wily/ginkgocadx/wily-proposed

« back to all changes in this revision

Viewing changes to src/cadxcore/widgets/wregla.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Tille
  • Date: 2011-05-02 08:09:26 UTC
  • Revision ID: james.westby@ubuntu.com-20110502080926-bql5wep49c7hg91t
Tags: upstream-2.4.1.1
Import upstream version 2.4.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  
 
3
 *  $Id: wregla.cpp 3748 2011-04-20 10:38:38Z carlos $
 
4
 *  Ginkgo CADx Project
 
5
 *
 
6
 *  Copyright 2008-10 MetaEmotion S.L. All rights reserved.
 
7
 *  http://ginkgo-cadx.com
 
8
 *
 
9
 *  This file is licensed under LGPL v3 license.
 
10
 *  See License.txt for details
 
11
 *
 
12
 *
 
13
 */
 
14
//#define _GINKGO_TRACE
 
15
#include <wx/xml/xml.h>
 
16
#include <api/globals.h>
 
17
#include <api/icontexto.h>
 
18
#include <api/iwidgetsrenderer.h>
 
19
#include <api/iwidgetsmanager.h>
 
20
#include <api/westilo.h>
 
21
 
 
22
#include <widgets/gui/calibracion.h>
 
23
#include <wx/menu.h>
 
24
#include <wx/xml/xml.h>
 
25
#include "wregla.h"
 
26
 
 
27
#include <main/managers/widgetsmanager.h>
 
28
#include <vtkgl.h>
 
29
#include <cmath>
 
30
#include <sstream>
 
31
#include <cairo/cairo.h>
 
32
#include "openglhelper.h"
 
33
#include <eventos/eventosginkgo.h>
 
34
#include <resources/ginkgoresourcemanager.h>
 
35
#include <api/internacionalizacion.h>
 
36
#include <api/math/geometria3d.h>
 
37
 
 
38
//region "Implementacion de WReglaBuilder"
 
39
 
 
40
GNC::GCS::Widgets::WReglaBuilder::WReglaBuilder(GNC::GCS::IWidgetsManager* pManager) : GNC::GCS::Widgets::IWidgetBuilder(pManager)
 
41
{
 
42
        m_MouseDown = false;
 
43
        m_pReglaTemp = NULL;
 
44
 
 
45
        GNC::GCS::Eventos::EventoModificacionImagen evt1(m_pManager->GetVista());
 
46
}
 
47
 
 
48
GNC::GCS::Widgets::WReglaBuilder::~WReglaBuilder()
 
49
{
 
50
        if (m_pReglaTemp != NULL) {
 
51
                delete m_pReglaTemp;
 
52
                m_pReglaTemp = NULL;
 
53
        }
 
54
}
 
55
 
 
56
void GNC::GCS::Widgets::WReglaBuilder::OnMouseEvents(GNC::GCS::Eventos::EventoRaton& evento)
 
57
{
 
58
        if (!m_pManager) {
 
59
                return;
 
60
        }
 
61
        GTRACE("GNC::GCS::Widgets::WReglaBuilder::OnMouseEvents(wxMouseEvent&)");
 
62
        if (m_MouseDown && evento.ButtonUp(GNC::GCS::Eventos::EventoRaton::EB_IZQUIERDO)) {
 
63
                m_MouseDown = false;
 
64
                if (m_pReglaTemp != NULL) {
 
65
                        m_pReglaTemp->m_Vertices[1] = evento.iP;;
 
66
                        m_pReglaTemp->Recalcular(evento.c->GetRenderer());
 
67
                        //como mínimo 2 pixels imagen
 
68
                        if (std::abs(m_pReglaTemp->Distancia()) > GNC::GCS::Vector::EpsilonDeReales() ) {
 
69
                                m_pManager->InsertarWidget(m_pReglaTemp);
 
70
                                m_pManager->LanzarEventoCreacion(m_pReglaTemp);
 
71
                        }
 
72
                        else {
 
73
                                delete m_pReglaTemp;
 
74
                        }
 
75
                        m_pReglaTemp = NULL;
 
76
                        m_pManager->Modificado();
 
77
                }
 
78
                ConsumirEvento();
 
79
 
 
80
        } else if (evento.ButtonDown(GNC::GCS::Eventos::EventoRaton::EB_IZQUIERDO)) {
 
81
 
 
82
                m_MouseDown = true;
 
83
                TNodo nodos[2];
 
84
                nodos[0] = nodos[1] = evento.iP;
 
85
                if (m_pReglaTemp != NULL) {
 
86
                        delete m_pReglaTemp;
 
87
                }
 
88
                m_pReglaTemp = new GNC::GCS::Widgets::WRegla(m_pManager, evento.c->GetRenderer()->GetVID(), nodos, "Regla");
 
89
                //std::cout << "linea (leftdwn): " << m_Vertices[0].m_wX << ", " << m_Vertices[0].m_wY << " -> " << m_Vertices[1].m_wX << ", " << m_Vertices[1].m_wY << std::endl;
 
90
                m_pManager->Modificado();
 
91
                ConsumirEvento();
 
92
        } else if (evento.Dragging() && m_MouseDown) {
 
93
                if (m_pReglaTemp != NULL) {
 
94
                        m_pReglaTemp->m_Vertices[1] = evento.iP;
 
95
                        m_pReglaTemp->Recalcular(evento.c->GetRenderer());
 
96
                        //std::cout << "linea (moving): " << m_Vertices[0].m_wX << ", " << m_Vertices[0].m_wY << " -> " << m_Vertices[1].m_wX << ", " << m_Vertices[1].m_wY << std::endl;
 
97
                        m_pManager->Modificado();
 
98
                }
 
99
                ConsumirEvento();
 
100
        }
 
101
 
 
102
}
 
103
 
 
104
void GNC::GCS::Widgets::WReglaBuilder::OnKeyEvents(GNC::GCS::Eventos::EventoTeclado&)
 
105
{
 
106
        GTRACE("GNC::GCS::Widgets::WReglaBuilder::OnKeyEvents(wxKeyEvent&)");
 
107
}
 
108
 
 
109
void GNC::GCS::Widgets::WReglaBuilder::Render(GNC::GCS::Contexto3D* c)
 
110
{
 
111
        if (m_pReglaTemp == NULL) {
 
112
                return;
 
113
        }
 
114
        m_pReglaTemp->Render(c);
 
115
}
 
116
 
 
117
GNC::GCS::Widgets::TipoCursor GNC::GCS::Widgets::WReglaBuilder::GetCursor()
 
118
{
 
119
        return GNC::GCS::Widgets::CUR_CREAR_LINEA;
 
120
}
 
121
 
 
122
//region Interfaz de eventos ginkgo
 
123
 
 
124
 
 
125
 
 
126
//endregion
 
127
 
 
128
 
 
129
//endregion
 
130
 
 
131
 
 
132
//region "Constructor y destructor"
 
133
 
 
134
GNC::GCS::Widgets::WRegla::WRegla(IWidgetsManager* pManager, long vid, GNC::GCS::Nodo nodos[2], const char* nombre) : GNC::GCS::Widgets::IWidget(pManager, vid, nombre), GNC::GCS::Widgets::IWidgetSerializable()
 
135
{
 
136
        m_Vertices[0] = nodos[0];
 
137
        m_Vertices[1] = nodos[1];
 
138
 
 
139
        m_MouseDown = false;
 
140
        m_ReservaRecursos = true;
 
141
        m_Oculto = false;
 
142
 
 
143
        GNC::GCS::Eventos::EventoModificacionImagen evt1(m_pManager->GetVista());
 
144
        m_pManager->GetControladorEventos()->Registrar(this, evt1);
 
145
}
 
146
 
 
147
GNC::GCS::Widgets::WRegla::~WRegla()
 
148
{
 
149
        LanzarEventoDestruccion();
 
150
}
 
151
 
 
152
//endregion
 
153
 
 
154
//region "Serializado y desserializado"
 
155
GNC::GCS::Widgets::WRegla::WRegla(IWidgetsManager* pManager, long vid, wxXmlNode* nodo): GNC::GCS::Widgets::IWidget(pManager, vid, "Regla"), GNC::GCS::Widgets::IWidgetSerializable(nodo)
 
156
{
 
157
        if(nodo->GetName() != wxT("rule_widget")){
 
158
                std::cerr<< "Ha ocurrido un error al desserializar el widget regla"<<std::endl;
 
159
        }
 
160
 
 
161
        wxXmlNode *child = nodo->GetChildren();
 
162
        while (child) {
 
163
                if(child->GetName() == wxT("node0")){
 
164
                        m_Vertices[0] = GNC::GCS::Nodo::Deserializar(child);
 
165
                } else if(child->GetName() == wxT("node1")){
 
166
                        m_Vertices[1] = GNC::GCS::Nodo::Deserializar(child);
 
167
                }
 
168
                child = child->GetNext();
 
169
        }
 
170
 
 
171
        m_MouseDown = false;
 
172
        m_ReservaRecursos = true;
 
173
 
 
174
        GNC::GCS::Eventos::EventoModificacionImagen evt1(m_pManager->GetVista());
 
175
        m_pManager->GetControladorEventos()->Registrar(this, evt1);
 
176
}
 
177
 
 
178
wxXmlNode* GNC::GCS::Widgets::WRegla::Serializar(const std::string& nombreMedico)
 
179
{
 
180
        wxXmlNode* resultado = new wxXmlNode(NULL,wxXML_ELEMENT_NODE,wxT("rule_widget"));
 
181
        //almacenamos los dos nodos
 
182
        wxXmlNode* nodo = m_Vertices[0].Serializar();
 
183
        nodo->SetName(wxT("node0"));
 
184
        resultado->AddChild(nodo);
 
185
        nodo = m_Vertices[1].Serializar();
 
186
        nodo->SetName(wxT("node1"));
 
187
        resultado->AddChild(nodo);
 
188
        //metadatos
 
189
        SerializarMetadatos(resultado,nombreMedico);
 
190
        return resultado;
 
191
}
 
192
 
 
193
//endregion
 
194
 
 
195
void GNC::GCS::Widgets::WRegla::OnMouseEvents(GNC::GCS::Eventos::EventoRaton& evento)
 
196
{
 
197
        if(EstaOculto()){
 
198
                return;
 
199
        }
 
200
        //------------------------------------------------------
 
201
        // Leaving
 
202
        if (evento.Leaving() ) {
 
203
                Iluminar(false);
 
204
        }
 
205
        //------------------------------------------------------
 
206
        // Entering
 
207
        else if (evento.Entering() ) {
 
208
                if (m_MouseDown) {
 
209
                        Iluminar(true);
 
210
                }
 
211
        }
 
212
        //------------------------------------------------------
 
213
        // Dragging
 
214
        else if (evento.Dragging() && m_MouseDown) {
 
215
                if (EstaSeleccionado() || m_Vertices[0].EstaSeleccionado() || m_Vertices[1].EstaSeleccionado()) {
 
216
                        Vector delta = evento.iP - m_PosCursor;
 
217
                        m_PosCursor = evento.iP;
 
218
                        if (EstaSeleccionado() || m_Vertices[0].EstaSeleccionado()) {
 
219
                                m_Vertices[0] += delta;
 
220
                        }
 
221
                        if (EstaSeleccionado() || m_Vertices[1].EstaSeleccionado()) {
 
222
                                m_Vertices[1] += delta;
 
223
                        }
 
224
                        LanzarEventoModificacion();
 
225
                        Recalcular(evento.c->GetRenderer());
 
226
                        ConsumirEvento();
 
227
                }
 
228
        }
 
229
        //------------------------------------------------------
 
230
        // LeftDown
 
231
        else if (evento.LeftDown()) {
 
232
 
 
233
                if (EventoConsumido() && !evento.m_controlDown) {
 
234
                        SeleccionarNodo(m_Vertices[0], false);
 
235
                        SeleccionarNodo(m_Vertices[1], false);
 
236
                        Seleccionar(false);
 
237
                        return;
 
238
                }
 
239
 
 
240
                bool dentro = false;
 
241
 
 
242
 
 
243
                m_StartPointMov = evento.iP;
 
244
 
 
245
                const GNC::GCS::Vector::TComponente& factor = evento.c->RelacionImagenPantalla().NormaInfinito();
 
246
 
 
247
                if (m_Vertices[0].Hits(evento.iP.x, evento.iP.y, factor)) { // click sobre el nodo
 
248
                        SeleccionarNodo(m_Vertices[0], true);
 
249
                        SeleccionarNodo(m_Vertices[1], false);
 
250
                        Seleccionar(false);
 
251
 
 
252
                        dentro = true;
 
253
                }
 
254
                else { // Click fuera del nodo
 
255
                        SeleccionarNodo(m_Vertices[0], false);
 
256
                }
 
257
                if (!dentro && m_Vertices[1].Hits(evento.iP.x, evento.iP.y, factor)) { // click sobre el nodo
 
258
                        SeleccionarNodo(m_Vertices[0], false);
 
259
                        SeleccionarNodo(m_Vertices[1], true);
 
260
                        Seleccionar(false);
 
261
 
 
262
                        dentro = true;
 
263
                }
 
264
                else { // Click fuera del nodo
 
265
                        SeleccionarNodo(m_Vertices[1], false);
 
266
                }
 
267
 
 
268
                if (!dentro && HitTest(evento.iP.x, evento.iP.y, factor ) ) { // click sobre la recta
 
269
                        if (evento.m_controlDown) { // Inversion de seleccion
 
270
                                InvertirSeleccion();
 
271
                        }
 
272
                        else{
 
273
                                Seleccionar(true);
 
274
                        }
 
275
 
 
276
                        dentro = true;
 
277
                }
 
278
                else { // Click fuera del nodo
 
279
                        if (!evento.m_controlDown) {
 
280
                                Seleccionar(false);
 
281
                        }
 
282
                        else {
 
283
                                ConsumirEvento();
 
284
                                if (EstaSeleccionado()) {
 
285
                                        m_MouseDown = true;
 
286
                                        m_PosCursor = evento.iP;
 
287
                                        m_CentroAntiguo = m_Centro;
 
288
                                }
 
289
                        }
 
290
                }
 
291
 
 
292
                if (dentro) {
 
293
                        m_MouseDown = true;
 
294
                        m_PosCursor = evento.iP;
 
295
                        m_CentroAntiguo = m_Centro;
 
296
                        ConsumirEvento();
 
297
                }
 
298
                return;
 
299
        }
 
300
        //------------------------------------------------------
 
301
        // LeftUP
 
302
        else if (evento.LeftUp()) {
 
303
                if (m_MouseDown) {
 
304
                        ActualizarTimestampModificacion();
 
305
                        m_MouseDown = false;
 
306
                        ConsumirEvento();
 
307
                }
 
308
        }
 
309
        //------------------------------------------------------
 
310
        // Moving
 
311
        else if (evento.Moving()) {
 
312
 
 
313
                if (EventoConsumido()) {
 
314
                        IluminarNodo(m_Vertices[0], false);
 
315
                        IluminarNodo(m_Vertices[1], false);
 
316
                        Iluminar(false);
 
317
                        return;
 
318
                }
 
319
                bool dentro = false;
 
320
 
 
321
                m_PosCursor = evento.iP;
 
322
 
 
323
                const GNC::GCS::Vector::TComponente& factor = evento.c->RelacionImagenPantalla().NormaInfinito();
 
324
 
 
325
                if (m_Vertices[0].Hits(evento.iP.x, evento.iP.y, factor)) {
 
326
 
 
327
                        IluminarNodo(m_Vertices[0], true);
 
328
                        IluminarNodo(m_Vertices[1], false);
 
329
                        Iluminar(false);
 
330
 
 
331
                        dentro = true;
 
332
                }
 
333
                else {
 
334
                        IluminarNodo(m_Vertices[0], false);
 
335
                }
 
336
 
 
337
                if (m_Vertices[1].Hits(evento.iP.x, evento.iP.y, factor)) {
 
338
 
 
339
                        IluminarNodo(m_Vertices[0], false);
 
340
                        IluminarNodo(m_Vertices[1], true);
 
341
                        Iluminar(false);
 
342
 
 
343
                        dentro = true;
 
344
                }
 
345
                else {
 
346
                        IluminarNodo(m_Vertices[1], false);
 
347
                }
 
348
 
 
349
                if (!dentro && HitTest(evento.iP.x, evento.iP.y, factor) ) {
 
350
                        Iluminar(true);
 
351
                        dentro = true;
 
352
                }
 
353
                else {
 
354
                        Iluminar(false);
 
355
                }
 
356
 
 
357
                if (dentro) {
 
358
                        ConsumirEvento();
 
359
                }
 
360
                return;
 
361
        }
 
362
}
 
363
 
 
364
void GNC::GCS::Widgets::WRegla::OnKeyEvents(GNC::GCS::Eventos::EventoTeclado& evento)
 
365
{
 
366
        if (evento.GetKeyCode() == WXK_ESCAPE) {
 
367
                Seleccionar(false);
 
368
        }
 
369
}
 
370
 
 
371
bool GNC::GCS::Widgets::WRegla::HitTest(float x, float y, float umbral)
 
372
{
 
373
        TVector pos(x, y);
 
374
        if ( m_Vertices[0].DistanciaEuclideaCuadrado(m_Vertices[1]) / 4.0f > pos.DistanciaEuclideaCuadrado(m_Vertices[0].PuntoMedio(m_Vertices[1]))) {
 
375
                const GNC::GCS::Vector::TReales umbralCuadrado = (GNC::GCS::Vector::TReales) umbral * (GNC::GCS::Vector::TReales) umbral * (GNC::GCS::Vector::TReales) m_Vertices[0].m_Size * (GNC::GCS::Vector::TReales) m_Vertices[0].m_Size;
 
376
                if ( pos.DistanciaARectaCuadrado(m_Vertices[0], m_Vertices[1]) < umbralCuadrado ) {
 
377
                        return true;
 
378
                }
 
379
        }
 
380
        return false;
 
381
}
 
382
 
 
383
bool GNC::GCS::Widgets::WRegla::HitTest(GNC::GCS::Vector* vertices, int numVertices)
 
384
{
 
385
        return m_Vertices[0].DentroDePoligono2(vertices, numVertices) && m_Vertices[1].DentroDePoligono2(vertices, numVertices);
 
386
}
 
387
 
 
388
void GNC::GCS::Widgets::WRegla::Render(GNC::GCS::Contexto3D* c)
 
389
{
 
390
        if(m_Oculto){
 
391
                return;
 
392
        }
 
393
 
 
394
        const GNC::GCS::Vector& escala = c->RelacionImagenPantalla();
 
395
 
 
396
        glLineWidth(WIDGET_GROSOR_LINEA);
 
397
 
 
398
        // Highlights sobre nodos activos
 
399
        if (m_Vertices[0].m_Iluminado) {
 
400
                wDibujarElipseDegradado(m_Vertices[0], wRadioPuntoIluminado * escala, wColorPuntoIluminadoInterior, wColorPuntoIluminadoExterior);
 
401
        }
 
402
 
 
403
        if (m_Vertices[1].m_Iluminado) {
 
404
                wDibujarElipseDegradado(m_Vertices[1], wRadioPuntoIluminado * escala, wColorPuntoIluminadoInterior, wColorPuntoIluminadoExterior);
 
405
        }
 
406
 
 
407
        float fsombrax, fsombray;
 
408
        if (m_Seleccionado && m_MouseDown)
 
409
        {
 
410
                fsombrax = WIDGET_OFFSET_X_SOMBRA_SELECCIONADO * escala.x;
 
411
                fsombray = WIDGET_OFFSET_Y_SOMBRA_SELECCIONADO * escala.y;
 
412
        }
 
413
        else
 
414
        {
 
415
                fsombrax = WIDGET_OFFSET_X_SOMBRA * escala.x;
 
416
                fsombray = WIDGET_OFFSET_Y_SOMBRA * escala.y;
 
417
        }
 
418
 
 
419
        //------------------------------------------------------------------------------------------
 
420
        // Sombra de la regla
 
421
        wColorSombra.Aplicar();
 
422
        glBegin(GL_LINES);
 
423
                glVertex2d(m_Vertices[0].x + fsombrax, m_Vertices[0].y - fsombray);
 
424
                glVertex2d(m_Vertices[1].x + fsombrax, m_Vertices[1].y - fsombray);
 
425
        glEnd();
 
426
 
 
427
        // Dibujado de la regla
 
428
        wAplicarColor(m_Iluminado, m_MouseDown, m_Seleccionado);
 
429
        glBegin(GL_LINES);
 
430
                glVertex2d(m_Vertices[0].x, m_Vertices[0].y);
 
431
                glVertex2d(m_Vertices[1].x, m_Vertices[1].y);
 
432
        glEnd();
 
433
 
 
434
 
 
435
        TVector diff = m_Vertices[1] - m_Vertices[0];
 
436
 
 
437
        TVector puntoMedio = m_Vertices[0].PuntoMedio(m_Vertices[1]);
 
438
        TVector ortogonal = (diff).VectorOrtonormal() * escala * 6.0f;
 
439
 
 
440
        if (m_MouseDown && m_Seleccionado)
 
441
                ortogonal *= WIDGET_INCREMENTO_DETALLE_SELECCIONADO;
 
442
 
 
443
 
 
444
 
 
445
        TVector f00 = m_Vertices[0] + ortogonal;
 
446
        TVector f01 = m_Vertices[0] - ortogonal;
 
447
        TVector f10 = puntoMedio + ortogonal;
 
448
        TVector f20 = m_Vertices[1] + ortogonal;
 
449
        TVector f21 = m_Vertices[1] - ortogonal;
 
450
 
 
451
        //------------------------------------------------------------------------------------------
 
452
        // Dibujado de las marcas de la regla.
 
453
        //-- Sombras
 
454
        wColorSombra.Aplicar();
 
455
        glBegin(GL_LINES);
 
456
                glVertex2d(f00.x + fsombrax, f00.y - fsombray);
 
457
                glVertex2d(f01.x + fsombrax, f01.y - fsombray);
 
458
        glEnd();
 
459
 
 
460
        glBegin(GL_LINES);
 
461
                glVertex2d(f10.x + fsombrax, f10.y - fsombray);
 
462
                glVertex2d(puntoMedio.x + fsombrax, puntoMedio.y - fsombray);
 
463
        glEnd();
 
464
 
 
465
        glBegin(GL_LINES);
 
466
                glVertex2d(f20.x + fsombrax, f20.y - fsombray);
 
467
                glVertex2d(f21.x + fsombrax, f21.y - fsombray);
 
468
        glEnd();
 
469
 
 
470
        // Marca derecha
 
471
        glBegin(GL_LINES);
 
472
                glVertex2d(f20.x + fsombrax, f20.y - fsombray);
 
473
                glVertex2d(f21.x + fsombrax, f21.y - fsombray);
 
474
        glEnd();
 
475
 
 
476
        //-- Marca izquierda
 
477
        wAplicarColor(m_Iluminado || m_Vertices[0].m_Iluminado, m_MouseDown, m_Seleccionado);
 
478
        glBegin(GL_LINES);
 
479
                glVertex2d(f00.x, f00.y);
 
480
                glVertex2d(f01.x, f01.y);
 
481
        glEnd();
 
482
 
 
483
        //-- Marca central
 
484
        wAplicarColor(m_Iluminado, m_MouseDown, m_Seleccionado);
 
485
        glBegin(GL_LINES);
 
486
                glVertex2d(f10.x, f10.y);
 
487
                glVertex2d(puntoMedio.x, puntoMedio.y);
 
488
        glEnd();
 
489
 
 
490
        // Marca derecha
 
491
        wAplicarColor(m_Iluminado || m_Vertices[1].m_Iluminado, m_MouseDown, m_Seleccionado);
 
492
        glBegin(GL_LINES);
 
493
                glVertex2d(f20.x, f20.y);
 
494
                glVertex2d(f21.x, f21.y);
 
495
        glEnd();
 
496
 
 
497
        //------------------------------------------------------------------------------------------
 
498
        // Dibujado del texto de la medida
 
499
        TexturaRegla* tr = GetTextura(c->GetRenderer());
 
500
        if(tr->texto != m_Texto) {
 
501
                Recalcular(c->GetRenderer());
 
502
        }
 
503
        GNC::GCS::TexturaCairo* tc = tr->m_textura;
 
504
 
 
505
        if (!tc->contextoCreado) {
 
506
                //std::cerr << "Error: Contexto no creado" << std::endl;
 
507
                return;
 
508
        }
 
509
        if (!tc->texturaCargada) {
 
510
                tc->Cargar();
 
511
        }
 
512
        if (tc->texturaModificada) {
 
513
 
 
514
                tc->Actualizar();
 
515
        }
 
516
        //std::cout << "Dibujando..." << std::endl;
 
517
 
 
518
        GNC::GCS::Vector quad[4];
 
519
 
 
520
        // Dibujado del texto.
 
521
 
 
522
        // Alineamiento
 
523
        GNC::GCS::Vector alineacion = GNC::GCS::Vector(-m_TamTexto.x / 2.0f, -(m_TamTexto.y + 4.0f)) * escala;
 
524
        /*
 
525
         * Posicion del Quad
 
526
         *  q3   q2
 
527
         *  q0   q1
 
528
         * */
 
529
        /*
 
530
        quad[0].Asignar(0.0f, 0.0f);
 
531
        quad[2] = GNC::GCS::Vector(tc->ancho, tc->alto)*escala;
 
532
        quad[1].Asignar(quad[2].x, quad[0].y);
 
533
        quad[3].Asignar(quad[0].x, quad[2].y);
 
534
 
 
535
        quad[0] +=  puntoMedio + alineacion;
 
536
        quad[1] +=  puntoMedio + alineacion;
 
537
        quad[2] +=  puntoMedio + alineacion;
 
538
        quad[3] +=  puntoMedio + alineacion;
 
539
 
 
540
        AjustarAPixelsPantalla(c, quad, 4);
 
541
 
 
542
        tc->Render(quad);
 
543
        */
 
544
 
 
545
        TMatriz matrizRotacion = TMatriz::MatrizRotacion(c->rotacion);
 
546
 
 
547
        quad[0] = puntoMedio + ( matrizRotacion.ProductoMatricial( alineacion + TVector( 0.0f,     0.0f  ) * escala) );
 
548
        quad[1] = puntoMedio + ( matrizRotacion.ProductoMatricial( alineacion + TVector( tc->ancho, 0.0f  ) * escala) );
 
549
        quad[2] = puntoMedio + ( matrizRotacion.ProductoMatricial( alineacion + TVector( tc->ancho, ((float)tc->alto) ) * escala) );
 
550
        quad[3] = puntoMedio + ( matrizRotacion.ProductoMatricial( alineacion +  TVector( 0.0f,     ((float)tc->alto) ) * escala) );
 
551
 
 
552
        AjustarAPixelsPantalla(c, quad, 4);
 
553
 
 
554
        tc->Render(quad, c->flipHorizontal, c->flipVertical, c->rotacion);
 
555
 
 
556
 
 
557
 
 
558
        //------------------------------------------------------------------------------------------
 
559
        // Dibujado de la linea punteada de arrastre
 
560
        if (m_MouseDown) {
 
561
                glLineWidth(WIDGET_GROSOR_LINEA_ARRASTRE);
 
562
                glEnable(GL_LINE_STIPPLE);
 
563
                wColorLineaArrastre.Aplicar();
 
564
                glLineStipple(3, 0xAAAA);
 
565
 
 
566
                GNC::GCS::Vector startPoint, endPoint;
 
567
                if (m_Vertices[0].m_Seleccionado)
 
568
                {
 
569
                        startPoint = m_Vertices[0];
 
570
                        endPoint = m_Vertices[0] - (m_PosCursor - m_StartPointMov);
 
571
                }
 
572
                else if (m_Vertices[1].m_Seleccionado)
 
573
                {
 
574
                        startPoint = m_Vertices[1];
 
575
                        endPoint = m_Vertices[1] - (m_PosCursor - m_StartPointMov);
 
576
                }
 
577
                else // Es el centro
 
578
                {
 
579
                        startPoint = m_CentroAntiguo;
 
580
                        endPoint = m_Centro;
 
581
                }
 
582
 
 
583
                glBegin(GL_LINE_STRIP);
 
584
                glVertex2d(startPoint.x, startPoint.y);
 
585
                glVertex2d(endPoint.x, endPoint.y);
 
586
                glEnd();
 
587
 
 
588
                glDisable(GL_LINE_STIPPLE);
 
589
        }
 
590
 
 
591
}
 
592
 
 
593
bool GNC::GCS::Widgets::WRegla::GetMenuContextual(wxMenu* menuContextual, wxWindow* pParent) {
 
594
 
 
595
        GNC::GCS::Widgets::Dialogos::Calibracion* pCalibracion = new GNC::GCS::Widgets::Dialogos::Calibracion(pParent, this, m_pManager);
 
596
        wxMenuItem* pMenuCalibrar = new wxMenuItem(menuContextual, 1, _("Image Calibration"), _("Image Calibration"), wxITEM_NORMAL );
 
597
        menuContextual->Connect(1,wxEVT_COMMAND_MENU_SELECTED,wxCommandEventHandler( GNC::GCS::Widgets::Dialogos::Calibracion::OnClickEnMenu),NULL,pCalibracion);
 
598
 
 
599
        #ifdef __WXMSW__
 
600
        pMenuCalibrar->SetBitmaps(GinkgoResourcesManager::IconosMenus::GetIcoCalibrarImagen());
 
601
        #else
 
602
        pMenuCalibrar->SetBitmap(GinkgoResourcesManager::IconosMenus::GetIcoCalibrarImagen());
 
603
        #endif
 
604
 
 
605
        menuContextual->Append(pMenuCalibrar);
 
606
        return true;
 
607
}
 
608
 
 
609
GNC::GCS::Widgets::WRegla::TexturaRegla* GNC::GCS::Widgets::WRegla::GetTextura(GNC::GCS::IWidgetsRenderer* renderer)
 
610
{
 
611
        if(m_mapaRecursos.find(renderer) == m_mapaRecursos.end()) {
 
612
                TexturaRegla* pTextura = new TexturaRegla();
 
613
                m_mapaRecursos[renderer] = pTextura;
 
614
                Recalcular(renderer);
 
615
        }
 
616
        return m_mapaRecursos[renderer];
 
617
}
 
618
 
 
619
void GNC::GCS::Widgets::WRegla::Recalcular(GNC::GCS::IWidgetsRenderer* renderer)
 
620
{
 
621
        GNC::GCS::Vector3D worldPosition0,worldPosition1, wDiff;
 
622
        GNC::GCS::Vector iDiff;
 
623
        double imagePosition0[3] = {m_Vertices[0].x, m_Vertices[0].y};
 
624
        double imagePosition1[3] = {m_Vertices[1].x, m_Vertices[1].y};
 
625
 
 
626
        renderer->m_pImageViewer->CoordenadasImagenACoordenadasMundo(imagePosition0, worldPosition0.v);
 
627
        renderer->m_pImageViewer->CoordenadasImagenACoordenadasMundo(imagePosition1, worldPosition1.v);
 
628
                
 
629
 
 
630
        //std::cout << "--- Recalculando... " << std::endl;
 
631
        m_Modificado = true;
 
632
        wDiff = worldPosition1 - worldPosition0;
 
633
        iDiff = m_Vertices[1] - m_Vertices[0];
 
634
        m_Centro = m_Vertices[0].PuntoMedio(m_Vertices[1]);
 
635
        m_Pendiente = iDiff.Pendiente();
 
636
        m_Angulo = iDiff.AnguloSobreAbscisa();
 
637
        m_Distancia = worldPosition0.DistanciaEuclidea(worldPosition1);
 
638
        //std::cout << *this << std::endl;
 
639
 
 
640
        std::stringstream os;
 
641
        os.setf(ios::floatfield, ios::fixed );
 
642
        os.precision(2);
 
643
        os.fill('0');
 
644
 
 
645
        float metricaDistancia = wDiff.Norma2();
 
646
 
 
647
        if (metricaDistancia > 1000.0f) {
 
648
                os << metricaDistancia / 1000.0f << " m.";
 
649
        }
 
650
        else if (metricaDistancia > 10.0f) {
 
651
                os << metricaDistancia / 10.0f << " cm.";
 
652
        }
 
653
        else if (metricaDistancia < 1.0f) {
 
654
                        os << metricaDistancia * 1000.0f << " µm.";
 
655
                }
 
656
        else {
 
657
                os << metricaDistancia << " mm.";
 
658
        }
 
659
 
 
660
        std::string medida = os.str();
 
661
 
 
662
        if (renderer != NULL) {
 
663
 
 
664
                TexturaRegla* tr = GetTextura(renderer);
 
665
                if (m_Texto != medida || tr->texto != medida) {
 
666
                        tr->texto = medida;
 
667
                        m_Texto = medida;
 
668
                        //std::cout << "distancia = " << m_Texto << std::endl;
 
669
                        GNC::GCS::TexturaCairo* tc = tr->m_textura;
 
670
 
 
671
                        if (!tc->contextoCreado) {
 
672
                                tc->Redimensionar(2, 2);
 
673
                        }
 
674
 
 
675
                        cairo_font_options_t* options;
 
676
                        options = cairo_font_options_create ();
 
677
 
 
678
                        cairo_select_font_face (tc->cr, "Arial", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
 
679
                        cairo_set_font_size(tc->cr, WIDGET_SIZE_FUENTE);
 
680
                        cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_NONE);
 
681
                        cairo_set_font_options(tc->cr, options);
 
682
 
 
683
                        m_TamTexto = GNC::GCS::GLHelper::calcularBoundingBox((*tc), m_Texto, m_AnchoMaximo); // Tamaño de la region en pixels
 
684
 
 
685
                        tc->Redimensionar(std::ceil(m_TamTexto.x), std::ceil(m_TamTexto.y));
 
686
                        m_TamTexto.Asignar(tc->ancho, tc->alto);
 
687
 
 
688
                        cairo_select_font_face (tc->cr, "Arial", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
 
689
                        cairo_set_font_size(tc->cr, WIDGET_SIZE_FUENTE);
 
690
                        cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_NONE);
 
691
                        cairo_set_font_options(tc->cr, options);
 
692
 
 
693
                        cairo_set_operator(tc->cr, CAIRO_OPERATOR_SOURCE);
 
694
                        cairo_set_source_rgba(tc->cr, 0.0f, 0.0f, 0.0f, 0.0f);
 
695
                        cairo_paint(tc->cr);
 
696
 
 
697
                        cairo_font_options_destroy(options);
 
698
                        options = NULL;
 
699
 
 
700
                        cairo_set_source_rgba (tc->cr, 1.0f, 1.0f, 1.0f, 1.0f);
 
701
                        GNC::GCS::GLHelper::dibujarTexto((*tc), m_Texto, m_AnchoMaximo);
 
702
                }
 
703
        }
 
704
}
 
705
 
 
706
void GNC::GCS::Widgets::WRegla::LiberarRecursos(GNC::GCS::IWidgetsRenderer* renderer)
 
707
{
 
708
        TMapaRecursos::iterator it = m_mapaRecursos.find(renderer);
 
709
        if(it!=m_mapaRecursos.end()) {
 
710
                delete (*it).second;
 
711
                m_mapaRecursos.erase(it);
 
712
        }
 
713
}
 
714
 
 
715
//region Interfaz de eventos ginkgo
 
716
 
 
717
 
 
718
//endregion
 
719
void GNC::GCS::Widgets::WRegla::InsertarPropiedades(TListaMapasPropiedades &listaMapaPropiedades)
 
720
{
 
721
        TMapaPropiedades& primerMapa = listaMapaPropiedades.front();
 
722
        {
 
723
                std::stringstream os;
 
724
                os.setf(ios::floatfield, ios::fixed );
 
725
                os.precision(2);
 
726
                os.fill('0');
 
727
 
 
728
                float metricaDistancia = m_Distancia;
 
729
 
 
730
                if (metricaDistancia > 1000.0f) {
 
731
                        os << metricaDistancia / 1000.0f << " m.";
 
732
                }
 
733
                else if (metricaDistancia > 10.0f) {
 
734
                        os << metricaDistancia / 10.0f << " cm.";
 
735
                }
 
736
                else if (metricaDistancia < 1.0f) {
 
737
                        os << metricaDistancia * 1000.0f << " µm.";
 
738
                }
 
739
                else {
 
740
                        os << metricaDistancia << " mm.";
 
741
                }
 
742
 
 
743
                std::string medida = os.str();
 
744
                primerMapa[_Std("Length")] = medida;
 
745
         }
 
746
        {
 
747
                std::stringstream out;
 
748
                out << m_Vertices[0] << ",\n" << m_Vertices[1];
 
749
                primerMapa[_Std("Points (I)")] = out.str();
 
750
        }
 
751
        {
 
752
                std::stringstream out;
 
753
                out << PuntoToStringMundo(m_Vertices[0]) << "," << std::endl;
 
754
                out << PuntoToStringMundo(m_Vertices[1]) ;
 
755
                
 
756
                primerMapa[_Std("Points (M)")] = out.str();
 
757
        }
 
758
}
 
759
 
 
760
void GNC::GCS::Widgets::WRegla::OffscreenRender(GNC::GCS::Contexto3D* c)
 
761
{
 
762
        GNC::GCS::Vector Diff = m_Vertices[1] - m_Vertices[0];
 
763
        GNC::GCS::Vector TamTexto;
 
764
 
 
765
        std::stringstream os;
 
766
        os.setf(ios::floatfield, ios::fixed );
 
767
        os.precision(2);
 
768
        os.fill('0');
 
769
 
 
770
        float metricaDistancia = m_Distancia;
 
771
 
 
772
        if (metricaDistancia > 1000.0f) {
 
773
                os << metricaDistancia / 1000.0f << " m.";
 
774
        }
 
775
        else if (metricaDistancia > 10.0f) {
 
776
                os << metricaDistancia / 10.0f << " cm.";
 
777
        }
 
778
        else if (metricaDistancia < 1.0f) {
 
779
                os << metricaDistancia * 1000.0f << " µm.";
 
780
        }
 
781
        else {
 
782
                os << metricaDistancia << " mm.";
 
783
        }
 
784
 
 
785
        std::string medida = os.str();
 
786
 
 
787
        const GNC::GCS::Vector& escala = c->RefRelacionMundoPantallaOffscreen();
 
788
 
 
789
        GNC::GCS::Vector vert[2] = {c->Reproyectar(m_Vertices[0]) * c->factorReescalado, c->Reproyectar(m_Vertices[1]) * c->factorReescalado };
 
790
 
 
791
        glLineWidth(WIDGET_GROSOR_LINEA);
 
792
 
 
793
        // Dibujado de la regla
 
794
        wColorNormal.AplicarCairo(c->cr);
 
795
        cairo_move_to(c->cr, vert[0].x, vert[0].y);
 
796
        cairo_line_to(c->cr, vert[1].x, vert[1].y);
 
797
        cairo_stroke(c->cr);
 
798
 
 
799
        TVector diff = vert[1] - vert[0];
 
800
 
 
801
        TVector puntoMedio = vert[0].PuntoMedio(vert[1]);
 
802
        TVector ortogonal = (diff).VectorOrtonormal() * escala * 6.0f;
 
803
 
 
804
        TVector f00 = vert[0] + ortogonal;
 
805
        TVector f01 = vert[0] - ortogonal;
 
806
        TVector f10 = puntoMedio + ortogonal;
 
807
        TVector f20 = vert[1] + ortogonal;
 
808
        TVector f21 = vert[1] - ortogonal;
 
809
 
 
810
        //------------------------------------------------------------------------------------------
 
811
        // Dibujado de las marcas de la regla.
 
812
 
 
813
        //-- marcas normales
 
814
        wColorNormal.AplicarCairo(c->cr);
 
815
        //-- Marca izquierda
 
816
        cairo_move_to(c->cr, f00.x , f00.y );
 
817
        cairo_line_to(c->cr, f01.x , f01.y );
 
818
        cairo_stroke(c->cr);
 
819
 
 
820
        //-- Marca central
 
821
        cairo_move_to(c->cr, f10.x , f10.y );
 
822
        cairo_line_to(c->cr, puntoMedio.x , puntoMedio.y );
 
823
        cairo_stroke(c->cr);
 
824
 
 
825
        // Marca derecha
 
826
        cairo_move_to(c->cr, f20.x , f20.y );
 
827
        cairo_line_to(c->cr, f21.x , f21.y );
 
828
        cairo_stroke(c->cr);
 
829
 
 
830
        //------------------------------------------------------------------------------------------
 
831
        //// Dibujado del texto de la medida
 
832
        cairo_font_options_t* options;
 
833
        options = cairo_font_options_create ();
 
834
 
 
835
        cairo_select_font_face (c->cr, "Arial", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
 
836
        cairo_set_font_size(c->cr, std::max(WIDGET_SIZE_FUENTE * escala.x, (double)8.0f));
 
837
        cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_NONE);
 
838
        cairo_set_font_options(c->cr, options);
 
839
 
 
840
        TamTexto = GNC::GCS::Widgets::HelperTexto::calcularBoundingBox(c, medida, m_AnchoMaximo * escala.x); // Tamaño de la region en pixels
 
841
 
 
842
        cairo_set_source_rgba (c->cr, 1.0f, 1.0f, 1.0f, 1.0f);
 
843
        cairo_save(c->cr);
 
844
        GNC::GCS::Vector puntoTexto( puntoMedio.x - (TamTexto.x / 2.0f), puntoMedio.y - TamTexto.y);
 
845
        puntoTexto.Redondear();
 
846
        cairo_translate(c->cr, puntoTexto.x, puntoTexto.y);
 
847
        GNC::GCS::Widgets::HelperTexto::dibujarTexto(c, medida, m_AnchoMaximo * escala.x);
 
848
        cairo_restore(c->cr);
 
849
 
 
850
        cairo_font_options_destroy(options);
 
851
 
 
852
}
 
853
 
 
854
void GNC::GCS::Widgets::WRegla::ProcesarEvento(GNC::GCS::Eventos::IEvento *evt)
 
855
{
 
856
        if (EstaOculto())
 
857
        {
 
858
                return;
 
859
        }
 
860
        if (evt->GetCodigoEvento() == ginkgoEVT_Core_ModificacionImagen)
 
861
        {
 
862
                GNC::GCS::Eventos::EventoModificacionImagen* pEvt = dynamic_cast<GNC::GCS::Eventos::EventoModificacionImagen*>(evt);
 
863
                if (pEvt == NULL) {
 
864
                        std::cerr << "Error al interpretar evento como evento de modificacion de imagen: Evento = " << evt << std::endl;
 
865
                        return;
 
866
                }
 
867
                if(pEvt->GetTipo() == GNC::GCS::Eventos::EventoModificacionImagen::ImagenRecalibrada)
 
868
                {
 
869
                        Recalcular(m_pManager->GetRendererActivo());
 
870
                }
 
871
        }
 
872
}
 
873