Add ability to assign styles to cosmetic text (in the form of
Constraint::COMMENTs), including line width and color, and text height and origin location. [git-p4: depot-paths = "//depot/solvespace/": change = 2033]
This commit is contained in:
parent
9416faca88
commit
4634961054
@ -654,10 +654,9 @@ void Constraint::MenuConstrain(int id) {
|
||||
break;
|
||||
|
||||
case GraphicsWindow::MNU_COMMENT:
|
||||
c.type = COMMENT;
|
||||
c.comment.strcpy("NEW COMMENT -- DOUBLE-CLICK TO EDIT");
|
||||
c.disp.offset = SS.GW.offset.ScaledBy(-1);
|
||||
AddConstraint(&c);
|
||||
SS.GW.pending.operation = GraphicsWindow::MNU_COMMENT;
|
||||
SS.GW.pending.description = "click center of comment text";
|
||||
SS.later.showTW = true;
|
||||
break;
|
||||
|
||||
default: oops();
|
||||
|
72
draw.cpp
72
draw.cpp
@ -409,17 +409,18 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
||||
// selection.
|
||||
bool toggleForStyles = false,
|
||||
toggleForGroupInfo = false,
|
||||
toggleForDelete = false;
|
||||
toggleForDelete = false,
|
||||
toggleForStyleInfo = false;
|
||||
|
||||
if(!hover.IsEmpty()) {
|
||||
AddContextMenuItem("Toggle Hovered Item Selection",
|
||||
CMNU_TOGGLE_SELECTION);
|
||||
}
|
||||
|
||||
if(gs.entities > 0) {
|
||||
if(gs.stylables > 0) {
|
||||
ContextMenuListStyles();
|
||||
AddContextMenuItem("Assign Selection to Style", CONTEXT_SUBMENU);
|
||||
} else if(hover.entity.v && gs.n == 0 && gs.constraints == 0) {
|
||||
} else if(gs.n == 0 && gs.constraints == 0 && hover.IsStylable()) {
|
||||
ContextMenuListStyles();
|
||||
AddContextMenuItem("Assign Hovered Item to Style", CONTEXT_SUBMENU);
|
||||
toggleForStyles = true;
|
||||
@ -432,9 +433,16 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
||||
toggleForGroupInfo = true;
|
||||
}
|
||||
|
||||
if(gs.n + gs.constraints == 1 && gs.stylables == 1) {
|
||||
AddContextMenuItem("Style Info for Selected Item", CMNU_STYLE_INFO);
|
||||
} else if(hover.IsStylable() && gs.n == 0 && gs.constraints == 0) {
|
||||
AddContextMenuItem("Style Info for Hovered Item", CMNU_STYLE_INFO);
|
||||
toggleForStyleInfo = true;
|
||||
}
|
||||
|
||||
if(hover.constraint.v && gs.n == 0 && gs.constraints == 0) {
|
||||
Constraint *c = SK.GetConstraint(hover.constraint);
|
||||
if(c->HasLabel()) {
|
||||
if(c->HasLabel() && c->type != Constraint::COMMENT) {
|
||||
AddContextMenuItem("Toggle Reference Dimension",
|
||||
CMNU_REFERENCE_DIM);
|
||||
}
|
||||
@ -483,8 +491,9 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
||||
|
||||
case CMNU_GROUP_INFO: {
|
||||
if(toggleForGroupInfo) ToggleSelectionStateOfHovered();
|
||||
GroupSelection();
|
||||
|
||||
hGroup hg;
|
||||
GroupSelection();
|
||||
if(gs.entities == 1) {
|
||||
hg = SK.GetEntity(gs.entity[0])->group;
|
||||
} else if(gs.points == 1) {
|
||||
@ -495,12 +504,36 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
||||
break;
|
||||
}
|
||||
ClearSelection();
|
||||
|
||||
SS.TW.GoToScreen(TextWindow::SCREEN_GROUP_INFO);
|
||||
SS.TW.shown.group = hg;
|
||||
SS.later.showTW = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case CMNU_STYLE_INFO: {
|
||||
if(toggleForStyleInfo) ToggleSelectionStateOfHovered();
|
||||
|
||||
hStyle hs;
|
||||
GroupSelection();
|
||||
if(gs.entities == 1) {
|
||||
hs = Style::ForEntity(gs.entity[0]);
|
||||
} else if(gs.points == 1) {
|
||||
hs = Style::ForEntity(gs.point[0]);
|
||||
} else if(gs.constraints == 1) {
|
||||
hs = SK.GetConstraint(gs.constraint[0])->disp.style;
|
||||
if(!hs.v) hs.v = Style::CONSTRAINT;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
ClearSelection();
|
||||
|
||||
SS.TW.GoToScreen(TextWindow::SCREEN_STYLE_INFO);
|
||||
SS.TW.shown.style = hs;
|
||||
SS.later.showTW = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case CMNU_NEW_CUSTOM_STYLE: {
|
||||
if(toggleForStyles) ToggleSelectionStateOfHovered();
|
||||
DWORD v = Style::CreateCustomStyle();
|
||||
@ -602,8 +635,6 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||
ConstrainPointByHovered(hr.entity(0));
|
||||
|
||||
ClearSuper();
|
||||
|
||||
pending.operation = 0;
|
||||
break;
|
||||
|
||||
case MNU_LINE_SEGMENT:
|
||||
@ -738,6 +769,19 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||
break;
|
||||
}
|
||||
|
||||
case MNU_COMMENT: {
|
||||
ClearSuper();
|
||||
Constraint c;
|
||||
ZERO(&c);
|
||||
c.group = SS.GW.activeGroup;
|
||||
c.workplane = SS.GW.ActiveWorkplane();
|
||||
c.type = Constraint::COMMENT;
|
||||
c.disp.offset = v;
|
||||
c.comment.strcpy("NEW COMMENT -- DOUBLE-CLICK TO EDIT");
|
||||
Constraint::AddConstraint(&c);
|
||||
break;
|
||||
}
|
||||
|
||||
case DRAGGING_RADIUS:
|
||||
case DRAGGING_NEW_POINT:
|
||||
// The MouseMoved event has already dragged it as desired.
|
||||
@ -925,6 +969,15 @@ bool GraphicsWindow::Selection::IsEmpty(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GraphicsWindow::Selection::IsStylable(void) {
|
||||
if(entity.v) return true;
|
||||
if(constraint.v) {
|
||||
Constraint *c = SK.GetConstraint(constraint);
|
||||
if(c->type == Constraint::COMMENT) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GraphicsWindow::Selection::Clear(void) {
|
||||
entity.v = constraint.v = 0;
|
||||
emphasized = false;
|
||||
@ -1045,6 +1098,7 @@ void GraphicsWindow::GroupSelection(void) {
|
||||
gs.point[(gs.points)++] = s->entity;
|
||||
} else {
|
||||
gs.entity[(gs.entities)++] = s->entity;
|
||||
(gs.stylables)++;
|
||||
}
|
||||
|
||||
// And an auxiliary list of normals, including normals from
|
||||
@ -1081,6 +1135,10 @@ void GraphicsWindow::GroupSelection(void) {
|
||||
}
|
||||
if(s->constraint.v) {
|
||||
gs.constraint[(gs.constraints)++] = s->constraint;
|
||||
Constraint *c = SK.GetConstraint(s->constraint);
|
||||
if(c->type == Constraint::COMMENT) {
|
||||
(gs.stylables)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,13 +19,26 @@ bool Constraint::HasLabel(void) {
|
||||
|
||||
void Constraint::LineDrawOrGetDistance(Vector a, Vector b) {
|
||||
if(dogd.drawing) {
|
||||
if(dogd.sel) {
|
||||
dogd.sel->AddEdge(a, b, Style::CONSTRAINT);
|
||||
// Draw comments in the specified style, but everything else in the
|
||||
// default style for constraints.
|
||||
hStyle hs;
|
||||
if(type == COMMENT && disp.style.v) {
|
||||
hs = disp.style;
|
||||
} else {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glxVertex3v(a);
|
||||
glxVertex3v(b);
|
||||
glEnd();
|
||||
hs.v = Style::CONSTRAINT;
|
||||
}
|
||||
|
||||
if(dogd.sel) {
|
||||
dogd.sel->AddEdge(a, b, hs.v);
|
||||
} else {
|
||||
if(hs.v && Style::Width(disp.style) >= 3.0) {
|
||||
glxFatLine(a, b, Style::Width(disp.style) / SS.GW.scale);
|
||||
} else {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glxVertex3v(a);
|
||||
glxVertex3v(b);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Point2d ap = SS.GW.ProjectPoint(a);
|
||||
@ -70,8 +83,28 @@ char *Constraint::Label(void) {
|
||||
}
|
||||
|
||||
void Constraint::DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu) {
|
||||
double th;
|
||||
if(type == COMMENT) {
|
||||
th = Style::TextHeight(disp.style);
|
||||
} else {
|
||||
th = DEFAULT_TEXT_HEIGHT;
|
||||
}
|
||||
|
||||
char *s = Label();
|
||||
double swidth = glxStrWidth(s), sheight = glxStrHeight();
|
||||
double swidth = glxStrWidth(s, th),
|
||||
sheight = glxStrHeight(th);
|
||||
|
||||
// By default, the reference is from the center; but the style could
|
||||
// specify otherwise if one is present.
|
||||
if(type == COMMENT && disp.style.v) {
|
||||
Style *s = Style::Get(disp.style);
|
||||
int o = s->textOrigin;
|
||||
if(o & Style::ORIGIN_LEFT) ref = ref.Plus(gr.WithMagnitude(swidth/2));
|
||||
if(o & Style::ORIGIN_RIGHT) ref = ref.Minus(gr.WithMagnitude(swidth/2));
|
||||
if(o & Style::ORIGIN_BOT) ref = ref.Plus(gu.WithMagnitude(sheight/2));
|
||||
if(o & Style::ORIGIN_TOP) ref = ref.Minus(gu.WithMagnitude(sheight/2));
|
||||
}
|
||||
|
||||
if(labelPos) {
|
||||
// labelPos is from the top left corner (for the text box used to
|
||||
// edit things), but ref is from the center.
|
||||
@ -79,8 +112,9 @@ void Constraint::DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu) {
|
||||
gu.WithMagnitude(sheight/2));
|
||||
}
|
||||
|
||||
|
||||
if(dogd.drawing) {
|
||||
glxWriteTextRefCenter(s, ref, gr, gu, LineCallback, this);
|
||||
glxWriteTextRefCenter(s, th, ref, gr, gu, LineCallback, this);
|
||||
} else {
|
||||
double l = swidth/2 - sheight/2;
|
||||
l = max(l, 5/SS.GW.scale);
|
||||
@ -88,7 +122,7 @@ void Constraint::DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu) {
|
||||
Point2d b = SS.GW.ProjectPoint(ref.Plus (gr.WithMagnitude(l)));
|
||||
double d = dogd.mp.DistanceToLine(a, b.Minus(a), true);
|
||||
|
||||
dogd.dmin = min(dogd.dmin, d - 3);
|
||||
dogd.dmin = min(dogd.dmin, d - (th / 2));
|
||||
dogd.refp = ref;
|
||||
}
|
||||
}
|
||||
@ -116,8 +150,8 @@ int Constraint::DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b) {
|
||||
|
||||
double pixels = 1.0 / SS.GW.scale;
|
||||
char *s = Label();
|
||||
double swidth = glxStrWidth(s) + 4*pixels,
|
||||
sheight = glxStrHeight() + 8*pixels;
|
||||
double swidth = glxStrWidth(s, DEFAULT_TEXT_HEIGHT) + 4*pixels,
|
||||
sheight = glxStrHeight(DEFAULT_TEXT_HEIGHT) + 8*pixels;
|
||||
|
||||
struct {
|
||||
Vector n;
|
||||
@ -322,15 +356,18 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
|
||||
// complex and this looks pretty good.
|
||||
double tl = atan2(rm.Dot(gu), rm.Dot(gr));
|
||||
double adj = EllipticalInterpolation(
|
||||
glxStrWidth(Label())/2, glxStrHeight()/2, tl);
|
||||
glxStrWidth(Label(), DEFAULT_TEXT_HEIGHT)/2,
|
||||
glxStrHeight(DEFAULT_TEXT_HEIGHT)/2,
|
||||
tl);
|
||||
*ref = (*ref).Plus(rm.WithMagnitude(adj + 3/SS.GW.scale));
|
||||
} else {
|
||||
// The lines are skew; no wonderful way to illustrate that.
|
||||
*ref = a0.Plus(b0);
|
||||
*ref = (*ref).ScaledBy(0.5).Plus(disp.offset);
|
||||
gu = gu.WithMagnitude(1);
|
||||
Vector trans = (*ref).Plus(gu.ScaledBy(-1.5*glxStrHeight()));
|
||||
glxWriteTextRefCenter("angle between skew lines",
|
||||
Vector trans =
|
||||
(*ref).Plus(gu.ScaledBy(-1.5*glxStrHeight(DEFAULT_TEXT_HEIGHT)));
|
||||
glxWriteTextRefCenter("angle between skew lines", DEFAULT_TEXT_HEIGHT,
|
||||
trans, gr, gu, LineCallback, this);
|
||||
}
|
||||
}
|
||||
@ -653,7 +690,8 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
||||
}
|
||||
|
||||
if(dogd.drawing) {
|
||||
glxWriteTextRefCenter("T", textAt, u, v, LineCallback, this);
|
||||
glxWriteTextRefCenter("T", DEFAULT_TEXT_HEIGHT,
|
||||
textAt, u, v, LineCallback, this);
|
||||
} else {
|
||||
dogd.refp = textAt;
|
||||
Point2d ref = SS.GW.ProjectPoint(dogd.refp);
|
||||
@ -835,8 +873,8 @@ s:
|
||||
(type == VERTICAL) ? "V" : (
|
||||
(type == AT_MIDPOINT) ? "M" : NULL));
|
||||
|
||||
glxWriteTextRefCenter(s, m.Plus(offset), r, u,
|
||||
LineCallback, this);
|
||||
glxWriteTextRefCenter(s, DEFAULT_TEXT_HEIGHT,
|
||||
m.Plus(offset), r, u, LineCallback, this);
|
||||
} else {
|
||||
dogd.refp = m.Plus(offset);
|
||||
Point2d ref = SS.GW.ProjectPoint(dogd.refp);
|
||||
@ -880,6 +918,10 @@ s:
|
||||
break;
|
||||
|
||||
case COMMENT:
|
||||
if(disp.style.v) {
|
||||
glLineWidth(Style::Width(disp.style));
|
||||
glxColorRGB(Style::Color(disp.style));
|
||||
}
|
||||
DoLabel(disp.offset, labelPos, gr, gu);
|
||||
break;
|
||||
|
||||
|
@ -10,55 +10,6 @@ char *Entity::DescriptionString(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::FatLineEndcap(Vector p, Vector u, Vector v) {
|
||||
// A table of cos and sin of (pi*i/10 + pi/2), as i goes from 0 to 10
|
||||
static const double Circle[11][2] = {
|
||||
{ 0.0000, 1.0000 },
|
||||
{ -0.3090, 0.9511 },
|
||||
{ -0.5878, 0.8090 },
|
||||
{ -0.8090, 0.5878 },
|
||||
{ -0.9511, 0.3090 },
|
||||
{ -1.0000, 0.0000 },
|
||||
{ -0.9511, -0.3090 },
|
||||
{ -0.8090, -0.5878 },
|
||||
{ -0.5878, -0.8090 },
|
||||
{ -0.3090, -0.9511 },
|
||||
{ 0.0000, -1.0000 },
|
||||
};
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
for(int i = 0; i <= 10; i++) {
|
||||
double c = Circle[i][0], s = Circle[i][1];
|
||||
glxVertex3v(p.Plus(u.ScaledBy(c)).Plus(v.ScaledBy(s)));
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void Entity::FatLine(Vector a, Vector b) {
|
||||
// The half-width of the line we're drawing.
|
||||
double hw = (dogd.lineWidth/SS.GW.scale) / 2;
|
||||
Vector ab = b.Minus(a);
|
||||
Vector gn = (SS.GW.projRight).Cross(SS.GW.projUp);
|
||||
Vector abn = (ab.Cross(gn)).WithMagnitude(1);
|
||||
abn = abn.Minus(gn.ScaledBy(gn.Dot(abn)));
|
||||
// So now abn is normal to the projection of ab into the screen, so the
|
||||
// line will always have constant thickness as the view is rotated.
|
||||
|
||||
abn = abn.WithMagnitude(hw);
|
||||
ab = gn.Cross(abn);
|
||||
ab = ab. WithMagnitude(hw);
|
||||
|
||||
// The body of a line is a quad
|
||||
glBegin(GL_QUADS);
|
||||
glxVertex3v(a.Minus(abn));
|
||||
glxVertex3v(b.Minus(abn));
|
||||
glxVertex3v(b.Plus (abn));
|
||||
glxVertex3v(a.Plus (abn));
|
||||
glEnd();
|
||||
// And the line has two semi-circular end caps.
|
||||
FatLineEndcap(a, ab, abn);
|
||||
FatLineEndcap(b, ab.ScaledBy(-1), abn);
|
||||
}
|
||||
|
||||
void Entity::LineDrawOrGetDistance(Vector a, Vector b, bool maybeFat) {
|
||||
if(dogd.drawing) {
|
||||
// Draw lines from active group in front of those from previous
|
||||
@ -71,7 +22,7 @@ void Entity::LineDrawOrGetDistance(Vector a, Vector b, bool maybeFat) {
|
||||
glxVertex3v(b);
|
||||
glEnd();
|
||||
} else {
|
||||
FatLine(a, b);
|
||||
glxFatLine(a, b, dogd.lineWidth/SS.GW.scale);
|
||||
}
|
||||
|
||||
glxDepthRangeOffset(0);
|
||||
@ -506,11 +457,12 @@ void Entity::DrawOrGetDistance(void) {
|
||||
glDisable(GL_LINE_STIPPLE);
|
||||
|
||||
char *str = DescriptionString()+5;
|
||||
double th = DEFAULT_TEXT_HEIGHT;
|
||||
if(dogd.drawing) {
|
||||
glxWriteText(str, mm2, u, v, NULL, NULL);
|
||||
glxWriteText(str, th, mm2, u, v, NULL, NULL);
|
||||
} else {
|
||||
Vector pos = mm2.Plus(u.ScaledBy(glxStrWidth(str)/2)).Plus(
|
||||
v.ScaledBy(glxStrHeight()/2));
|
||||
Vector pos = mm2.Plus(u.ScaledBy(glxStrWidth(str, th)/2)).Plus(
|
||||
v.ScaledBy(glxStrHeight(th)/2));
|
||||
Point2d pp = SS.GW.ProjectPoint(pos);
|
||||
dogd.dmin = min(dogd.dmin, pp.DistanceTo(dogd.mp) - 10);
|
||||
// If a line lies in a plane, then select the line, not
|
||||
|
7
file.cpp
7
file.cpp
@ -154,7 +154,10 @@ const SolveSpace::SaveTable SolveSpace::SAVED[] = {
|
||||
{ 's', "Style.h.v", 'x', &(SS.sv.s.h.v) },
|
||||
{ 's', "Style.name", 'N', &(SS.sv.s.name) },
|
||||
{ 's', "Style.width", 'f', &(SS.sv.s.width) },
|
||||
{ 's', "Style.widthHow", 'd', &(SS.sv.s.widthHow) },
|
||||
{ 's', "Style.widthAs", 'd', &(SS.sv.s.widthAs) },
|
||||
{ 's', "Style.textHeight", 'f', &(SS.sv.s.textHeight) },
|
||||
{ 's', "Style.textHeightAs", 'd', &(SS.sv.s.textHeightAs) },
|
||||
{ 's', "Style.textOrigin", 'x', &(SS.sv.s.textOrigin) },
|
||||
{ 's', "Style.color", 'x', &(SS.sv.s.color) },
|
||||
{ 's', "Style.visible", 'b', &(SS.sv.s.visible) },
|
||||
{ 's', "Style.exportable", 'b', &(SS.sv.s.exportable) },
|
||||
@ -484,6 +487,8 @@ bool SolveSpace::LoadEntitiesFromFile(char *file, EntityList *le,
|
||||
|
||||
} else if(strcmp(line, "AddConstraint")==0) {
|
||||
|
||||
} else if(strcmp(line, "AddStyle")==0) {
|
||||
|
||||
} else if(strcmp(line, VERSION_STRING)==0) {
|
||||
|
||||
} else if(StrStartsWith(line, "Triangle ")) {
|
||||
|
77
glhelper.cpp
77
glhelper.cpp
@ -6,8 +6,8 @@
|
||||
static bool ColorLocked;
|
||||
static bool DepthOffsetLocked;
|
||||
|
||||
#define FONT_SCALE (0.55)
|
||||
double glxStrWidth(char *str) {
|
||||
#define FONT_SCALE(h) ((h)/22.0)
|
||||
double glxStrWidth(char *str, double h) {
|
||||
int w = 0;
|
||||
for(; *str; str++) {
|
||||
int c = *str;
|
||||
@ -16,21 +16,21 @@ double glxStrWidth(char *str) {
|
||||
|
||||
w += Font[c].width;
|
||||
}
|
||||
return w*FONT_SCALE/SS.GW.scale;
|
||||
return w*FONT_SCALE(h)/SS.GW.scale;
|
||||
}
|
||||
double glxStrHeight(void) {
|
||||
// The characters have height ~21, as they appear in the table.
|
||||
return 21.0*FONT_SCALE/SS.GW.scale;
|
||||
double glxStrHeight(double h) {
|
||||
// The characters have height ~22, as they appear in the table.
|
||||
return 22.0*FONT_SCALE(h)/SS.GW.scale;
|
||||
}
|
||||
void glxWriteTextRefCenter(char *str, Vector t, Vector u, Vector v,
|
||||
void glxWriteTextRefCenter(char *str, double h, Vector t, Vector u, Vector v,
|
||||
glxLineFn *fn, void *fndata)
|
||||
{
|
||||
u = u.WithMagnitude(1);
|
||||
v = v.WithMagnitude(1);
|
||||
|
||||
double scale = FONT_SCALE/SS.GW.scale;
|
||||
double fh = glxStrHeight();
|
||||
double fw = glxStrWidth(str);
|
||||
double scale = FONT_SCALE(h)/SS.GW.scale;
|
||||
double fh = glxStrHeight(h);
|
||||
double fw = glxStrWidth(str, h);
|
||||
|
||||
t = t.Plus(u.ScaledBy(-fw/2));
|
||||
t = t.Plus(v.ScaledBy(-fh/2));
|
||||
@ -39,7 +39,7 @@ void glxWriteTextRefCenter(char *str, Vector t, Vector u, Vector v,
|
||||
t = t.Plus(u.ScaledBy(-5*scale));
|
||||
t = t.Plus(v.ScaledBy(-5*scale));
|
||||
|
||||
glxWriteText(str, t, u, v, fn, fndata);
|
||||
glxWriteText(str, h, t, u, v, fn, fndata);
|
||||
}
|
||||
|
||||
static void LineDrawCallback(void *fndata, Vector a, Vector b)
|
||||
@ -51,14 +51,14 @@ static void LineDrawCallback(void *fndata, Vector a, Vector b)
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void glxWriteText(char *str, Vector t, Vector u, Vector v,
|
||||
void glxWriteText(char *str, double h, Vector t, Vector u, Vector v,
|
||||
glxLineFn *fn, void *fndata)
|
||||
{
|
||||
if(!fn) fn = LineDrawCallback;
|
||||
u = u.WithMagnitude(1);
|
||||
v = v.WithMagnitude(1);
|
||||
|
||||
double scale = FONT_SCALE/SS.GW.scale;
|
||||
double scale = FONT_SCALE(h)/SS.GW.scale;
|
||||
int xo = 5;
|
||||
int yo = 5;
|
||||
|
||||
@ -96,6 +96,57 @@ void glxVertex3v(Vector u)
|
||||
glVertex3f((GLfloat)u.x, (GLfloat)u.y, (GLfloat)u.z);
|
||||
}
|
||||
|
||||
static void FatLineEndcap(Vector p, Vector u, Vector v)
|
||||
{
|
||||
// A table of cos and sin of (pi*i/10 + pi/2), as i goes from 0 to 10
|
||||
static const double Circle[11][2] = {
|
||||
{ 0.0000, 1.0000 },
|
||||
{ -0.3090, 0.9511 },
|
||||
{ -0.5878, 0.8090 },
|
||||
{ -0.8090, 0.5878 },
|
||||
{ -0.9511, 0.3090 },
|
||||
{ -1.0000, 0.0000 },
|
||||
{ -0.9511, -0.3090 },
|
||||
{ -0.8090, -0.5878 },
|
||||
{ -0.5878, -0.8090 },
|
||||
{ -0.3090, -0.9511 },
|
||||
{ 0.0000, -1.0000 },
|
||||
};
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
for(int i = 0; i <= 10; i++) {
|
||||
double c = Circle[i][0], s = Circle[i][1];
|
||||
glxVertex3v(p.Plus(u.ScaledBy(c)).Plus(v.ScaledBy(s)));
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void glxFatLine(Vector a, Vector b, double width) {
|
||||
// The half-width of the line we're drawing.
|
||||
double hw = width / 2;
|
||||
Vector ab = b.Minus(a);
|
||||
Vector gn = (SS.GW.projRight).Cross(SS.GW.projUp);
|
||||
Vector abn = (ab.Cross(gn)).WithMagnitude(1);
|
||||
abn = abn.Minus(gn.ScaledBy(gn.Dot(abn)));
|
||||
// So now abn is normal to the projection of ab into the screen, so the
|
||||
// line will always have constant thickness as the view is rotated.
|
||||
|
||||
abn = abn.WithMagnitude(hw);
|
||||
ab = gn.Cross(abn);
|
||||
ab = ab. WithMagnitude(hw);
|
||||
|
||||
// The body of a line is a quad
|
||||
glBegin(GL_QUADS);
|
||||
glxVertex3v(a.Minus(abn));
|
||||
glxVertex3v(b.Minus(abn));
|
||||
glxVertex3v(b.Plus (abn));
|
||||
glxVertex3v(a.Plus (abn));
|
||||
glEnd();
|
||||
// And the line has two semi-circular end caps.
|
||||
FatLineEndcap(a, ab, abn);
|
||||
FatLineEndcap(b, ab.ScaledBy(-1), abn);
|
||||
}
|
||||
|
||||
|
||||
void glxLockColorTo(DWORD rgb)
|
||||
{
|
||||
ColorLocked = false;
|
||||
|
@ -591,7 +591,9 @@ void GraphicsWindow::MenuEdit(int id) {
|
||||
// to cancel, then perhaps they want to return to the home
|
||||
// screen in the text window.
|
||||
if(SS.GW.gs.n == 0 && SS.GW.pending.operation == 0) {
|
||||
if(!TextEditControlIsVisible()) {
|
||||
if(!(TextEditControlIsVisible() ||
|
||||
GraphicsEditControlIsVisible()))
|
||||
{
|
||||
if(SS.TW.shown.screen == TextWindow::SCREEN_STYLE_INFO) {
|
||||
SS.TW.GoToScreen(TextWindow::SCREEN_LIST_OF_STYLES);
|
||||
} else {
|
||||
|
@ -424,7 +424,7 @@ void Group::Draw(void) {
|
||||
glxVertex3v(polyError.notClosedAt.b);
|
||||
glEnd();
|
||||
glxColorRGB(Style::Color(Style::DRAW_ERROR));
|
||||
glxWriteText("not closed contour!",
|
||||
glxWriteText("not closed contour!", DEFAULT_TEXT_HEIGHT,
|
||||
polyError.notClosedAt.b, SS.GW.projRight, SS.GW.projUp,
|
||||
NULL, NULL);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
@ -439,7 +439,7 @@ void Group::Draw(void) {
|
||||
char *msg = (polyError.how == POLY_NOT_COPLANAR) ?
|
||||
"points not all coplanar!" :
|
||||
"contour is self-intersecting!";
|
||||
glxWriteText(msg,
|
||||
glxWriteText(msg, DEFAULT_TEXT_HEIGHT,
|
||||
polyError.errorPointAt, SS.GW.projRight, SS.GW.projUp,
|
||||
NULL, NULL);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
16
sketch.h
16
sketch.h
@ -415,8 +415,6 @@ public:
|
||||
Vector refp;
|
||||
double lineWidth;
|
||||
} dogd; // state for drawing or getting distance (for hit testing)
|
||||
void FatLine(Vector a, Vector b);
|
||||
void FatLineEndcap(Vector p, Vector u, Vector v);
|
||||
void LineDrawOrGetDistance(Vector a, Vector b, bool maybeFat=false);
|
||||
void DrawOrGetDistance(void);
|
||||
|
||||
@ -626,10 +624,17 @@ public:
|
||||
|
||||
NameStr name;
|
||||
|
||||
static const int WIDTH_AS_MM = 0;
|
||||
static const int WIDTH_AS_PIXELS = 1;
|
||||
static const int UNITS_AS_PIXELS = 0;
|
||||
static const int UNITS_AS_MM = 1;
|
||||
double width;
|
||||
int widthHow;
|
||||
int widthAs;
|
||||
double textHeight;
|
||||
int textHeightAs;
|
||||
static const int ORIGIN_LEFT = 0x01;
|
||||
static const int ORIGIN_RIGHT = 0x02;
|
||||
static const int ORIGIN_BOT = 0x04;
|
||||
static const int ORIGIN_TOP = 0x08;
|
||||
int textOrigin;
|
||||
DWORD color;
|
||||
bool visible;
|
||||
bool exportable;
|
||||
@ -662,6 +667,7 @@ public:
|
||||
static DWORD Color(int hs, bool forExport=false);
|
||||
static float Width(int hs);
|
||||
static double WidthMm(int hs);
|
||||
static double TextHeight(hStyle hs);
|
||||
static bool Exportable(int hs);
|
||||
static hStyle ForEntity(hEntity he);
|
||||
|
||||
|
10
solvespace.h
10
solvespace.h
@ -181,6 +181,7 @@ typedef IdList<Param,hParam> ParamList;
|
||||
|
||||
// Utility functions that are provided in the platform-independent code.
|
||||
void glxVertex3v(Vector u);
|
||||
#define DEFAULT_TEXT_HEIGHT (11.5)
|
||||
#define GLX_CALLBACK __stdcall
|
||||
typedef void GLX_CALLBACK glxCallbackFptr(void);
|
||||
void glxTesselatePolygon(GLUtesselator *gt, SPolygon *p);
|
||||
@ -191,13 +192,14 @@ void glxDrawEdges(SEdgeList *l, bool endpointsToo);
|
||||
void glxDebugMesh(SMesh *m);
|
||||
void glxMarkPolygonNormal(SPolygon *p);
|
||||
typedef void glxLineFn(void *data, Vector a, Vector b);
|
||||
void glxWriteText(char *str, Vector t, Vector u, Vector v,
|
||||
void glxWriteText(char *str, double h, Vector t, Vector u, Vector v,
|
||||
glxLineFn *fn, void *fndata);
|
||||
void glxWriteTextRefCenter(char *str, Vector t, Vector u, Vector v,
|
||||
void glxWriteTextRefCenter(char *str, double h, Vector t, Vector u, Vector v,
|
||||
glxLineFn *fn, void *fndata);
|
||||
double glxStrWidth(char *str);
|
||||
double glxStrHeight(void);
|
||||
double glxStrWidth(char *str, double h);
|
||||
double glxStrHeight(double h);
|
||||
void glxLockColorTo(DWORD rgb);
|
||||
void glxFatLine(Vector a, Vector b, double width);
|
||||
void glxUnlockColor(void);
|
||||
void glxColorRGB(DWORD rgb);
|
||||
void glxColorRGBa(DWORD rgb, double a);
|
||||
|
260
style.cpp
260
style.cpp
@ -68,12 +68,14 @@ void Style::CreateDefaultStyle(hStyle h) {
|
||||
|
||||
Style ns;
|
||||
ZERO(&ns);
|
||||
ns.color = CnfThawDWORD(d->color, CnfColor(d->cnfPrefix));
|
||||
ns.width = CnfThawFloat((float)(d->width), CnfWidth(d->cnfPrefix));
|
||||
ns.widthHow = WIDTH_AS_PIXELS;
|
||||
ns.visible = true;
|
||||
ns.exportable = true;
|
||||
ns.h = h;
|
||||
ns.color = CnfThawDWORD(d->color, CnfColor(d->cnfPrefix));
|
||||
ns.width = CnfThawFloat((float)(d->width), CnfWidth(d->cnfPrefix));
|
||||
ns.widthAs = UNITS_AS_PIXELS;
|
||||
ns.textHeight = DEFAULT_TEXT_HEIGHT;
|
||||
ns.textHeightAs = UNITS_AS_PIXELS;
|
||||
ns.visible = true;
|
||||
ns.exportable = true;
|
||||
ns.h = h;
|
||||
if(isDefaultStyle) {
|
||||
ns.name.strcpy(CnfPrefixToName(d->cnfPrefix));
|
||||
} else {
|
||||
@ -88,11 +90,13 @@ void Style::LoadFactoryDefaults(void) {
|
||||
for(d = &(Defaults[0]); d->h.v; d++) {
|
||||
Style *s = Get(d->h);
|
||||
|
||||
s->color = d->color;
|
||||
s->width = d->width;
|
||||
s->widthHow = WIDTH_AS_PIXELS;
|
||||
s->visible = true;
|
||||
s->exportable = true;
|
||||
s->color = d->color;
|
||||
s->width = d->width;
|
||||
s->widthAs = UNITS_AS_PIXELS;
|
||||
s->textHeight = DEFAULT_TEXT_HEIGHT;
|
||||
s->textHeightAs = UNITS_AS_PIXELS;
|
||||
s->visible = true;
|
||||
s->exportable = true;
|
||||
s->name.strcpy(CnfPrefixToName(d->cnfPrefix));
|
||||
}
|
||||
SS.backgroundColor = RGB(0, 0, 0);
|
||||
@ -119,7 +123,8 @@ void Style::AssignSelectionToStyle(DWORD v) {
|
||||
SS.GW.GroupSelection();
|
||||
|
||||
SS.UndoRemember();
|
||||
for(int i = 0; i < SS.GW.gs.entities; i++) {
|
||||
int i;
|
||||
for(i = 0; i < SS.GW.gs.entities; i++) {
|
||||
hEntity he = SS.GW.gs.entity[i];
|
||||
if(!he.isFromRequest()) {
|
||||
showError = true;
|
||||
@ -131,6 +136,13 @@ void Style::AssignSelectionToStyle(DWORD v) {
|
||||
r->style.v = v;
|
||||
SS.later.generateAll = true;
|
||||
}
|
||||
for(i = 0; i < SS.GW.gs.constraints; i++) {
|
||||
hConstraint hc = SS.GW.gs.constraint[i];
|
||||
Constraint *c = SK.GetConstraint(hc);
|
||||
if(c->type != Constraint::COMMENT) continue;
|
||||
|
||||
c->disp.style.v = v;
|
||||
}
|
||||
|
||||
if(showError) {
|
||||
Error("Can't assign style to an entity that's derived from another "
|
||||
@ -204,9 +216,9 @@ DWORD Style::Color(hStyle h, bool forExport) {
|
||||
float Style::Width(hStyle h) {
|
||||
double r = 1.0;
|
||||
Style *s = Get(h);
|
||||
if(s->widthHow == WIDTH_AS_MM) {
|
||||
if(s->widthAs == UNITS_AS_MM) {
|
||||
r = s->width * SS.GW.scale;
|
||||
} else if(s->widthHow == WIDTH_AS_PIXELS) {
|
||||
} else if(s->widthAs == UNITS_AS_PIXELS) {
|
||||
r = s->width;
|
||||
}
|
||||
// This returns a float because glLineWidth expects a float, avoid casts.
|
||||
@ -221,6 +233,20 @@ double Style::WidthMm(int hs) {
|
||||
return widthpx / SS.GW.scale;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Return the associated text height, in pixels.
|
||||
//-----------------------------------------------------------------------------
|
||||
double Style::TextHeight(hStyle hs) {
|
||||
Style *s = Get(hs);
|
||||
if(s->textHeightAs == UNITS_AS_MM) {
|
||||
return s->textHeight * SS.GW.scale;
|
||||
} else if(s->textHeightAs == UNITS_AS_PIXELS) {
|
||||
return s->textHeight;
|
||||
} else {
|
||||
return DEFAULT_TEXT_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Should lines and curves from this style appear in the output file? Only
|
||||
// if it's both shown and exportable.
|
||||
@ -346,18 +372,22 @@ void TextWindow::ScreenDeleteStyle(int link, DWORD v) {
|
||||
InvalidateGraphics();
|
||||
}
|
||||
|
||||
void TextWindow::ScreenChangeStyleWidth(int link, DWORD v) {
|
||||
void TextWindow::ScreenChangeStyleWidthOrTextHeight(int link, DWORD v) {
|
||||
hStyle hs = { v };
|
||||
Style *s = Style::Get(hs);
|
||||
double val = (link == 'w') ? s->width : s->textHeight;
|
||||
int units = (link == 'w') ? s->widthAs : s->textHeightAs;
|
||||
|
||||
char str[300];
|
||||
if(s->widthHow == Style::WIDTH_AS_PIXELS) {
|
||||
sprintf(str, "%.2f", s->width);
|
||||
if(units == Style::UNITS_AS_PIXELS) {
|
||||
sprintf(str, "%.2f", val);
|
||||
} else {
|
||||
strcpy(str, SS.MmToString(s->width));
|
||||
strcpy(str, SS.MmToString(val));
|
||||
}
|
||||
ShowTextEditControl(16, 8, str);
|
||||
ShowTextEditControl((link == 'w') ? 21 : 26, 13, str);
|
||||
SS.TW.edit.style = hs;
|
||||
SS.TW.edit.meaning = EDIT_STYLE_WIDTH;
|
||||
SS.TW.edit.meaning = (link == 'w') ? EDIT_STYLE_WIDTH :
|
||||
EDIT_STYLE_TEXT_HEIGHT;
|
||||
}
|
||||
|
||||
void TextWindow::ScreenChangeStyleColor(int link, DWORD v) {
|
||||
@ -377,10 +407,24 @@ void TextWindow::ScreenChangeStyleYesNo(int link, DWORD v) {
|
||||
Style *s = Style::Get(hs);
|
||||
switch(link) {
|
||||
case 'w':
|
||||
if(s->widthHow == Style::WIDTH_AS_PIXELS) {
|
||||
s->widthHow = Style::WIDTH_AS_MM;
|
||||
// Units for the width
|
||||
if(s->widthAs == Style::UNITS_AS_PIXELS) {
|
||||
s->widthAs = Style::UNITS_AS_MM;
|
||||
s->width /= SS.GW.scale;
|
||||
} else {
|
||||
s->widthHow = Style::WIDTH_AS_PIXELS;
|
||||
s->widthAs = Style::UNITS_AS_PIXELS;
|
||||
s->width *= SS.GW.scale;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
// Units for the height
|
||||
if(s->textHeightAs == Style::UNITS_AS_PIXELS) {
|
||||
s->textHeightAs = Style::UNITS_AS_MM;
|
||||
s->textHeight /= SS.GW.scale;
|
||||
} else {
|
||||
s->textHeightAs = Style::UNITS_AS_PIXELS;
|
||||
s->textHeight *= SS.GW.scale;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -391,6 +435,34 @@ void TextWindow::ScreenChangeStyleYesNo(int link, DWORD v) {
|
||||
case 'v':
|
||||
s->visible = !(s->visible);
|
||||
break;
|
||||
|
||||
// Horizontal text alignment
|
||||
case 'L':
|
||||
s->textOrigin |= Style::ORIGIN_LEFT;
|
||||
s->textOrigin &= ~Style::ORIGIN_RIGHT;
|
||||
break;
|
||||
case 'H':
|
||||
s->textOrigin &= ~Style::ORIGIN_LEFT;
|
||||
s->textOrigin &= ~Style::ORIGIN_RIGHT;
|
||||
break;
|
||||
case 'R':
|
||||
s->textOrigin &= ~Style::ORIGIN_LEFT;
|
||||
s->textOrigin |= Style::ORIGIN_RIGHT;
|
||||
break;
|
||||
|
||||
// Vertical text alignment
|
||||
case 'B':
|
||||
s->textOrigin |= Style::ORIGIN_BOT;
|
||||
s->textOrigin &= ~Style::ORIGIN_TOP;
|
||||
break;
|
||||
case 'V':
|
||||
s->textOrigin &= ~Style::ORIGIN_BOT;
|
||||
s->textOrigin &= ~Style::ORIGIN_TOP;
|
||||
break;
|
||||
case 'T':
|
||||
s->textOrigin &= ~Style::ORIGIN_BOT;
|
||||
s->textOrigin |= Style::ORIGIN_TOP;
|
||||
break;
|
||||
}
|
||||
InvalidateGraphics();
|
||||
}
|
||||
@ -398,17 +470,27 @@ void TextWindow::ScreenChangeStyleYesNo(int link, DWORD v) {
|
||||
bool TextWindow::EditControlDoneForStyles(char *str) {
|
||||
Style *s;
|
||||
switch(edit.meaning) {
|
||||
case EDIT_STYLE_WIDTH:
|
||||
case EDIT_STYLE_TEXT_HEIGHT:
|
||||
case EDIT_STYLE_WIDTH: {
|
||||
SS.UndoRemember();
|
||||
s = Style::Get(edit.style);
|
||||
if(s->widthHow == Style::WIDTH_AS_MM) {
|
||||
s->width = SS.StringToMm(str);
|
||||
} else {
|
||||
s->width = atof(str);
|
||||
}
|
||||
s->width = max(0, s->width);
|
||||
return true;
|
||||
|
||||
double v;
|
||||
int units = (edit.meaning == EDIT_STYLE_TEXT_HEIGHT) ?
|
||||
s->textHeightAs : s->widthAs;
|
||||
if(units == Style::UNITS_AS_MM) {
|
||||
v = SS.StringToMm(str);
|
||||
} else {
|
||||
v = atof(str);
|
||||
}
|
||||
v = max(0, v);
|
||||
if(edit.meaning == EDIT_STYLE_TEXT_HEIGHT) {
|
||||
s->textHeight = v;
|
||||
} else {
|
||||
s->width = v;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case EDIT_BACKGROUND_COLOR:
|
||||
case EDIT_STYLE_COLOR: {
|
||||
double r, g, b;
|
||||
@ -462,31 +544,6 @@ void TextWindow::ShowStyleInfo(void) {
|
||||
REDf(s->color), GREENf(s->color), BLUEf(s->color),
|
||||
s->h.v, ScreenChangeStyleColor);
|
||||
|
||||
if(s->widthHow == Style::WIDTH_AS_PIXELS) {
|
||||
Printf(true, "%FtWIDTH %E%@ %D%f%Ll%Fl[change]%E",
|
||||
s->width,
|
||||
s->h.v, &ScreenChangeStyleWidth);
|
||||
} else {
|
||||
Printf(true, "%FtWIDTH %E%s %D%f%Ll%Fl[change]%E",
|
||||
SS.MmToString(s->width),
|
||||
s->h.v, &ScreenChangeStyleWidth);
|
||||
}
|
||||
|
||||
char *unit = (SS.viewUnits == SolveSpace::UNIT_INCHES) ? "inches" : "mm";
|
||||
bool widthpx = (s->widthHow == Style::WIDTH_AS_PIXELS);
|
||||
|
||||
if(s->h.v < Style::FIRST_CUSTOM) {
|
||||
Printf(false,"%FtUNITS %Fspixels%E");
|
||||
} else {
|
||||
Printf(false,"%FtUNITS %Fh%D%f%Lw%s%E%Fs%s%E / %Fh%D%f%Lw%s%E%Fs%s%E",
|
||||
s->h.v, &ScreenChangeStyleYesNo,
|
||||
( widthpx ? "" : "pixels"),
|
||||
( widthpx ? "pixels" : ""),
|
||||
s->h.v, &ScreenChangeStyleYesNo,
|
||||
(!widthpx ? "" : unit),
|
||||
(!widthpx ? unit : ""));
|
||||
}
|
||||
|
||||
if(s->h.v >= Style::FIRST_CUSTOM) {
|
||||
Printf(true, "%FtSHOW %Fh%D%f%Lv%s%E%Fs%s%E / %Fh%D%f%Lv%s%E%Fs%s%E",
|
||||
s->h.v, &ScreenChangeStyleYesNo,
|
||||
@ -502,7 +559,98 @@ void TextWindow::ShowStyleInfo(void) {
|
||||
s->h.v, &ScreenChangeStyleYesNo,
|
||||
(!s->exportable ? "" : "no"),
|
||||
(!s->exportable ? "no" : ""));
|
||||
}
|
||||
|
||||
char *unit = (SS.viewUnits == SolveSpace::UNIT_INCHES) ? "inches" : "mm";
|
||||
|
||||
// The line width, and its units
|
||||
if(s->widthAs == Style::UNITS_AS_PIXELS) {
|
||||
Printf(true, "%FtLINE WIDTH %E%@ %D%f%Lw%Fl[change]%E",
|
||||
s->width,
|
||||
s->h.v, &ScreenChangeStyleWidthOrTextHeight);
|
||||
} else {
|
||||
Printf(true, "%FtLINE WIDTH %E%s %D%f%Lw%Fl[change]%E",
|
||||
SS.MmToString(s->width),
|
||||
s->h.v, &ScreenChangeStyleWidthOrTextHeight);
|
||||
}
|
||||
|
||||
bool widthpx = (s->widthAs == Style::UNITS_AS_PIXELS);
|
||||
if(s->h.v < Style::FIRST_CUSTOM) {
|
||||
Printf(false,"%FtIN UNITS OF %Fspixels%E");
|
||||
} else {
|
||||
Printf(false,"%FtIN UNITS OF "
|
||||
"%Fh%D%f%Lw%s%E%Fs%s%E / %Fh%D%f%Lw%s%E%Fs%s%E",
|
||||
s->h.v, &ScreenChangeStyleYesNo,
|
||||
( widthpx ? "" : "pixels"),
|
||||
( widthpx ? "pixels" : ""),
|
||||
s->h.v, &ScreenChangeStyleYesNo,
|
||||
(!widthpx ? "" : unit),
|
||||
(!widthpx ? unit : ""));
|
||||
}
|
||||
|
||||
// The text height, and its units
|
||||
char *chng = (s->h.v < Style::FIRST_CUSTOM) ? "" : "[change]";
|
||||
if(s->textHeightAs == Style::UNITS_AS_PIXELS) {
|
||||
Printf(true, "%FtTEXT HEIGHT %E%@ %D%f%Lt%Fl%s%E",
|
||||
s->textHeight,
|
||||
s->h.v, &ScreenChangeStyleWidthOrTextHeight,
|
||||
chng);
|
||||
} else {
|
||||
Printf(true, "%FtTEXT HEIGHT %E%s %D%f%Lt%Fl%s%E",
|
||||
SS.MmToString(s->textHeight),
|
||||
s->h.v, &ScreenChangeStyleWidthOrTextHeight,
|
||||
chng);
|
||||
}
|
||||
|
||||
bool textHeightpx = (s->textHeightAs == Style::UNITS_AS_PIXELS);
|
||||
if(s->h.v < Style::FIRST_CUSTOM) {
|
||||
Printf(false,"%FtIN UNITS OF %Fspixels%E");
|
||||
} else {
|
||||
Printf(false,"%FtIN UNITS OF "
|
||||
"%Fh%D%f%Lh%s%E%Fs%s%E / %Fh%D%f%Lh%s%E%Fs%s%E",
|
||||
s->h.v, &ScreenChangeStyleYesNo,
|
||||
( textHeightpx ? "" : "pixels"),
|
||||
( textHeightpx ? "pixels" : ""),
|
||||
s->h.v, &ScreenChangeStyleYesNo,
|
||||
(!textHeightpx ? "" : unit),
|
||||
(!textHeightpx ? unit : ""));
|
||||
}
|
||||
|
||||
if(s->h.v >= Style::FIRST_CUSTOM) {
|
||||
bool neither;
|
||||
|
||||
neither = !(s->textOrigin & (Style::ORIGIN_LEFT | Style::ORIGIN_RIGHT));
|
||||
Printf(true, "%FtALIGN TEXT "
|
||||
"%Fh%D%f%LL%s%E%Fs%s%E / "
|
||||
"%Fh%D%f%LH%s%E%Fs%s%E / "
|
||||
"%Fh%D%f%LR%s%E%Fs%s%E",
|
||||
s->h.v, &ScreenChangeStyleYesNo,
|
||||
((s->textOrigin & Style::ORIGIN_LEFT) ? "" : "left"),
|
||||
((s->textOrigin & Style::ORIGIN_LEFT) ? "left" : ""),
|
||||
s->h.v, &ScreenChangeStyleYesNo,
|
||||
(neither ? "" : "center"),
|
||||
(neither ? "center" : ""),
|
||||
s->h.v, &ScreenChangeStyleYesNo,
|
||||
((s->textOrigin & Style::ORIGIN_RIGHT) ? "" : "right"),
|
||||
((s->textOrigin & Style::ORIGIN_RIGHT) ? "right" : ""));
|
||||
|
||||
neither = !(s->textOrigin & (Style::ORIGIN_BOT | Style::ORIGIN_TOP));
|
||||
Printf(false, "%Ft "
|
||||
"%Fh%D%f%LB%s%E%Fs%s%E / "
|
||||
"%Fh%D%f%LV%s%E%Fs%s%E / "
|
||||
"%Fh%D%f%LT%s%E%Fs%s%E",
|
||||
s->h.v, &ScreenChangeStyleYesNo,
|
||||
((s->textOrigin & Style::ORIGIN_BOT) ? "" : "bottom"),
|
||||
((s->textOrigin & Style::ORIGIN_BOT) ? "bottom" : ""),
|
||||
s->h.v, &ScreenChangeStyleYesNo,
|
||||
(neither ? "" : "center"),
|
||||
(neither ? "center" : ""),
|
||||
s->h.v, &ScreenChangeStyleYesNo,
|
||||
((s->textOrigin & Style::ORIGIN_TOP) ? "" : "top"),
|
||||
((s->textOrigin & Style::ORIGIN_TOP) ? "top" : ""));
|
||||
}
|
||||
|
||||
if(s->h.v >= Style::FIRST_CUSTOM) {
|
||||
Printf(false, "");
|
||||
Printf(false, "To assign lines or curves to this style,");
|
||||
Printf(false, "select them on the drawing. Then commit");
|
||||
|
12
ui.h
12
ui.h
@ -94,9 +94,10 @@ public:
|
||||
static const int EDIT_STEP_DIM_STEPS = 41;
|
||||
// For the styles stuff
|
||||
static const int EDIT_STYLE_WIDTH = 50;
|
||||
static const int EDIT_STYLE_COLOR = 51;
|
||||
static const int EDIT_STYLE_NAME = 52;
|
||||
static const int EDIT_BACKGROUND_COLOR = 53;
|
||||
static const int EDIT_STYLE_TEXT_HEIGHT = 51;
|
||||
static const int EDIT_STYLE_COLOR = 52;
|
||||
static const int EDIT_STYLE_NAME = 53;
|
||||
static const int EDIT_BACKGROUND_COLOR = 54;
|
||||
struct {
|
||||
int meaning;
|
||||
int i;
|
||||
@ -189,7 +190,7 @@ public:
|
||||
static void ScreenChangeExportScale(int link, DWORD v);
|
||||
static void ScreenChangeExportOffset(int link, DWORD v);
|
||||
static void ScreenChangeStyleName(int link, DWORD v);
|
||||
static void ScreenChangeStyleWidth(int link, DWORD v);
|
||||
static void ScreenChangeStyleWidthOrTextHeight(int link, DWORD v);
|
||||
static void ScreenChangeStyleColor(int link, DWORD v);
|
||||
static void ScreenChangeBackgroundColor(int link, DWORD v);
|
||||
|
||||
@ -400,6 +401,7 @@ public:
|
||||
void Clear(void);
|
||||
bool IsEmpty(void);
|
||||
bool Equals(Selection *b);
|
||||
bool IsStylable(void);
|
||||
};
|
||||
Selection hover;
|
||||
static const int MAX_SELECTED = 32;
|
||||
@ -425,6 +427,7 @@ public:
|
||||
int anyNormals;
|
||||
int vectors;
|
||||
int constraints;
|
||||
int stylables;
|
||||
int n;
|
||||
} gs;
|
||||
void GroupSelection(void);
|
||||
@ -439,6 +442,7 @@ public:
|
||||
static const int CMNU_GROUP_INFO = 0x105;
|
||||
static const int CMNU_REFERENCE_DIM = 0x106;
|
||||
static const int CMNU_OTHER_ANGLE = 0x107;
|
||||
static const int CMNU_STYLE_INFO = 0x108;
|
||||
static const int CMNU_FIRST_STYLE = 0x40000000;
|
||||
void ContextMenuListStyles(void);
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
|
||||
grid
|
||||
better text
|
||||
right-click menu
|
||||
wireframe export
|
||||
|
||||
-----
|
||||
|
Loading…
Reference in New Issue
Block a user