Add a toolbar. This requires a tool to convert my PNG icons to
tables in the code, which I have written in perl and am checking in. Also get WM_MOUSELEAVE events from win32, so that I can de-hover everything when the mouse leaves the graphics window. And fix one of the icons, which was 23x24 instead of 24x24. [git-p4: depot-paths = "//depot/solvespace/": change = 1883]solver
parent
3ae0ca8c19
commit
0f228fc0fb
6
Makefile
6
Makefile
|
@ -25,6 +25,7 @@ SSOBJS = $(OBJDIR)\solvespace.obj \
|
||||||
$(OBJDIR)\expr.obj \
|
$(OBJDIR)\expr.obj \
|
||||||
$(OBJDIR)\constraint.obj \
|
$(OBJDIR)\constraint.obj \
|
||||||
$(OBJDIR)\draw.obj \
|
$(OBJDIR)\draw.obj \
|
||||||
|
$(OBJDIR)\toolbar.obj \
|
||||||
$(OBJDIR)\drawconstraint.obj \
|
$(OBJDIR)\drawconstraint.obj \
|
||||||
$(OBJDIR)\file.obj \
|
$(OBJDIR)\file.obj \
|
||||||
$(OBJDIR)\undoredo.obj \
|
$(OBJDIR)\undoredo.obj \
|
||||||
|
@ -67,3 +68,8 @@ $(RES): win32/$(@B).rc icon.ico
|
||||||
rc win32/$(@B).rc
|
rc win32/$(@B).rc
|
||||||
mv win32/$(@B).res $(OBJDIR)/$(@B).res
|
mv win32/$(@B).res $(OBJDIR)/$(@B).res
|
||||||
|
|
||||||
|
toolbar.cpp: $(OBJDIR)/icons.h
|
||||||
|
|
||||||
|
$(OBJDIR)/icons.h: icons/* png2c.pl
|
||||||
|
perl png2c.pl > $(OBJDIR)/icons.h
|
||||||
|
|
||||||
|
|
24
draw.cpp
24
draw.cpp
|
@ -25,6 +25,13 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
|
||||||
shiftDown = !shiftDown;
|
shiftDown = !shiftDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(SS.showToolbar) {
|
||||||
|
if(ToolbarMouseMoved((int)x, (int)y)) {
|
||||||
|
hover.Clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Point2d mp = { x, y };
|
Point2d mp = { x, y };
|
||||||
|
|
||||||
// If the middle button is down, then mouse movement is used to pan and
|
// If the middle button is down, then mouse movement is used to pan and
|
||||||
|
@ -337,6 +344,10 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
if(GraphicsEditControlIsVisible()) return;
|
if(GraphicsEditControlIsVisible()) return;
|
||||||
HideTextEditControl();
|
HideTextEditControl();
|
||||||
|
|
||||||
|
if(SS.showToolbar) {
|
||||||
|
if(ToolbarMouseDown((int)mx, (int)my)) return;
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure the hover is up to date.
|
// Make sure the hover is up to date.
|
||||||
MouseMoved(mx, my, false, false, false, false, false);
|
MouseMoved(mx, my, false, false, false, false, false);
|
||||||
orig.mouse.x = mx;
|
orig.mouse.x = mx;
|
||||||
|
@ -682,6 +693,14 @@ void GraphicsWindow::MouseScroll(double x, double y, int delta) {
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphicsWindow::MouseLeave(void) {
|
||||||
|
// Un-hover everything when the mouse leaves our window.
|
||||||
|
hover.Clear();
|
||||||
|
toolbarTooltipped = 0;
|
||||||
|
toolbarHovered = 0;
|
||||||
|
PaintGraphics();
|
||||||
|
}
|
||||||
|
|
||||||
bool GraphicsWindow::Selection::Equals(Selection *b) {
|
bool GraphicsWindow::Selection::Equals(Selection *b) {
|
||||||
if(entity.v != b->entity.v) return false;
|
if(entity.v != b->entity.v) return false;
|
||||||
if(constraint.v != b->constraint.v) return false;
|
if(constraint.v != b->constraint.v) return false;
|
||||||
|
@ -1006,5 +1025,10 @@ void GraphicsWindow::Paint(int w, int h) {
|
||||||
for(i = 0; i < MAX_SELECTED; i++) {
|
for(i = 0; i < MAX_SELECTED; i++) {
|
||||||
selection[i].Draw();
|
selection[i].Draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// And finally the toolbar.
|
||||||
|
if(SS.showToolbar) {
|
||||||
|
ToolbarDraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
||||||
{ 1, "Nearest &Iso View\tF2", MNU_NEAREST_ISO, F(2), mView },
|
{ 1, "Nearest &Iso View\tF2", MNU_NEAREST_ISO, F(2), mView },
|
||||||
{ 1, NULL, 0, NULL },
|
{ 1, NULL, 0, NULL },
|
||||||
{ 1, "Show Text &Window\tTab", MNU_SHOW_TEXT_WND, '\t', mView },
|
{ 1, "Show Text &Window\tTab", MNU_SHOW_TEXT_WND, '\t', mView },
|
||||||
|
{ 1, "Show &Toolbar", MNU_SHOW_TOOLBAR, 0, mView },
|
||||||
{ 1, NULL, 0, NULL },
|
{ 1, NULL, 0, NULL },
|
||||||
{ 1, "Dimensions in &Inches", MNU_UNITS_INCHES, 0, mView },
|
{ 1, "Dimensions in &Inches", MNU_UNITS_INCHES, 0, mView },
|
||||||
{ 1, "Dimensions in &Millimeters", MNU_UNITS_MM, 0, mView },
|
{ 1, "Dimensions in &Millimeters", MNU_UNITS_MM, 0, mView },
|
||||||
|
@ -395,6 +396,12 @@ void GraphicsWindow::MenuView(int id) {
|
||||||
SS.GW.EnsureValidActives();
|
SS.GW.EnsureValidActives();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MNU_SHOW_TOOLBAR:
|
||||||
|
SS.showToolbar = !SS.showToolbar;
|
||||||
|
SS.GW.EnsureValidActives();
|
||||||
|
PaintGraphics();
|
||||||
|
break;
|
||||||
|
|
||||||
case MNU_UNITS_MM:
|
case MNU_UNITS_MM:
|
||||||
SS.viewUnits = SolveSpace::UNIT_MM;
|
SS.viewUnits = SolveSpace::UNIT_MM;
|
||||||
SS.later.showTW = true;
|
SS.later.showTW = true;
|
||||||
|
@ -475,6 +482,8 @@ void GraphicsWindow::EnsureValidActives(void) {
|
||||||
ShowTextWindow(SS.GW.showTextWindow);
|
ShowTextWindow(SS.GW.showTextWindow);
|
||||||
CheckMenuById(MNU_SHOW_TEXT_WND, SS.GW.showTextWindow);
|
CheckMenuById(MNU_SHOW_TEXT_WND, SS.GW.showTextWindow);
|
||||||
|
|
||||||
|
CheckMenuById(MNU_SHOW_TOOLBAR, SS.showToolbar);
|
||||||
|
|
||||||
if(change) SS.later.showTW = true;
|
if(change) SS.later.showTW = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
@ -0,0 +1,35 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
use GD;
|
||||||
|
|
||||||
|
for $file (<icons/*.png>) {
|
||||||
|
|
||||||
|
$file =~ m#.*/(.*)\.png#;
|
||||||
|
$base = "Icon_$1";
|
||||||
|
$base =~ y/-/_/;
|
||||||
|
|
||||||
|
open(PNG, $file) or die "$file: $!\n";
|
||||||
|
$img = newFromPng GD::Image(\*PNG) or die;
|
||||||
|
$img->trueColor(1);
|
||||||
|
|
||||||
|
close PNG;
|
||||||
|
|
||||||
|
($width, $height) = $img->getBounds();
|
||||||
|
die "$file: $width, $height" if ($width != 24) or ($height != 24);
|
||||||
|
|
||||||
|
print "unsigned char $base\[24*24*3] = {\n";
|
||||||
|
|
||||||
|
for($y = 0; $y < 24; $y++) {
|
||||||
|
for($x = 0; $x < 24; $x++) {
|
||||||
|
$index = $img->getPixel($x, 23-$y);
|
||||||
|
($r, $g, $b) = $img->rgb($index);
|
||||||
|
if($r + $g + $b < 11) {
|
||||||
|
($r, $g, $b) = (30, 30, 30);
|
||||||
|
}
|
||||||
|
printf " 0x%02x, 0x%02x, 0x%02x,\n", $r, $g, $b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print "};\n\n";
|
||||||
|
|
||||||
|
}
|
|
@ -53,6 +53,8 @@ void SolveSpace::Init(char *cmdLine) {
|
||||||
exportOffset = CnfThawFloat(0.0f, "ExportOffset");
|
exportOffset = CnfThawFloat(0.0f, "ExportOffset");
|
||||||
// Draw back faces of triangles (when mesh is leaky/self-intersecting)
|
// Draw back faces of triangles (when mesh is leaky/self-intersecting)
|
||||||
drawBackFaces = CnfThawDWORD(1, "DrawBackFaces");
|
drawBackFaces = CnfThawDWORD(1, "DrawBackFaces");
|
||||||
|
// Show toolbar in the graphics window
|
||||||
|
showToolbar = CnfThawDWORD(1, "ShowToolbar");
|
||||||
// Recent files menus
|
// Recent files menus
|
||||||
for(i = 0; i < MAX_RECENT; i++) {
|
for(i = 0; i < MAX_RECENT; i++) {
|
||||||
char name[100];
|
char name[100];
|
||||||
|
@ -115,6 +117,8 @@ void SolveSpace::Exit(void) {
|
||||||
CnfFreezeFloat(exportOffset, "ExportOffset");
|
CnfFreezeFloat(exportOffset, "ExportOffset");
|
||||||
// Draw back faces of triangles (when mesh is leaky/self-intersecting)
|
// Draw back faces of triangles (when mesh is leaky/self-intersecting)
|
||||||
CnfFreezeDWORD(drawBackFaces, "DrawBackFaces");
|
CnfFreezeDWORD(drawBackFaces, "DrawBackFaces");
|
||||||
|
// Show toolbar in the graphics window
|
||||||
|
CnfFreezeDWORD(showToolbar, "ShowToolbar");
|
||||||
|
|
||||||
ExitNow();
|
ExitNow();
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,8 +99,12 @@ void dbp(char *str, ...);
|
||||||
void SetWindowTitle(char *str);
|
void SetWindowTitle(char *str);
|
||||||
void Message(char *str, ...);
|
void Message(char *str, ...);
|
||||||
void Error(char *str, ...);
|
void Error(char *str, ...);
|
||||||
|
void SetTimerFor(int milliseconds);
|
||||||
void ExitNow(void);
|
void ExitNow(void);
|
||||||
|
|
||||||
|
void DrawWithBitmapFont(char *str);
|
||||||
|
void GetBitmapFontExtent(char *str, int *w, int *h);
|
||||||
|
|
||||||
void CnfFreezeString(char *str, char *name);
|
void CnfFreezeString(char *str, char *name);
|
||||||
void CnfFreezeDWORD(DWORD v, char *name);
|
void CnfFreezeDWORD(DWORD v, char *name);
|
||||||
void CnfFreezeFloat(float v, char *name);
|
void CnfFreezeFloat(float v, char *name);
|
||||||
|
@ -372,6 +376,7 @@ public:
|
||||||
float exportScale;
|
float exportScale;
|
||||||
float exportOffset;
|
float exportOffset;
|
||||||
int drawBackFaces;
|
int drawBackFaces;
|
||||||
|
int showToolbar;
|
||||||
|
|
||||||
int CircleSides(double r);
|
int CircleSides(double r);
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -0,0 +1,263 @@
|
||||||
|
#include "solvespace.h"
|
||||||
|
#include "obj/icons.h"
|
||||||
|
|
||||||
|
BYTE SPACER[1];
|
||||||
|
static const struct {
|
||||||
|
BYTE *image;
|
||||||
|
int menu;
|
||||||
|
char *tip;
|
||||||
|
} Toolbar[] = {
|
||||||
|
{ Icon_line, GraphicsWindow::MNU_LINE_SEGMENT, "Sketch line segment" },
|
||||||
|
{ Icon_rectangle, GraphicsWindow::MNU_RECTANGLE, "Sketch rectangle" },
|
||||||
|
{ Icon_circle, GraphicsWindow::MNU_CIRCLE, "Sketch circle" },
|
||||||
|
{ Icon_arc, GraphicsWindow::MNU_ARC, "Sketch arc, or tangent arc at selected point" },
|
||||||
|
{ Icon_bezier, GraphicsWindow::MNU_CUBIC, "Sketch cubic Bezier section" },
|
||||||
|
{ Icon_point, GraphicsWindow::MNU_DATUM_POINT, "Sketch datum point" },
|
||||||
|
{ Icon_construction, GraphicsWindow::MNU_CONSTRUCTION, "Toggle construction" },
|
||||||
|
{ Icon_trim, GraphicsWindow::MNU_CONSTRUCTION, "Split lines / curves where they intersect" },
|
||||||
|
{ SPACER },
|
||||||
|
|
||||||
|
{ Icon_length, GraphicsWindow::MNU_DISTANCE_DIA, "Constrain distance / diameter / length" },
|
||||||
|
{ Icon_angle, GraphicsWindow::MNU_ANGLE, "Constrain angle" },
|
||||||
|
{ Icon_horiz, GraphicsWindow::MNU_HORIZONTAL, "Constrain to be horizontal" },
|
||||||
|
{ Icon_vert, GraphicsWindow::MNU_VERTICAL, "Constrain to be vertical" },
|
||||||
|
{ Icon_parallel, GraphicsWindow::MNU_PARALLEL, "Constrain to be parallel or tangent" },
|
||||||
|
{ Icon_perpendicular, GraphicsWindow::MNU_PERPENDICULAR, "Constrain to be perpendicular" },
|
||||||
|
{ Icon_pointonx, GraphicsWindow::MNU_ON_ENTITY, "Constrain point on line / curve / plane / face" },
|
||||||
|
{ Icon_symmetric, GraphicsWindow::MNU_SYMMETRIC, "Constrain symmetric" },
|
||||||
|
{ Icon_ref, GraphicsWindow::MNU_REFERENCE, "Toggle reference dimension" },
|
||||||
|
{ SPACER },
|
||||||
|
|
||||||
|
{ Icon_extrude, GraphicsWindow::MNU_GROUP_EXTRUDE, "New group extruding active sketch" },
|
||||||
|
{ Icon_sketch_in_plane, GraphicsWindow::MNU_GROUP_WRKPL, "New group in new workplane (thru given entities)" },
|
||||||
|
{ Icon_sketch_in_3d, GraphicsWindow::MNU_GROUP_3D, "New group in 3d" },
|
||||||
|
{ Icon_assemble, GraphicsWindow::MNU_GROUP_IMPORT, "New group importing / assembling file" },
|
||||||
|
{ SPACER },
|
||||||
|
|
||||||
|
{ Icon_in3d, GraphicsWindow::MNU_FREE_IN_3D, "Sketch / constrain in 3d" },
|
||||||
|
{ Icon_ontoworkplane, GraphicsWindow::MNU_SEL_WORKPLANE, "Sketch / constrain in workplane" },
|
||||||
|
{ NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
void GraphicsWindow::ToolbarDraw(void) {
|
||||||
|
ToolbarDrawOrHitTest(0, 0, true, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GraphicsWindow::ToolbarMouseMoved(int x, int y) {
|
||||||
|
x += ((int)width/2);
|
||||||
|
y += ((int)height/2);
|
||||||
|
|
||||||
|
int nh;
|
||||||
|
bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh);
|
||||||
|
if(!withinToolbar) nh = 0;
|
||||||
|
|
||||||
|
if(nh != toolbarTooltipped) {
|
||||||
|
// Don't let the tool tip move around if the mouse moves within the
|
||||||
|
// same item.
|
||||||
|
toolbarMouseX = x;
|
||||||
|
toolbarMouseY = y;
|
||||||
|
toolbarTooltipped = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nh != toolbarHovered) {
|
||||||
|
toolbarHovered = nh;
|
||||||
|
SetTimerFor(1000);
|
||||||
|
PaintGraphics();
|
||||||
|
}
|
||||||
|
// So if we moved off the toolbar, then toolbarHovered is now equal to
|
||||||
|
// zero, so it doesn't matter if the tool tip timer expires. And if
|
||||||
|
// we moved from one item to another, we reset the timer, so also okay.
|
||||||
|
return withinToolbar;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GraphicsWindow::ToolbarMouseDown(int x, int y) {
|
||||||
|
x += ((int)width/2);
|
||||||
|
y += ((int)height/2);
|
||||||
|
|
||||||
|
int nh;
|
||||||
|
bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh);
|
||||||
|
if(withinToolbar) {
|
||||||
|
for(int i = 0; SS.GW.menu[i].level >= 0; i++) {
|
||||||
|
if(nh == SS.GW.menu[i].id) {
|
||||||
|
(SS.GW.menu[i].fn)((GraphicsWindow::MenuId)SS.GW.menu[i].id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return withinToolbar;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my,
|
||||||
|
bool paint, int *menu)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int x = 17, y = (int)(height - 52);
|
||||||
|
|
||||||
|
int fudge = 8;
|
||||||
|
int h = 32*12 + 3*16 + fudge;
|
||||||
|
int aleft = 0, aright = 66, atop = y+16+fudge/2, abot = y+16-h;
|
||||||
|
|
||||||
|
bool withinToolbar =
|
||||||
|
(mx >= aleft && mx <= aright && my <= atop && my >= abot);
|
||||||
|
|
||||||
|
if(!paint && !withinToolbar) {
|
||||||
|
// This gets called every MouseMove event, so return quickly.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(paint) {
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glTranslated(-1, -1, 0);
|
||||||
|
glScaled(2.0/width, 2.0/height, 0);
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
|
double c = 30.0/255;
|
||||||
|
glColor4d(c, c, c, 1.0);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glVertex2d(aleft, atop);
|
||||||
|
glVertex2d(aleft, abot);
|
||||||
|
glVertex2d(aright, abot);
|
||||||
|
glVertex2d(aright, atop);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool show;
|
||||||
|
char *str;
|
||||||
|
} toolTip = { false, NULL };
|
||||||
|
|
||||||
|
bool leftpos = true;
|
||||||
|
for(i = 0; Toolbar[i].image; i++) {
|
||||||
|
if(Toolbar[i].image == SPACER) {
|
||||||
|
if(!leftpos) {
|
||||||
|
leftpos = true;
|
||||||
|
y -= 32;
|
||||||
|
x -= 32;
|
||||||
|
}
|
||||||
|
y -= 16;
|
||||||
|
|
||||||
|
if(paint) {
|
||||||
|
// Draw a separator bar in a slightly different color.
|
||||||
|
int divw = 30, divh = 2;
|
||||||
|
glColor4d(0.17, 0.17, 0.17, 1);
|
||||||
|
x += 16;
|
||||||
|
y += 24;
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glVertex2d(x+divw, y+divh);
|
||||||
|
glVertex2d(x+divw, y-divh);
|
||||||
|
glVertex2d(x-divw, y-divh);
|
||||||
|
glVertex2d(x-divw, y+divh);
|
||||||
|
glEnd();
|
||||||
|
x -= 16;
|
||||||
|
y -= 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(paint) {
|
||||||
|
glRasterPos2i(x - 12, y - 12);
|
||||||
|
glDrawPixels(24, 24, GL_RGB, GL_UNSIGNED_BYTE, Toolbar[i].image);
|
||||||
|
|
||||||
|
if(toolbarHovered == Toolbar[i].menu) {
|
||||||
|
// Highlight the hovered or pending item.
|
||||||
|
glColor4d(1, 1, 0, 0.3);
|
||||||
|
int boxhw = 15;
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glVertex2d(x+boxhw, y+boxhw);
|
||||||
|
glVertex2d(x+boxhw, y-boxhw);
|
||||||
|
glVertex2d(x-boxhw, y-boxhw);
|
||||||
|
glVertex2d(x-boxhw, y+boxhw);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(toolbarTooltipped == Toolbar[i].menu) {
|
||||||
|
// Display the tool tip for this item; postpone till later
|
||||||
|
// so that no one draws over us. Don't need position since
|
||||||
|
// that's just wherever the mouse is.
|
||||||
|
toolTip.show = true;
|
||||||
|
toolTip.str = Toolbar[i].tip;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int boxhw = 16;
|
||||||
|
if(mx < (x+boxhw) && mx > (x - boxhw) &&
|
||||||
|
my < (y+boxhw) && my > (y - boxhw))
|
||||||
|
{
|
||||||
|
if(menu) *menu = Toolbar[i].menu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(leftpos) {
|
||||||
|
x += 32;
|
||||||
|
leftpos = false;
|
||||||
|
} else {
|
||||||
|
x -= 32;
|
||||||
|
y -= 32;
|
||||||
|
leftpos = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(paint) {
|
||||||
|
// Do this last so that nothing can draw over it.
|
||||||
|
if(toolTip.show) {
|
||||||
|
char str[1024];
|
||||||
|
if(strlen(toolTip.str) >= 200) oops();
|
||||||
|
strcpy(str, toolTip.str);
|
||||||
|
|
||||||
|
for(i = 0; SS.GW.menu[i].level >= 0; i++) {
|
||||||
|
if(toolbarTooltipped == SS.GW.menu[i].id) {
|
||||||
|
int accel = SS.GW.menu[i].accel;
|
||||||
|
int ac = accel & 0xff;
|
||||||
|
if(isalnum(ac) || ac == '[') {
|
||||||
|
char *s = str+strlen(str);
|
||||||
|
if(accel & 0x100) {
|
||||||
|
sprintf(s, " (Shift+%c)", ac);
|
||||||
|
} else if((accel & ~0xff) == 0) {
|
||||||
|
sprintf(s, " (%c)", ac);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int tw, th;
|
||||||
|
GetBitmapFontExtent(str, &tw, &th);
|
||||||
|
tw += 10;
|
||||||
|
th += 2;
|
||||||
|
|
||||||
|
double ox = toolbarMouseX + 3, oy = toolbarMouseY + 3;
|
||||||
|
glColor4d(1.0, 1.0, 0.6, 1.0);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glVertex2d(ox, oy);
|
||||||
|
glVertex2d(ox+tw, oy);
|
||||||
|
glVertex2d(ox+tw, oy+th);
|
||||||
|
glVertex2d(ox, oy+th);
|
||||||
|
glEnd();
|
||||||
|
glColor4d(0.0, 0.0, 0.0, 1.0);
|
||||||
|
glBegin(GL_LINE_LOOP);
|
||||||
|
glVertex2d(ox, oy);
|
||||||
|
glVertex2d(ox+tw, oy);
|
||||||
|
glVertex2d(ox+tw, oy+th);
|
||||||
|
glVertex2d(ox, oy+th);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glColor4d(0, 0, 0, 1);
|
||||||
|
glPushMatrix();
|
||||||
|
glRasterPos2d(ox+6, oy+6);
|
||||||
|
DrawWithBitmapFont(str);
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
glxDepthRangeLockToFront(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return withinToolbar;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphicsWindow::TimerCallback(void) {
|
||||||
|
SS.GW.toolbarTooltipped = SS.GW.toolbarHovered;
|
||||||
|
PaintGraphics();
|
||||||
|
}
|
||||||
|
|
12
ui.h
12
ui.h
|
@ -187,6 +187,7 @@ public:
|
||||||
MNU_NEAREST_ORTHO,
|
MNU_NEAREST_ORTHO,
|
||||||
MNU_NEAREST_ISO,
|
MNU_NEAREST_ISO,
|
||||||
MNU_SHOW_TEXT_WND,
|
MNU_SHOW_TEXT_WND,
|
||||||
|
MNU_SHOW_TOOLBAR,
|
||||||
MNU_UNITS_INCHES,
|
MNU_UNITS_INCHES,
|
||||||
MNU_UNITS_MM,
|
MNU_UNITS_MM,
|
||||||
// Edit
|
// Edit
|
||||||
|
@ -371,6 +372,16 @@ public:
|
||||||
|
|
||||||
void ClearSuper(void);
|
void ClearSuper(void);
|
||||||
|
|
||||||
|
// The toolbar, in toolbar.cpp
|
||||||
|
bool ToolbarDrawOrHitTest(int x, int y, bool paint, int *menu);
|
||||||
|
void ToolbarDraw(void);
|
||||||
|
bool ToolbarMouseMoved(int x, int y);
|
||||||
|
bool ToolbarMouseDown(int x, int y);
|
||||||
|
static void TimerCallback(void);
|
||||||
|
int toolbarHovered;
|
||||||
|
int toolbarTooltipped;
|
||||||
|
int toolbarMouseX, toolbarMouseY;
|
||||||
|
|
||||||
// This sets what gets displayed.
|
// This sets what gets displayed.
|
||||||
bool showWorkplanes;
|
bool showWorkplanes;
|
||||||
bool showNormals;
|
bool showNormals;
|
||||||
|
@ -395,6 +406,7 @@ public:
|
||||||
void MouseLeftDoubleClick(double x, double y);
|
void MouseLeftDoubleClick(double x, double y);
|
||||||
void MouseMiddleOrRightDown(double x, double y);
|
void MouseMiddleOrRightDown(double x, double y);
|
||||||
void MouseScroll(double x, double y, int delta);
|
void MouseScroll(double x, double y, int delta);
|
||||||
|
void MouseLeave(void);
|
||||||
void EditControlDone(char *s);
|
void EditControlDone(char *s);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
#define EDIT_WIDTH 220
|
#define EDIT_WIDTH 220
|
||||||
#define EDIT_HEIGHT 21
|
#define EDIT_HEIGHT 21
|
||||||
|
|
||||||
|
// The list representing glyph with ASCII code zero, for bitmap fonts
|
||||||
|
#define BITMAP_GLYPH_BASE 1000
|
||||||
|
|
||||||
HINSTANCE Instance;
|
HINSTANCE Instance;
|
||||||
|
|
||||||
HWND TextWnd;
|
HWND TextWnd;
|
||||||
|
@ -95,6 +98,27 @@ void Message(char *str, ...)
|
||||||
va_end(f);
|
va_end(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CALLBACK TimerCallback(HWND hwnd, UINT msg, UINT_PTR id, DWORD time)
|
||||||
|
{
|
||||||
|
SS.GW.TimerCallback();
|
||||||
|
}
|
||||||
|
void SetTimerFor(int milliseconds)
|
||||||
|
{
|
||||||
|
SetTimer(GraphicsWnd, 1, milliseconds, TimerCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawWithBitmapFont(char *str)
|
||||||
|
{
|
||||||
|
// These lists were created in CreateGlContext
|
||||||
|
glListBase(BITMAP_GLYPH_BASE);
|
||||||
|
glCallLists(strlen(str), GL_UNSIGNED_BYTE, str);
|
||||||
|
}
|
||||||
|
void GetBitmapFontExtent(char *str, int *w, int *h)
|
||||||
|
{
|
||||||
|
// Easy since that's a fixed-width font for now.
|
||||||
|
*h = TEXT_HEIGHT;
|
||||||
|
*w = TEXT_WIDTH*strlen(str);
|
||||||
|
}
|
||||||
|
|
||||||
void OpenWebsite(char *url) {
|
void OpenWebsite(char *url) {
|
||||||
ShellExecute(GraphicsWnd, "open", url, NULL, NULL, SW_SHOWNORMAL);
|
ShellExecute(GraphicsWnd, "open", url, NULL, NULL, SW_SHOWNORMAL);
|
||||||
|
@ -598,6 +622,10 @@ static void CreateGlContext(void)
|
||||||
|
|
||||||
GraphicsHpgl = wglCreateContext(hdc);
|
GraphicsHpgl = wglCreateContext(hdc);
|
||||||
wglMakeCurrent(hdc, GraphicsHpgl);
|
wglMakeCurrent(hdc, GraphicsHpgl);
|
||||||
|
|
||||||
|
// Create a bitmap font in a display list, for DrawWithBitmapFont().
|
||||||
|
SelectObject(hdc, FixedFont);
|
||||||
|
wglUseFontBitmaps(hdc, 0, 255, BITMAP_GLYPH_BASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InvalidateGraphics(void)
|
void InvalidateGraphics(void)
|
||||||
|
@ -702,6 +730,10 @@ LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_MOUSELEAVE:
|
||||||
|
SS.GW.MouseLeave();
|
||||||
|
break;
|
||||||
|
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
case WM_LBUTTONUP:
|
case WM_LBUTTONUP:
|
||||||
|
@ -711,6 +743,15 @@ LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||||
int x = LOWORD(lParam);
|
int x = LOWORD(lParam);
|
||||||
int y = HIWORD(lParam);
|
int y = HIWORD(lParam);
|
||||||
|
|
||||||
|
// We need this in order to get the WM_MOUSELEAVE
|
||||||
|
TRACKMOUSEEVENT tme;
|
||||||
|
ZERO(&tme);
|
||||||
|
tme.cbSize = sizeof(tme);
|
||||||
|
tme.dwFlags = TME_LEAVE;
|
||||||
|
tme.hwndTrack = GraphicsWnd;
|
||||||
|
TrackMouseEvent(&tme);
|
||||||
|
|
||||||
|
// Convert to xy (vs. ij) style coordinates, with (0, 0) at center
|
||||||
RECT r;
|
RECT r;
|
||||||
GetClientRect(GraphicsWnd, &r);
|
GetClientRect(GraphicsWnd, &r);
|
||||||
x = x - (r.right - r.left)/2;
|
x = x - (r.right - r.left)/2;
|
||||||
|
|
Loading…
Reference in New Issue