Add the keyboard accelerator mechanism for menu items. Use that to
implement zoom in/out, and orient onto a csys. [git-p4: depot-paths = "//depot/solvespace/": change = 1663]solver
parent
6c63d9c8cb
commit
d36c70216a
16
entity.cpp
16
entity.cpp
|
@ -36,16 +36,15 @@ void Entity::DrawOrGetDistance(void) {
|
||||||
if(!SS.GW.show2dCsyss) break;
|
if(!SS.GW.show2dCsyss) break;
|
||||||
|
|
||||||
Vector p;
|
Vector p;
|
||||||
double a, b, c, d;
|
|
||||||
|
|
||||||
p = SS.point.FindById(point(16))->GetCoords();
|
p = SS.point.FindById(point(16))->GetCoords();
|
||||||
a = SS.param.FindById(param(0))->val;
|
|
||||||
b = SS.param.FindById(param(1))->val;
|
|
||||||
c = SS.param.FindById(param(2))->val;
|
|
||||||
d = SS.param.FindById(param(3))->val;
|
|
||||||
|
|
||||||
Vector u = Vector::RotationU(a, b, c, d);
|
double q[4];
|
||||||
Vector v = Vector::RotationV(a, b, c, d);
|
for(int i = 0; i < 4; i++) {
|
||||||
|
q[i] = SS.param.FindById(param(i))->val;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector u = Vector::RotationU(q[0], q[1], q[2], q[3]);
|
||||||
|
Vector v = Vector::RotationV(q[0], q[1], q[2], q[3]);
|
||||||
|
|
||||||
double s = (min(SS.GW.width, SS.GW.height))*0.4;
|
double s = (min(SS.GW.width, SS.GW.height))*0.4;
|
||||||
|
|
||||||
|
@ -77,3 +76,4 @@ void Entity::DrawOrGetDistance(void) {
|
||||||
oops();
|
oops();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
179
graphicswin.cpp
179
graphicswin.cpp
|
@ -2,36 +2,43 @@
|
||||||
|
|
||||||
#include "solvespace.h"
|
#include "solvespace.h"
|
||||||
|
|
||||||
|
#define mView (&GraphicsWindow::MenuView)
|
||||||
|
#define mEdit (&GraphicsWindow::MenuEdit)
|
||||||
const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
||||||
{ 0, "&File", 0, NULL },
|
{ 0, "&File", 0, NULL },
|
||||||
{ 1, "&New\tCtrl+N", 0, NULL },
|
{ 1, "&New\tCtrl+N", 0, NULL },
|
||||||
{ 1, "&Open...\tCtrl+O", 0, NULL },
|
{ 1, "&Open...\tCtrl+O", 0, NULL },
|
||||||
{ 1, "&Save\tCtrl+S", 0, NULL },
|
{ 1, "&Save\tCtrl+S", 0, NULL },
|
||||||
{ 1, "Save &As...", 0, NULL },
|
{ 1, "Save &As...", 0, NULL },
|
||||||
{ 1, NULL, 0, NULL },
|
{ 1, NULL, 0, NULL },
|
||||||
{ 1, "E&xit", 0, NULL },
|
{ 1, "E&xit", 0, NULL },
|
||||||
|
|
||||||
{ 0, "&Edit", 0, NULL },
|
{ 0, "&Edit", 0, NULL },
|
||||||
{ 1, "&Undo\tCtrl+Z", 0, NULL },
|
{ 1, "&Undo\tCtrl+Z", 0, NULL },
|
||||||
{ 1, "&Redo\tCtrl+Y", 0, NULL },
|
{ 1, "&Redo\tCtrl+Y", 0, NULL },
|
||||||
{ 0, "&View", 0, NULL },
|
{ 1, NULL, 0, NULL },
|
||||||
{ 1, "Zoom &In\t+", 0, NULL },
|
{ 1, "&Unselect All\tEsc", MNU_UNSELECT_ALL, 27, mEdit },
|
||||||
{ 1, "Zoom &Out\t-", 0, NULL },
|
|
||||||
{ 1, "Zoom To &Fit\tF", 0, NULL },
|
|
||||||
{ 1, NULL, 0, NULL },
|
|
||||||
{ 1, "Dimensions in &Inches", 0, NULL },
|
|
||||||
{ 1, "Dimensions in &Millimeters", 0, NULL },
|
|
||||||
|
|
||||||
{ 0, "&Sketch", 0, NULL },
|
{ 0, "&View", 0, NULL },
|
||||||
{ 1, NULL, 0, NULL },
|
{ 1, "Zoom &In\t+", MNU_ZOOM_IN, '+', mView },
|
||||||
{ 1, "To&ggle Construction\tG", 0, NULL },
|
{ 1, "Zoom &Out\t-", MNU_ZOOM_OUT, '-', mView },
|
||||||
|
{ 1, "Zoom To &Fit\tF", MNU_ZOOM_TO_FIT, 'F', mView },
|
||||||
|
{ 1, NULL, 0, NULL },
|
||||||
|
{ 1, "Onto Plane/Csys\tO", MNU_ORIENT_ONTO, 'O', mView },
|
||||||
|
{ 1, NULL, 0, NULL },
|
||||||
|
{ 1, "Dimensions in &Inches", 0, NULL },
|
||||||
|
{ 1, "Dimensions in &Millimeters", 0, NULL },
|
||||||
|
|
||||||
{ 0, "&Constrain", 0, NULL },
|
{ 0, "&Sketch", 0, NULL },
|
||||||
{ 1, "S&ymmetric\tY", 0, NULL },
|
{ 1, NULL, 0, NULL },
|
||||||
|
{ 1, "To&ggle Construction\tG", 0, NULL },
|
||||||
|
|
||||||
{ 0, "&Help", 0, NULL },
|
{ 0, "&Constrain", 0, NULL },
|
||||||
{ 1, "&About\t", 0, NULL },
|
{ 1, "S&ymmetric\tY", 0, NULL },
|
||||||
{ -1 },
|
|
||||||
|
{ 0, "&Help", 0, NULL },
|
||||||
|
{ 1, "&About\t", 0, NULL },
|
||||||
|
{ -1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
void GraphicsWindow::Init(void) {
|
void GraphicsWindow::Init(void) {
|
||||||
|
@ -40,7 +47,7 @@ void GraphicsWindow::Init(void) {
|
||||||
offset.x = offset.y = offset.z = 0;
|
offset.x = offset.y = offset.z = 0;
|
||||||
scale = 1;
|
scale = 1;
|
||||||
projRight.x = 1; projRight.y = projRight.z = 0;
|
projRight.x = 1; projRight.y = projRight.z = 0;
|
||||||
projDown.y = 1; projDown.z = projDown.x = 0;
|
projUp.y = 1; projUp.z = projUp.x = 0;
|
||||||
|
|
||||||
show2dCsyss = true;
|
show2dCsyss = true;
|
||||||
showAxes = true;
|
showAxes = true;
|
||||||
|
@ -50,10 +57,10 @@ void GraphicsWindow::Init(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsWindow::NormalizeProjectionVectors(void) {
|
void GraphicsWindow::NormalizeProjectionVectors(void) {
|
||||||
Vector norm = projRight.Cross(projDown);
|
Vector norm = projRight.Cross(projUp);
|
||||||
projDown = norm.Cross(projRight);
|
projUp = norm.Cross(projRight);
|
||||||
|
|
||||||
projDown = projDown.ScaledBy(1/projDown.Magnitude());
|
projUp = projUp.ScaledBy(1/projUp.Magnitude());
|
||||||
projRight = projRight.ScaledBy(1/projRight.Magnitude());
|
projRight = projRight.ScaledBy(1/projRight.Magnitude());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,10 +69,56 @@ Point2d GraphicsWindow::ProjectPoint(Vector p) {
|
||||||
|
|
||||||
Point2d r;
|
Point2d r;
|
||||||
r.x = p.Dot(projRight) * scale;
|
r.x = p.Dot(projRight) * scale;
|
||||||
r.y = p.Dot(projDown) * scale;
|
r.y = p.Dot(projUp) * scale;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphicsWindow::MenuView(MenuId id) {
|
||||||
|
switch(id) {
|
||||||
|
case MNU_ZOOM_IN:
|
||||||
|
SS.GW.scale *= 1.2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MNU_ZOOM_OUT:
|
||||||
|
SS.GW.scale /= 1.2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MNU_ZOOM_TO_FIT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MNU_ORIENT_ONTO:
|
||||||
|
SS.GW.GroupSelection();
|
||||||
|
if(SS.GW.gs.n == 1 && SS.GW.gs.csyss == 1) {
|
||||||
|
Entity *e = SS.entity.FindById(SS.GW.gs.entity[0]);
|
||||||
|
double q[4];
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
q[i] = SS.param.FindById(e->param(i))->val;
|
||||||
|
}
|
||||||
|
SS.GW.projRight = Vector::RotationU(q[0], q[1], q[2], q[3]);
|
||||||
|
SS.GW.projUp = Vector::RotationV(q[0], q[1], q[2], q[3]);
|
||||||
|
SS.GW.offset = SS.point.FindById(e->point(16))->GetCoords();
|
||||||
|
SS.GW.ClearSelection();
|
||||||
|
InvalidateGraphics();
|
||||||
|
} else {
|
||||||
|
Error("Select plane or coordinate system before orienting.");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: oops();
|
||||||
|
}
|
||||||
|
InvalidateGraphics();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicsWindow::MenuEdit(MenuId id) {
|
||||||
|
switch(id) {
|
||||||
|
case MNU_UNSELECT_ALL:
|
||||||
|
SS.GW.ClearSelection();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: oops();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
|
void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
|
||||||
bool middleDown, bool rightDown, bool shiftDown, bool ctrlDown)
|
bool middleDown, bool rightDown, bool shiftDown, bool ctrlDown)
|
||||||
{
|
{
|
||||||
|
@ -78,28 +131,28 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
|
||||||
double dy = (y - orig.mouse.y) / scale;
|
double dy = (y - orig.mouse.y) / scale;
|
||||||
|
|
||||||
if(shiftDown) {
|
if(shiftDown) {
|
||||||
offset.x = orig.offset.x + dx*projRight.x + dy*projDown.x;
|
offset.x = orig.offset.x + dx*projRight.x + dy*projUp.x;
|
||||||
offset.y = orig.offset.y + dx*projRight.y + dy*projDown.y;
|
offset.y = orig.offset.y + dx*projRight.y + dy*projUp.y;
|
||||||
offset.z = orig.offset.z + dx*projRight.z + dy*projDown.z;
|
offset.z = orig.offset.z + dx*projRight.z + dy*projUp.z;
|
||||||
} else if(ctrlDown) {
|
} else if(ctrlDown) {
|
||||||
double theta = atan2(orig.mouse.y, orig.mouse.x);
|
double theta = atan2(orig.mouse.y, orig.mouse.x);
|
||||||
theta -= atan2(y, x);
|
theta -= atan2(y, x);
|
||||||
|
|
||||||
Vector normal = orig.projRight.Cross(orig.projDown);
|
Vector normal = orig.projRight.Cross(orig.projUp);
|
||||||
projRight = orig.projRight.RotatedAbout(normal, theta);
|
projRight = orig.projRight.RotatedAbout(normal, theta);
|
||||||
projDown = orig.projDown.RotatedAbout(normal, theta);
|
projUp = orig.projUp.RotatedAbout(normal, theta);
|
||||||
|
|
||||||
NormalizeProjectionVectors();
|
NormalizeProjectionVectors();
|
||||||
} else {
|
} else {
|
||||||
double s = 0.3*(PI/180); // degrees per pixel
|
double s = 0.3*(PI/180); // degrees per pixel
|
||||||
projRight = orig.projRight.RotatedAbout(orig.projDown, -s*dx);
|
projRight = orig.projRight.RotatedAbout(orig.projUp, -s*dx);
|
||||||
projDown = orig.projDown.RotatedAbout(orig.projRight, s*dy);
|
projUp = orig.projUp.RotatedAbout(orig.projRight, s*dy);
|
||||||
|
|
||||||
NormalizeProjectionVectors();
|
NormalizeProjectionVectors();
|
||||||
}
|
}
|
||||||
|
|
||||||
orig.projRight = projRight;
|
orig.projRight = projRight;
|
||||||
orig.projDown = projDown;
|
orig.projUp = projUp;
|
||||||
orig.offset = offset;
|
orig.offset = offset;
|
||||||
orig.mouse.x = x;
|
orig.mouse.x = x;
|
||||||
orig.mouse.y = y;
|
orig.mouse.y = y;
|
||||||
|
@ -142,6 +195,7 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp, Selection *dest) {
|
||||||
dest->point.v = 0;
|
dest->point.v = 0;
|
||||||
dest->entity.v = 0;
|
dest->entity.v = 0;
|
||||||
|
|
||||||
|
// Do the points
|
||||||
for(i = 0; i < SS.entity.elems; i++) {
|
for(i = 0; i < SS.entity.elems; i++) {
|
||||||
d = SS.entity.elem[i].t.GetDistance(mp);
|
d = SS.entity.elem[i].t.GetDistance(mp);
|
||||||
if(d < 10 && d < dmin) {
|
if(d < 10 && d < dmin) {
|
||||||
|
@ -150,6 +204,7 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp, Selection *dest) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Entities
|
||||||
for(i = 0; i < SS.point.elems; i++) {
|
for(i = 0; i < SS.point.elems; i++) {
|
||||||
d = SS.point.elem[i].t.GetDistance(mp);
|
d = SS.point.elem[i].t.GetDistance(mp);
|
||||||
if(d < 10 && d < dmin) {
|
if(d < 10 && d < dmin) {
|
||||||
|
@ -159,9 +214,39 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp, Selection *dest) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphicsWindow::ClearSelection(void) {
|
||||||
|
for(int i = 0; i < MAX_SELECTED; i++) {
|
||||||
|
selection[i].Clear();
|
||||||
|
}
|
||||||
|
InvalidateGraphics();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicsWindow::GroupSelection(void) {
|
||||||
|
gs.points = gs.entities = 0;
|
||||||
|
gs.csyss = 0;
|
||||||
|
gs.n = 0;
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < MAX_SELECTED; i++) {
|
||||||
|
Selection *s = &(selection[i]);
|
||||||
|
if(s->point.v) {
|
||||||
|
gs.point[(gs.points)++] = s->point;
|
||||||
|
(gs.n)++;
|
||||||
|
}
|
||||||
|
if(s->entity.v) {
|
||||||
|
gs.entity[(gs.entities)++] = s->entity;
|
||||||
|
(gs.n)++;
|
||||||
|
|
||||||
|
Entity *e = SS.entity.FindById(s->entity);
|
||||||
|
if(e->type == Entity::CSYS_2D) {
|
||||||
|
(gs.csyss)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GraphicsWindow::MouseMiddleDown(double x, double y) {
|
void GraphicsWindow::MouseMiddleDown(double x, double y) {
|
||||||
orig.offset = offset;
|
orig.offset = offset;
|
||||||
orig.projDown = projDown;
|
orig.projUp = projUp;
|
||||||
orig.projRight = projRight;
|
orig.projRight = projRight;
|
||||||
orig.mouse.x = x;
|
orig.mouse.x = x;
|
||||||
orig.mouse.y = y;
|
orig.mouse.y = y;
|
||||||
|
@ -193,22 +278,22 @@ done:
|
||||||
|
|
||||||
void GraphicsWindow::MouseScroll(double x, double y, int delta) {
|
void GraphicsWindow::MouseScroll(double x, double y, int delta) {
|
||||||
double offsetRight = offset.Dot(projRight);
|
double offsetRight = offset.Dot(projRight);
|
||||||
double offsetDown = offset.Dot(projDown);
|
double offsetUp = offset.Dot(projUp);
|
||||||
|
|
||||||
double righti = x/scale - offsetRight;
|
double righti = x/scale - offsetRight;
|
||||||
double downi = y/scale - offsetDown;
|
double upi = y/scale - offsetUp;
|
||||||
|
|
||||||
if(delta > 0) {
|
if(delta > 0) {
|
||||||
scale *= 1.3;
|
scale *= 1.2;
|
||||||
} else {
|
} else {
|
||||||
scale /= 1.3;
|
scale /= 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
double rightf = x/scale - offsetRight;
|
double rightf = x/scale - offsetRight;
|
||||||
double downf = y/scale - offsetDown;
|
double upf = y/scale - offsetUp;
|
||||||
|
|
||||||
offset = offset.Plus(projRight.ScaledBy(rightf - righti));
|
offset = offset.Plus(projRight.ScaledBy(rightf - righti));
|
||||||
offset = offset.Plus(projDown.ScaledBy(downf - downi));
|
offset = offset.Plus(projUp.ScaledBy(upf - upi));
|
||||||
|
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
}
|
}
|
||||||
|
@ -245,10 +330,10 @@ void GraphicsWindow::Paint(int w, int h) {
|
||||||
glScaled(scale*2.0/w, scale*2.0/h, 0);
|
glScaled(scale*2.0/w, scale*2.0/h, 0);
|
||||||
|
|
||||||
double tx = projRight.Dot(offset);
|
double tx = projRight.Dot(offset);
|
||||||
double ty = projDown.Dot(offset);
|
double ty = projUp.Dot(offset);
|
||||||
double mat[16];
|
double mat[16];
|
||||||
MakeMatrix(mat, projRight.x, projRight.y, projRight.z, tx,
|
MakeMatrix(mat, projRight.x, projRight.y, projRight.z, tx,
|
||||||
projDown.x, projDown.y, projDown.z, ty,
|
projUp.x, projUp.y, projUp.z, ty,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
glMultMatrixd(mat);
|
glMultMatrixd(mat);
|
||||||
|
|
|
@ -126,7 +126,7 @@ void Point::Draw(void) {
|
||||||
|
|
||||||
double s = 4;
|
double s = 4;
|
||||||
Vector r = SS.GW.projRight.ScaledBy(4/SS.GW.scale);
|
Vector r = SS.GW.projRight.ScaledBy(4/SS.GW.scale);
|
||||||
Vector d = SS.GW.projDown.ScaledBy(4/SS.GW.scale);
|
Vector d = SS.GW.projUp.ScaledBy(4/SS.GW.scale);
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
glxVertex3v(v.Plus (r).Plus (d));
|
glxVertex3v(v.Plus (r).Plus (d));
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void dbp(char *str, ...);
|
void dbp(char *str, ...);
|
||||||
|
void Error(char *str, ...);
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
30
ui.h
30
ui.h
|
@ -69,17 +69,27 @@ public:
|
||||||
|
|
||||||
class GraphicsWindow {
|
class GraphicsWindow {
|
||||||
public:
|
public:
|
||||||
|
void Init(void);
|
||||||
|
|
||||||
// This table describes the top-level menus in the graphics winodw.
|
// This table describes the top-level menus in the graphics winodw.
|
||||||
typedef void MenuHandler(int id);
|
typedef enum {
|
||||||
|
MNU_ZOOM_IN = 100,
|
||||||
|
MNU_ZOOM_OUT,
|
||||||
|
MNU_ZOOM_TO_FIT,
|
||||||
|
MNU_ORIENT_ONTO,
|
||||||
|
MNU_UNSELECT_ALL,
|
||||||
|
} MenuId;
|
||||||
|
typedef void MenuHandler(MenuId id);
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int level; // 0 == on menu bar, 1 == one level down
|
int level; // 0 == on menu bar, 1 == one level down
|
||||||
char *label; // or NULL for a separator
|
char *label; // or NULL for a separator
|
||||||
int id; // unique ID
|
int id; // unique ID
|
||||||
|
int accel; // keyboard accelerator
|
||||||
MenuHandler *fn;
|
MenuHandler *fn;
|
||||||
} MenuEntry;
|
} MenuEntry;
|
||||||
static const MenuEntry menu[];
|
static const MenuEntry menu[];
|
||||||
|
static void MenuView(MenuId id);
|
||||||
void Init(void);
|
static void MenuEdit(MenuId id);
|
||||||
|
|
||||||
// The width and height (in pixels) of the window.
|
// The width and height (in pixels) of the window.
|
||||||
double width, height;
|
double width, height;
|
||||||
|
@ -88,12 +98,12 @@ public:
|
||||||
// projection.
|
// projection.
|
||||||
Vector offset;
|
Vector offset;
|
||||||
Vector projRight;
|
Vector projRight;
|
||||||
Vector projDown;
|
Vector projUp;
|
||||||
double scale;
|
double scale;
|
||||||
struct {
|
struct {
|
||||||
Vector offset;
|
Vector offset;
|
||||||
Vector projRight;
|
Vector projRight;
|
||||||
Vector projDown;
|
Vector projUp;
|
||||||
Point2d mouse;
|
Point2d mouse;
|
||||||
} orig;
|
} orig;
|
||||||
|
|
||||||
|
@ -116,6 +126,16 @@ public:
|
||||||
static const int MAX_SELECTED = 32;
|
static const int MAX_SELECTED = 32;
|
||||||
Selection selection[MAX_SELECTED];
|
Selection selection[MAX_SELECTED];
|
||||||
void HitTestMakeSelection(Point2d mp, Selection *dest);
|
void HitTestMakeSelection(Point2d mp, Selection *dest);
|
||||||
|
void ClearSelection(void);
|
||||||
|
struct {
|
||||||
|
hPoint point[MAX_SELECTED];
|
||||||
|
hEntity entity[MAX_SELECTED];
|
||||||
|
int points;
|
||||||
|
int entities;
|
||||||
|
int csyss;
|
||||||
|
int n;
|
||||||
|
} gs;
|
||||||
|
void GroupSelection(void);
|
||||||
|
|
||||||
// This sets what gets displayed.
|
// This sets what gets displayed.
|
||||||
bool show2dCsyss;
|
bool show2dCsyss;
|
||||||
|
|
|
@ -42,6 +42,17 @@ void dbp(char *str, ...)
|
||||||
OutputDebugString("\n");
|
OutputDebugString("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Error(char *str, ...)
|
||||||
|
{
|
||||||
|
va_list f;
|
||||||
|
char buf[1024];
|
||||||
|
va_start(f, str);
|
||||||
|
vsprintf(buf, str, f);
|
||||||
|
|
||||||
|
HWND h = GetForegroundWindow();
|
||||||
|
MessageBox(h, buf, "SolveSpace Error", MB_OK | MB_ICONERROR);
|
||||||
|
}
|
||||||
|
|
||||||
static void PaintTextWnd(HDC hdc)
|
static void PaintTextWnd(HDC hdc)
|
||||||
{
|
{
|
||||||
RECT rect;
|
RECT rect;
|
||||||
|
@ -241,6 +252,37 @@ LRESULT CALLBACK TextWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL ProcessKeyDown(WPARAM wParam)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
switch(wParam) {
|
||||||
|
case VK_OEM_PLUS: c = '+'; break;
|
||||||
|
case VK_OEM_MINUS: c = '-'; break;
|
||||||
|
case VK_ESCAPE: c = 27; break;
|
||||||
|
case VK_OEM_4: c = '['; break;
|
||||||
|
case VK_OEM_6: c = ']'; break;
|
||||||
|
case VK_OEM_5: c = '\\'; break;
|
||||||
|
case VK_SPACE: c = ' '; break;
|
||||||
|
case VK_DELETE: c = 127; break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
c = wParam;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(GetAsyncKeyState(VK_CONTROL) & 0x8000) c |= 0x100;
|
||||||
|
if(GetAsyncKeyState(VK_SHIFT) & 0x8000) c |= 0x200;
|
||||||
|
|
||||||
|
for(int i = 0; SS.GW.menu[i].level >= 0; i++) {
|
||||||
|
if(c == SS.GW.menu[i].accel) {
|
||||||
|
(SS.GW.menu[i].fn)((GraphicsWindow::MenuId)SS.GW.menu[i].id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No accelerator; process the key as normal.
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static HGLRC CreateGlContext(HDC hdc)
|
static HGLRC CreateGlContext(HDC hdc)
|
||||||
{
|
{
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
|
@ -347,6 +389,16 @@ LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||||
SS.GW.MouseScroll(LastMousePos.x, LastMousePos.y, delta);
|
SS.GW.MouseScroll(LastMousePos.x, LastMousePos.y, delta);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case WM_COMMAND: {
|
||||||
|
int id = LOWORD(wParam);
|
||||||
|
for(int i = 0; SS.GW.menu[i].level >= 0; i++) {
|
||||||
|
if(id == SS.GW.menu[i].id) {
|
||||||
|
(SS.GW.menu[i].fn)((GraphicsWindow::MenuId)id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
|
@ -485,6 +537,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||||
MSG msg;
|
MSG msg;
|
||||||
DWORD ret;
|
DWORD ret;
|
||||||
while(ret = GetMessage(&msg, NULL, 0, 0)) {
|
while(ret = GetMessage(&msg, NULL, 0, 0)) {
|
||||||
|
if(msg.message == WM_KEYDOWN) {
|
||||||
|
if(ProcessKeyDown(msg.wParam)) continue;
|
||||||
|
}
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue