Add option for displaying dimensions in feet and inches

pull/1003/head
Tom Sutcliffe 2021-08-12 12:35:44 +01:00 committed by phkahler
parent 645febfcd6
commit 2fb6119de8
5 changed files with 52 additions and 10 deletions

View File

@ -98,6 +98,7 @@ const MenuEntry Menu[] = {
{ 2, N_("Dimensions in &Millimeters"), Command::UNITS_MM, 0, KR, mView }, { 2, N_("Dimensions in &Millimeters"), Command::UNITS_MM, 0, KR, mView },
{ 2, N_("Dimensions in M&eters"), Command::UNITS_METERS, 0, KR, mView }, { 2, N_("Dimensions in M&eters"), Command::UNITS_METERS, 0, KR, mView },
{ 2, N_("Dimensions in &Inches"), Command::UNITS_INCHES, 0, KR, mView }, { 2, N_("Dimensions in &Inches"), Command::UNITS_INCHES, 0, KR, mView },
{ 2, N_("Dimensions in &Feet and Inches"), Command::UNITS_FEET_INCHES, 0, KR, mView },
{ 1, NULL, Command::NONE, 0, KN, NULL }, { 1, NULL, Command::NONE, 0, KN, NULL },
{ 1, N_("Show &Toolbar"), Command::SHOW_TOOLBAR, 0, KC, mView }, { 1, N_("Show &Toolbar"), Command::SHOW_TOOLBAR, 0, KC, mView },
{ 1, N_("Show Property Bro&wser"), Command::SHOW_TEXT_WND, '\t', KC, mView }, { 1, N_("Show Property Bro&wser"), Command::SHOW_TEXT_WND, '\t', KC, mView },
@ -329,6 +330,8 @@ void GraphicsWindow::PopulateMainMenu() {
unitsMetersMenuItem = menuItem; unitsMetersMenuItem = menuItem;
} else if(Menu[i].cmd == Command::UNITS_INCHES) { } else if(Menu[i].cmd == Command::UNITS_INCHES) {
unitsInchesMenuItem = menuItem; unitsInchesMenuItem = menuItem;
} else if(Menu[i].cmd == Command::UNITS_FEET_INCHES) {
unitsFeetInchesMenuItem = menuItem;
} else if(Menu[i].cmd == Command::SEL_WORKPLANE) { } else if(Menu[i].cmd == Command::SEL_WORKPLANE) {
inWorkplaneMenuItem = menuItem; inWorkplaneMenuItem = menuItem;
} else if(Menu[i].cmd == Command::FREE_IN_3D) { } else if(Menu[i].cmd == Command::FREE_IN_3D) {
@ -843,6 +846,12 @@ void GraphicsWindow::MenuView(Command id) {
SS.GW.EnsureValidActives(); SS.GW.EnsureValidActives();
break; break;
case Command::UNITS_FEET_INCHES:
SS.viewUnits = Unit::FEET_INCHES;
SS.ScheduleShowTW();
SS.GW.EnsureValidActives();
break;
case Command::UNITS_MM: case Command::UNITS_MM:
SS.viewUnits = Unit::MM; SS.viewUnits = Unit::MM;
SS.ScheduleShowTW(); SS.ScheduleShowTW();
@ -925,6 +934,7 @@ void GraphicsWindow::EnsureValidActives() {
case Unit::MM: case Unit::MM:
case Unit::METERS: case Unit::METERS:
case Unit::INCHES: case Unit::INCHES:
case Unit::FEET_INCHES:
break; break;
default: default:
SS.viewUnits = Unit::MM; SS.viewUnits = Unit::MM;
@ -933,6 +943,7 @@ void GraphicsWindow::EnsureValidActives() {
unitsMmMenuItem->SetActive(SS.viewUnits == Unit::MM); unitsMmMenuItem->SetActive(SS.viewUnits == Unit::MM);
unitsMetersMenuItem->SetActive(SS.viewUnits == Unit::METERS); unitsMetersMenuItem->SetActive(SS.viewUnits == Unit::METERS);
unitsInchesMenuItem->SetActive(SS.viewUnits == Unit::INCHES); unitsInchesMenuItem->SetActive(SS.viewUnits == Unit::INCHES);
unitsFeetInchesMenuItem->SetActive(SS.viewUnits == Unit::FEET_INCHES);
if(SS.TW.window) SS.TW.window->SetVisible(SS.GW.showTextWindow); if(SS.TW.window) SS.TW.window->SetVisible(SS.GW.showTextWindow);
showTextWndMenuItem->SetActive(SS.GW.showTextWindow); showTextWndMenuItem->SetActive(SS.GW.showTextWindow);

View File

@ -1378,7 +1378,7 @@ void GraphicsWindow::EditConstraint(hConstraint constraint) {
} else if(c->type == Constraint::Type::ANGLE) { } else if(c->type == Constraint::Type::ANGLE) {
editValue = SS.DegreeToString(value); editValue = SS.DegreeToString(value);
} else { } else {
editValue = SS.MmToString(value); editValue = SS.MmToString(value, true);
value /= SS.MmPerUnit(); value /= SS.MmPerUnit();
} }
// If that's not enough to represent it exactly, show the value with as many // If that's not enough to represent it exactly, show the value with as many

View File

@ -315,6 +315,7 @@ void SolveSpaceUI::ScheduleAutosave() {
double SolveSpaceUI::MmPerUnit() { double SolveSpaceUI::MmPerUnit() {
switch(viewUnits) { switch(viewUnits) {
case Unit::INCHES: return 25.4; case Unit::INCHES: return 25.4;
case Unit::FEET_INCHES: return 25.4; // The 'unit' is still inches
case Unit::METERS: return 1000.0; case Unit::METERS: return 1000.0;
case Unit::MM: return 1.0; case Unit::MM: return 1.0;
} }
@ -323,21 +324,41 @@ double SolveSpaceUI::MmPerUnit() {
const char *SolveSpaceUI::UnitName() { const char *SolveSpaceUI::UnitName() {
switch(viewUnits) { switch(viewUnits) {
case Unit::INCHES: return "in"; case Unit::INCHES: return "in";
case Unit::FEET_INCHES: return "in";
case Unit::METERS: return "m"; case Unit::METERS: return "m";
case Unit::MM: return "mm"; case Unit::MM: return "mm";
} }
return ""; return "";
} }
std::string SolveSpaceUI::MmToString(double v) { std::string SolveSpaceUI::MmToString(double v, bool editable) {
v /= MmPerUnit(); v /= MmPerUnit();
int feet = 0;
// The syntax 2' 6" for feet and inches is not something we can (currently)
// parse back from a string so if editable is true, we treat FEET_INCHES the
// same as INCHES and just return the unadorned decimal number of inches.
if(viewUnits == Unit::FEET_INCHES && !editable) {
// v is in inches at this point
feet = (int)(v / 12.0);
v = v - (feet * 12.0);
// v is now the remainder in inches
}
int digits = UnitDigitsAfterDecimal(); int digits = UnitDigitsAfterDecimal();
double minimum = 0.5 * pow(10,-digits); double minimum = 0.5 * pow(10,-digits);
while ((v < minimum) && (v > LENGTH_EPS)) { while ((feet == 0) && (v < minimum) && (v > LENGTH_EPS)) {
digits++; digits++;
minimum *= 0.1; minimum *= 0.1;
} }
if(viewUnits == Unit::FEET_INCHES && !editable) {
if(feet != 0) {
return ssprintf("%d' %.*f\"", feet, digits, v);
} else {
return ssprintf("%.*f\"", digits, v);
}
} else {
return ssprintf("%.*f", digits, v); return ssprintf("%.*f", digits, v);
}
} }
static const char *DimToString(int dim) { static const char *DimToString(int dim) {
switch(dim) { switch(dim) {
@ -394,17 +415,22 @@ std::string SolveSpaceUI::MmToStringSI(double v, int dim) {
dim = 1; dim = 1;
} }
v /= pow((viewUnits == Unit::INCHES) ? 25.4 : 1000, dim); bool inches = (viewUnits == Unit::INCHES) || (viewUnits == Unit::FEET_INCHES);
v /= pow(inches ? 25.4 : 1000, dim);
int vdeg = (int)(log10(fabs(v))); int vdeg = (int)(log10(fabs(v)));
std::string unit; std::string unit;
if(fabs(v) > 0.0) { if(fabs(v) > 0.0) {
int sdeg = 0; int sdeg = 0;
std::tie(sdeg, unit) = std::tie(sdeg, unit) =
(viewUnits == Unit::INCHES) inches
? SelectSIPrefixInch(vdeg/dim) ? SelectSIPrefixInch(vdeg/dim)
: SelectSIPrefixMm(vdeg, dim); : SelectSIPrefixMm(vdeg, dim);
v /= pow(10.0, sdeg * dim); v /= pow(10.0, sdeg * dim);
} }
if(viewUnits == Unit::FEET_INCHES && fabs(v) > pow(12.0, dim)) {
unit = "ft";
v /= pow(12.0, dim);
}
int pdeg = (int)ceil(log10(fabs(v) + 1e-10)); int pdeg = (int)ceil(log10(fabs(v) + 1e-10));
return ssprintf("%.*g%s%s%s", pdeg + UnitDigitsAfterDecimal(), v, return ssprintf("%.*g%s%s%s", pdeg + UnitDigitsAfterDecimal(), v,
compact ? "" : " ", unit.c_str(), DimToString(dim)); compact ? "" : " ", unit.c_str(), DimToString(dim));
@ -434,10 +460,11 @@ int SolveSpaceUI::GetMaxSegments() {
return maxSegments; return maxSegments;
} }
int SolveSpaceUI::UnitDigitsAfterDecimal() { int SolveSpaceUI::UnitDigitsAfterDecimal() {
return (viewUnits == Unit::INCHES) ? afterDecimalInch : afterDecimalMm; return (viewUnits == Unit::INCHES || viewUnits == Unit::FEET_INCHES) ?
afterDecimalInch : afterDecimalMm;
} }
void SolveSpaceUI::SetUnitDigitsAfterDecimal(int v) { void SolveSpaceUI::SetUnitDigitsAfterDecimal(int v) {
if(viewUnits == Unit::INCHES) { if(viewUnits == Unit::INCHES || viewUnits == Unit::FEET_INCHES) {
afterDecimalInch = v; afterDecimalInch = v;
} else { } else {
afterDecimalMm = v; afterDecimalMm = v;
@ -1036,6 +1063,7 @@ void SolveSpaceUI::Clear() {
GW.unitsMmMenuItem = NULL; GW.unitsMmMenuItem = NULL;
GW.unitsMetersMenuItem = NULL; GW.unitsMetersMenuItem = NULL;
GW.unitsInchesMenuItem = NULL; GW.unitsInchesMenuItem = NULL;
GW.unitsFeetInchesMenuItem = NULL;
GW.inWorkplaneMenuItem = NULL; GW.inWorkplaneMenuItem = NULL;
GW.in3dMenuItem = NULL; GW.in3dMenuItem = NULL;
GW.undoMenuItem = NULL; GW.undoMenuItem = NULL;

View File

@ -138,7 +138,8 @@ enum class Command : uint32_t;
enum class Unit : uint32_t { enum class Unit : uint32_t {
MM = 0, MM = 0,
INCHES, INCHES,
METERS METERS,
FEET_INCHES
}; };
template<class Key, class T> template<class Key, class T>
@ -609,7 +610,7 @@ public:
bool useSIPrefixes; bool useSIPrefixes;
int autosaveInterval; // in minutes int autosaveInterval; // in minutes
std::string MmToString(double v); std::string MmToString(double v, bool editable=false);
std::string MmToStringSI(double v, int dim = 0); std::string MmToStringSI(double v, int dim = 0);
std::string DegreeToString(double v); std::string DegreeToString(double v);
double ExprToMm(Expr *e); double ExprToMm(Expr *e);

View File

@ -89,6 +89,7 @@ enum class Command : uint32_t {
SHOW_TOOLBAR, SHOW_TOOLBAR,
SHOW_TEXT_WND, SHOW_TEXT_WND,
UNITS_INCHES, UNITS_INCHES,
UNITS_FEET_INCHES,
UNITS_MM, UNITS_MM,
UNITS_METERS, UNITS_METERS,
FULL_SCREEN, FULL_SCREEN,
@ -546,6 +547,7 @@ public:
Platform::MenuItemRef unitsMmMenuItem; Platform::MenuItemRef unitsMmMenuItem;
Platform::MenuItemRef unitsMetersMenuItem; Platform::MenuItemRef unitsMetersMenuItem;
Platform::MenuItemRef unitsInchesMenuItem; Platform::MenuItemRef unitsInchesMenuItem;
Platform::MenuItemRef unitsFeetInchesMenuItem;
Platform::MenuItemRef inWorkplaneMenuItem; Platform::MenuItemRef inWorkplaneMenuItem;
Platform::MenuItemRef in3dMenuItem; Platform::MenuItemRef in3dMenuItem;