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 M&eters"), Command::UNITS_METERS, 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, N_("Show &Toolbar"), Command::SHOW_TOOLBAR, 0, KC, mView },
{ 1, N_("Show Property Bro&wser"), Command::SHOW_TEXT_WND, '\t', KC, mView },
@ -329,6 +330,8 @@ void GraphicsWindow::PopulateMainMenu() {
unitsMetersMenuItem = menuItem;
} else if(Menu[i].cmd == Command::UNITS_INCHES) {
unitsInchesMenuItem = menuItem;
} else if(Menu[i].cmd == Command::UNITS_FEET_INCHES) {
unitsFeetInchesMenuItem = menuItem;
} else if(Menu[i].cmd == Command::SEL_WORKPLANE) {
inWorkplaneMenuItem = menuItem;
} else if(Menu[i].cmd == Command::FREE_IN_3D) {
@ -843,6 +846,12 @@ void GraphicsWindow::MenuView(Command id) {
SS.GW.EnsureValidActives();
break;
case Command::UNITS_FEET_INCHES:
SS.viewUnits = Unit::FEET_INCHES;
SS.ScheduleShowTW();
SS.GW.EnsureValidActives();
break;
case Command::UNITS_MM:
SS.viewUnits = Unit::MM;
SS.ScheduleShowTW();
@ -925,6 +934,7 @@ void GraphicsWindow::EnsureValidActives() {
case Unit::MM:
case Unit::METERS:
case Unit::INCHES:
case Unit::FEET_INCHES:
break;
default:
SS.viewUnits = Unit::MM;
@ -933,6 +943,7 @@ void GraphicsWindow::EnsureValidActives() {
unitsMmMenuItem->SetActive(SS.viewUnits == Unit::MM);
unitsMetersMenuItem->SetActive(SS.viewUnits == Unit::METERS);
unitsInchesMenuItem->SetActive(SS.viewUnits == Unit::INCHES);
unitsFeetInchesMenuItem->SetActive(SS.viewUnits == Unit::FEET_INCHES);
if(SS.TW.window) SS.TW.window->SetVisible(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) {
editValue = SS.DegreeToString(value);
} else {
editValue = SS.MmToString(value);
editValue = SS.MmToString(value, true);
value /= SS.MmPerUnit();
}
// 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() {
switch(viewUnits) {
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::MM: return 1.0;
}
@ -323,22 +324,42 @@ double SolveSpaceUI::MmPerUnit() {
const char *SolveSpaceUI::UnitName() {
switch(viewUnits) {
case Unit::INCHES: return "in";
case Unit::FEET_INCHES: return "in";
case Unit::METERS: return "m";
case Unit::MM: return "mm";
}
return "";
}
std::string SolveSpaceUI::MmToString(double v) {
std::string SolveSpaceUI::MmToString(double v, bool editable) {
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();
double minimum = 0.5 * pow(10,-digits);
while ((v < minimum) && (v > LENGTH_EPS)) {
while ((feet == 0) && (v < minimum) && (v > LENGTH_EPS)) {
digits++;
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);
}
}
static const char *DimToString(int dim) {
switch(dim) {
case 3: return "³";
@ -394,17 +415,22 @@ std::string SolveSpaceUI::MmToStringSI(double v, int dim) {
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)));
std::string unit;
if(fabs(v) > 0.0) {
int sdeg = 0;
std::tie(sdeg, unit) =
(viewUnits == Unit::INCHES)
inches
? SelectSIPrefixInch(vdeg/dim)
: SelectSIPrefixMm(vdeg, 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));
return ssprintf("%.*g%s%s%s", pdeg + UnitDigitsAfterDecimal(), v,
compact ? "" : " ", unit.c_str(), DimToString(dim));
@ -434,10 +460,11 @@ int SolveSpaceUI::GetMaxSegments() {
return maxSegments;
}
int SolveSpaceUI::UnitDigitsAfterDecimal() {
return (viewUnits == Unit::INCHES) ? afterDecimalInch : afterDecimalMm;
return (viewUnits == Unit::INCHES || viewUnits == Unit::FEET_INCHES) ?
afterDecimalInch : afterDecimalMm;
}
void SolveSpaceUI::SetUnitDigitsAfterDecimal(int v) {
if(viewUnits == Unit::INCHES) {
if(viewUnits == Unit::INCHES || viewUnits == Unit::FEET_INCHES) {
afterDecimalInch = v;
} else {
afterDecimalMm = v;
@ -1036,6 +1063,7 @@ void SolveSpaceUI::Clear() {
GW.unitsMmMenuItem = NULL;
GW.unitsMetersMenuItem = NULL;
GW.unitsInchesMenuItem = NULL;
GW.unitsFeetInchesMenuItem = NULL;
GW.inWorkplaneMenuItem = NULL;
GW.in3dMenuItem = NULL;
GW.undoMenuItem = NULL;

View File

@ -138,7 +138,8 @@ enum class Command : uint32_t;
enum class Unit : uint32_t {
MM = 0,
INCHES,
METERS
METERS,
FEET_INCHES
};
template<class Key, class T>
@ -609,7 +610,7 @@ public:
bool useSIPrefixes;
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 DegreeToString(double v);
double ExprToMm(Expr *e);

View File

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