3
* $Id: wregla.cpp 3748 2011-04-20 10:38:38Z carlos $
6
* Copyright 2008-10 MetaEmotion S.L. All rights reserved.
7
* http://ginkgo-cadx.com
9
* This file is licensed under LGPL v3 license.
10
* See License.txt for details
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>
22
#include <widgets/gui/calibracion.h>
24
#include <wx/xml/xml.h>
27
#include <main/managers/widgetsmanager.h>
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>
38
//region "Implementacion de WReglaBuilder"
40
GNC::GCS::Widgets::WReglaBuilder::WReglaBuilder(GNC::GCS::IWidgetsManager* pManager) : GNC::GCS::Widgets::IWidgetBuilder(pManager)
45
GNC::GCS::Eventos::EventoModificacionImagen evt1(m_pManager->GetVista());
48
GNC::GCS::Widgets::WReglaBuilder::~WReglaBuilder()
50
if (m_pReglaTemp != NULL) {
56
void GNC::GCS::Widgets::WReglaBuilder::OnMouseEvents(GNC::GCS::Eventos::EventoRaton& evento)
61
GTRACE("GNC::GCS::Widgets::WReglaBuilder::OnMouseEvents(wxMouseEvent&)");
62
if (m_MouseDown && evento.ButtonUp(GNC::GCS::Eventos::EventoRaton::EB_IZQUIERDO)) {
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);
76
m_pManager->Modificado();
80
} else if (evento.ButtonDown(GNC::GCS::Eventos::EventoRaton::EB_IZQUIERDO)) {
84
nodos[0] = nodos[1] = evento.iP;
85
if (m_pReglaTemp != NULL) {
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();
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();
104
void GNC::GCS::Widgets::WReglaBuilder::OnKeyEvents(GNC::GCS::Eventos::EventoTeclado&)
106
GTRACE("GNC::GCS::Widgets::WReglaBuilder::OnKeyEvents(wxKeyEvent&)");
109
void GNC::GCS::Widgets::WReglaBuilder::Render(GNC::GCS::Contexto3D* c)
111
if (m_pReglaTemp == NULL) {
114
m_pReglaTemp->Render(c);
117
GNC::GCS::Widgets::TipoCursor GNC::GCS::Widgets::WReglaBuilder::GetCursor()
119
return GNC::GCS::Widgets::CUR_CREAR_LINEA;
122
//region Interfaz de eventos ginkgo
132
//region "Constructor y destructor"
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()
136
m_Vertices[0] = nodos[0];
137
m_Vertices[1] = nodos[1];
140
m_ReservaRecursos = true;
143
GNC::GCS::Eventos::EventoModificacionImagen evt1(m_pManager->GetVista());
144
m_pManager->GetControladorEventos()->Registrar(this, evt1);
147
GNC::GCS::Widgets::WRegla::~WRegla()
149
LanzarEventoDestruccion();
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)
157
if(nodo->GetName() != wxT("rule_widget")){
158
std::cerr<< "Ha ocurrido un error al desserializar el widget regla"<<std::endl;
161
wxXmlNode *child = nodo->GetChildren();
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);
168
child = child->GetNext();
172
m_ReservaRecursos = true;
174
GNC::GCS::Eventos::EventoModificacionImagen evt1(m_pManager->GetVista());
175
m_pManager->GetControladorEventos()->Registrar(this, evt1);
178
wxXmlNode* GNC::GCS::Widgets::WRegla::Serializar(const std::string& nombreMedico)
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);
189
SerializarMetadatos(resultado,nombreMedico);
195
void GNC::GCS::Widgets::WRegla::OnMouseEvents(GNC::GCS::Eventos::EventoRaton& evento)
200
//------------------------------------------------------
202
if (evento.Leaving() ) {
205
//------------------------------------------------------
207
else if (evento.Entering() ) {
212
//------------------------------------------------------
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;
221
if (EstaSeleccionado() || m_Vertices[1].EstaSeleccionado()) {
222
m_Vertices[1] += delta;
224
LanzarEventoModificacion();
225
Recalcular(evento.c->GetRenderer());
229
//------------------------------------------------------
231
else if (evento.LeftDown()) {
233
if (EventoConsumido() && !evento.m_controlDown) {
234
SeleccionarNodo(m_Vertices[0], false);
235
SeleccionarNodo(m_Vertices[1], false);
243
m_StartPointMov = evento.iP;
245
const GNC::GCS::Vector::TComponente& factor = evento.c->RelacionImagenPantalla().NormaInfinito();
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);
254
else { // Click fuera del nodo
255
SeleccionarNodo(m_Vertices[0], false);
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);
264
else { // Click fuera del nodo
265
SeleccionarNodo(m_Vertices[1], false);
268
if (!dentro && HitTest(evento.iP.x, evento.iP.y, factor ) ) { // click sobre la recta
269
if (evento.m_controlDown) { // Inversion de seleccion
278
else { // Click fuera del nodo
279
if (!evento.m_controlDown) {
284
if (EstaSeleccionado()) {
286
m_PosCursor = evento.iP;
287
m_CentroAntiguo = m_Centro;
294
m_PosCursor = evento.iP;
295
m_CentroAntiguo = m_Centro;
300
//------------------------------------------------------
302
else if (evento.LeftUp()) {
304
ActualizarTimestampModificacion();
309
//------------------------------------------------------
311
else if (evento.Moving()) {
313
if (EventoConsumido()) {
314
IluminarNodo(m_Vertices[0], false);
315
IluminarNodo(m_Vertices[1], false);
321
m_PosCursor = evento.iP;
323
const GNC::GCS::Vector::TComponente& factor = evento.c->RelacionImagenPantalla().NormaInfinito();
325
if (m_Vertices[0].Hits(evento.iP.x, evento.iP.y, factor)) {
327
IluminarNodo(m_Vertices[0], true);
328
IluminarNodo(m_Vertices[1], false);
334
IluminarNodo(m_Vertices[0], false);
337
if (m_Vertices[1].Hits(evento.iP.x, evento.iP.y, factor)) {
339
IluminarNodo(m_Vertices[0], false);
340
IluminarNodo(m_Vertices[1], true);
346
IluminarNodo(m_Vertices[1], false);
349
if (!dentro && HitTest(evento.iP.x, evento.iP.y, factor) ) {
364
void GNC::GCS::Widgets::WRegla::OnKeyEvents(GNC::GCS::Eventos::EventoTeclado& evento)
366
if (evento.GetKeyCode() == WXK_ESCAPE) {
371
bool GNC::GCS::Widgets::WRegla::HitTest(float x, float y, float umbral)
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 ) {
383
bool GNC::GCS::Widgets::WRegla::HitTest(GNC::GCS::Vector* vertices, int numVertices)
385
return m_Vertices[0].DentroDePoligono2(vertices, numVertices) && m_Vertices[1].DentroDePoligono2(vertices, numVertices);
388
void GNC::GCS::Widgets::WRegla::Render(GNC::GCS::Contexto3D* c)
394
const GNC::GCS::Vector& escala = c->RelacionImagenPantalla();
396
glLineWidth(WIDGET_GROSOR_LINEA);
398
// Highlights sobre nodos activos
399
if (m_Vertices[0].m_Iluminado) {
400
wDibujarElipseDegradado(m_Vertices[0], wRadioPuntoIluminado * escala, wColorPuntoIluminadoInterior, wColorPuntoIluminadoExterior);
403
if (m_Vertices[1].m_Iluminado) {
404
wDibujarElipseDegradado(m_Vertices[1], wRadioPuntoIluminado * escala, wColorPuntoIluminadoInterior, wColorPuntoIluminadoExterior);
407
float fsombrax, fsombray;
408
if (m_Seleccionado && m_MouseDown)
410
fsombrax = WIDGET_OFFSET_X_SOMBRA_SELECCIONADO * escala.x;
411
fsombray = WIDGET_OFFSET_Y_SOMBRA_SELECCIONADO * escala.y;
415
fsombrax = WIDGET_OFFSET_X_SOMBRA * escala.x;
416
fsombray = WIDGET_OFFSET_Y_SOMBRA * escala.y;
419
//------------------------------------------------------------------------------------------
420
// Sombra de la regla
421
wColorSombra.Aplicar();
423
glVertex2d(m_Vertices[0].x + fsombrax, m_Vertices[0].y - fsombray);
424
glVertex2d(m_Vertices[1].x + fsombrax, m_Vertices[1].y - fsombray);
427
// Dibujado de la regla
428
wAplicarColor(m_Iluminado, m_MouseDown, m_Seleccionado);
430
glVertex2d(m_Vertices[0].x, m_Vertices[0].y);
431
glVertex2d(m_Vertices[1].x, m_Vertices[1].y);
435
TVector diff = m_Vertices[1] - m_Vertices[0];
437
TVector puntoMedio = m_Vertices[0].PuntoMedio(m_Vertices[1]);
438
TVector ortogonal = (diff).VectorOrtonormal() * escala * 6.0f;
440
if (m_MouseDown && m_Seleccionado)
441
ortogonal *= WIDGET_INCREMENTO_DETALLE_SELECCIONADO;
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;
451
//------------------------------------------------------------------------------------------
452
// Dibujado de las marcas de la regla.
454
wColorSombra.Aplicar();
456
glVertex2d(f00.x + fsombrax, f00.y - fsombray);
457
glVertex2d(f01.x + fsombrax, f01.y - fsombray);
461
glVertex2d(f10.x + fsombrax, f10.y - fsombray);
462
glVertex2d(puntoMedio.x + fsombrax, puntoMedio.y - fsombray);
466
glVertex2d(f20.x + fsombrax, f20.y - fsombray);
467
glVertex2d(f21.x + fsombrax, f21.y - fsombray);
472
glVertex2d(f20.x + fsombrax, f20.y - fsombray);
473
glVertex2d(f21.x + fsombrax, f21.y - fsombray);
477
wAplicarColor(m_Iluminado || m_Vertices[0].m_Iluminado, m_MouseDown, m_Seleccionado);
479
glVertex2d(f00.x, f00.y);
480
glVertex2d(f01.x, f01.y);
484
wAplicarColor(m_Iluminado, m_MouseDown, m_Seleccionado);
486
glVertex2d(f10.x, f10.y);
487
glVertex2d(puntoMedio.x, puntoMedio.y);
491
wAplicarColor(m_Iluminado || m_Vertices[1].m_Iluminado, m_MouseDown, m_Seleccionado);
493
glVertex2d(f20.x, f20.y);
494
glVertex2d(f21.x, f21.y);
497
//------------------------------------------------------------------------------------------
498
// Dibujado del texto de la medida
499
TexturaRegla* tr = GetTextura(c->GetRenderer());
500
if(tr->texto != m_Texto) {
501
Recalcular(c->GetRenderer());
503
GNC::GCS::TexturaCairo* tc = tr->m_textura;
505
if (!tc->contextoCreado) {
506
//std::cerr << "Error: Contexto no creado" << std::endl;
509
if (!tc->texturaCargada) {
512
if (tc->texturaModificada) {
516
//std::cout << "Dibujando..." << std::endl;
518
GNC::GCS::Vector quad[4];
520
// Dibujado del texto.
523
GNC::GCS::Vector alineacion = GNC::GCS::Vector(-m_TamTexto.x / 2.0f, -(m_TamTexto.y + 4.0f)) * escala;
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);
535
quad[0] += puntoMedio + alineacion;
536
quad[1] += puntoMedio + alineacion;
537
quad[2] += puntoMedio + alineacion;
538
quad[3] += puntoMedio + alineacion;
540
AjustarAPixelsPantalla(c, quad, 4);
545
TMatriz matrizRotacion = TMatriz::MatrizRotacion(c->rotacion);
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) );
552
AjustarAPixelsPantalla(c, quad, 4);
554
tc->Render(quad, c->flipHorizontal, c->flipVertical, c->rotacion);
558
//------------------------------------------------------------------------------------------
559
// Dibujado de la linea punteada de arrastre
561
glLineWidth(WIDGET_GROSOR_LINEA_ARRASTRE);
562
glEnable(GL_LINE_STIPPLE);
563
wColorLineaArrastre.Aplicar();
564
glLineStipple(3, 0xAAAA);
566
GNC::GCS::Vector startPoint, endPoint;
567
if (m_Vertices[0].m_Seleccionado)
569
startPoint = m_Vertices[0];
570
endPoint = m_Vertices[0] - (m_PosCursor - m_StartPointMov);
572
else if (m_Vertices[1].m_Seleccionado)
574
startPoint = m_Vertices[1];
575
endPoint = m_Vertices[1] - (m_PosCursor - m_StartPointMov);
579
startPoint = m_CentroAntiguo;
583
glBegin(GL_LINE_STRIP);
584
glVertex2d(startPoint.x, startPoint.y);
585
glVertex2d(endPoint.x, endPoint.y);
588
glDisable(GL_LINE_STIPPLE);
593
bool GNC::GCS::Widgets::WRegla::GetMenuContextual(wxMenu* menuContextual, wxWindow* pParent) {
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);
600
pMenuCalibrar->SetBitmaps(GinkgoResourcesManager::IconosMenus::GetIcoCalibrarImagen());
602
pMenuCalibrar->SetBitmap(GinkgoResourcesManager::IconosMenus::GetIcoCalibrarImagen());
605
menuContextual->Append(pMenuCalibrar);
609
GNC::GCS::Widgets::WRegla::TexturaRegla* GNC::GCS::Widgets::WRegla::GetTextura(GNC::GCS::IWidgetsRenderer* renderer)
611
if(m_mapaRecursos.find(renderer) == m_mapaRecursos.end()) {
612
TexturaRegla* pTextura = new TexturaRegla();
613
m_mapaRecursos[renderer] = pTextura;
614
Recalcular(renderer);
616
return m_mapaRecursos[renderer];
619
void GNC::GCS::Widgets::WRegla::Recalcular(GNC::GCS::IWidgetsRenderer* renderer)
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};
626
renderer->m_pImageViewer->CoordenadasImagenACoordenadasMundo(imagePosition0, worldPosition0.v);
627
renderer->m_pImageViewer->CoordenadasImagenACoordenadasMundo(imagePosition1, worldPosition1.v);
630
//std::cout << "--- Recalculando... " << std::endl;
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;
640
std::stringstream os;
641
os.setf(ios::floatfield, ios::fixed );
645
float metricaDistancia = wDiff.Norma2();
647
if (metricaDistancia > 1000.0f) {
648
os << metricaDistancia / 1000.0f << " m.";
650
else if (metricaDistancia > 10.0f) {
651
os << metricaDistancia / 10.0f << " cm.";
653
else if (metricaDistancia < 1.0f) {
654
os << metricaDistancia * 1000.0f << " µm.";
657
os << metricaDistancia << " mm.";
660
std::string medida = os.str();
662
if (renderer != NULL) {
664
TexturaRegla* tr = GetTextura(renderer);
665
if (m_Texto != medida || tr->texto != medida) {
668
//std::cout << "distancia = " << m_Texto << std::endl;
669
GNC::GCS::TexturaCairo* tc = tr->m_textura;
671
if (!tc->contextoCreado) {
672
tc->Redimensionar(2, 2);
675
cairo_font_options_t* options;
676
options = cairo_font_options_create ();
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);
683
m_TamTexto = GNC::GCS::GLHelper::calcularBoundingBox((*tc), m_Texto, m_AnchoMaximo); // Tamaño de la region en pixels
685
tc->Redimensionar(std::ceil(m_TamTexto.x), std::ceil(m_TamTexto.y));
686
m_TamTexto.Asignar(tc->ancho, tc->alto);
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);
693
cairo_set_operator(tc->cr, CAIRO_OPERATOR_SOURCE);
694
cairo_set_source_rgba(tc->cr, 0.0f, 0.0f, 0.0f, 0.0f);
697
cairo_font_options_destroy(options);
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);
706
void GNC::GCS::Widgets::WRegla::LiberarRecursos(GNC::GCS::IWidgetsRenderer* renderer)
708
TMapaRecursos::iterator it = m_mapaRecursos.find(renderer);
709
if(it!=m_mapaRecursos.end()) {
711
m_mapaRecursos.erase(it);
715
//region Interfaz de eventos ginkgo
719
void GNC::GCS::Widgets::WRegla::InsertarPropiedades(TListaMapasPropiedades &listaMapaPropiedades)
721
TMapaPropiedades& primerMapa = listaMapaPropiedades.front();
723
std::stringstream os;
724
os.setf(ios::floatfield, ios::fixed );
728
float metricaDistancia = m_Distancia;
730
if (metricaDistancia > 1000.0f) {
731
os << metricaDistancia / 1000.0f << " m.";
733
else if (metricaDistancia > 10.0f) {
734
os << metricaDistancia / 10.0f << " cm.";
736
else if (metricaDistancia < 1.0f) {
737
os << metricaDistancia * 1000.0f << " µm.";
740
os << metricaDistancia << " mm.";
743
std::string medida = os.str();
744
primerMapa[_Std("Length")] = medida;
747
std::stringstream out;
748
out << m_Vertices[0] << ",\n" << m_Vertices[1];
749
primerMapa[_Std("Points (I)")] = out.str();
752
std::stringstream out;
753
out << PuntoToStringMundo(m_Vertices[0]) << "," << std::endl;
754
out << PuntoToStringMundo(m_Vertices[1]) ;
756
primerMapa[_Std("Points (M)")] = out.str();
760
void GNC::GCS::Widgets::WRegla::OffscreenRender(GNC::GCS::Contexto3D* c)
762
GNC::GCS::Vector Diff = m_Vertices[1] - m_Vertices[0];
763
GNC::GCS::Vector TamTexto;
765
std::stringstream os;
766
os.setf(ios::floatfield, ios::fixed );
770
float metricaDistancia = m_Distancia;
772
if (metricaDistancia > 1000.0f) {
773
os << metricaDistancia / 1000.0f << " m.";
775
else if (metricaDistancia > 10.0f) {
776
os << metricaDistancia / 10.0f << " cm.";
778
else if (metricaDistancia < 1.0f) {
779
os << metricaDistancia * 1000.0f << " µm.";
782
os << metricaDistancia << " mm.";
785
std::string medida = os.str();
787
const GNC::GCS::Vector& escala = c->RefRelacionMundoPantallaOffscreen();
789
GNC::GCS::Vector vert[2] = {c->Reproyectar(m_Vertices[0]) * c->factorReescalado, c->Reproyectar(m_Vertices[1]) * c->factorReescalado };
791
glLineWidth(WIDGET_GROSOR_LINEA);
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);
799
TVector diff = vert[1] - vert[0];
801
TVector puntoMedio = vert[0].PuntoMedio(vert[1]);
802
TVector ortogonal = (diff).VectorOrtonormal() * escala * 6.0f;
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;
810
//------------------------------------------------------------------------------------------
811
// Dibujado de las marcas de la regla.
814
wColorNormal.AplicarCairo(c->cr);
816
cairo_move_to(c->cr, f00.x , f00.y );
817
cairo_line_to(c->cr, f01.x , f01.y );
821
cairo_move_to(c->cr, f10.x , f10.y );
822
cairo_line_to(c->cr, puntoMedio.x , puntoMedio.y );
826
cairo_move_to(c->cr, f20.x , f20.y );
827
cairo_line_to(c->cr, f21.x , f21.y );
830
//------------------------------------------------------------------------------------------
831
//// Dibujado del texto de la medida
832
cairo_font_options_t* options;
833
options = cairo_font_options_create ();
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);
840
TamTexto = GNC::GCS::Widgets::HelperTexto::calcularBoundingBox(c, medida, m_AnchoMaximo * escala.x); // Tamaño de la region en pixels
842
cairo_set_source_rgba (c->cr, 1.0f, 1.0f, 1.0f, 1.0f);
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);
850
cairo_font_options_destroy(options);
854
void GNC::GCS::Widgets::WRegla::ProcesarEvento(GNC::GCS::Eventos::IEvento *evt)
860
if (evt->GetCodigoEvento() == ginkgoEVT_Core_ModificacionImagen)
862
GNC::GCS::Eventos::EventoModificacionImagen* pEvt = dynamic_cast<GNC::GCS::Eventos::EventoModificacionImagen*>(evt);
864
std::cerr << "Error al interpretar evento como evento de modificacion de imagen: Evento = " << evt << std::endl;
867
if(pEvt->GetTipo() == GNC::GCS::Eventos::EventoModificacionImagen::ImagenRecalibrada)
869
Recalcular(m_pManager->GetRendererActivo());