Add a color picker, with a fancy HSV (actually, a modified version
of that, where you can pick the hue and blackness, and then the whiteness) color picker and some swatches. This is used in three places now: the special colors in the config screen, the background color, and the style colors. [git-p4: depot-paths = "//depot/solvespace/": change = 2174]solver
parent
98897af77b
commit
439e4d3124
|
@ -21,12 +21,8 @@ void TextWindow::ScreenChangeLightIntensity(int link, DWORD v) {
|
|||
}
|
||||
|
||||
void TextWindow::ScreenChangeColor(int link, DWORD v) {
|
||||
char str[1024];
|
||||
sprintf(str, "%.2f, %.2f, %.2f",
|
||||
REDf(SS.modelColor[v]),
|
||||
GREENf(SS.modelColor[v]),
|
||||
BLUEf(SS.modelColor[v]));
|
||||
SS.TW.ShowEditControl(9+2*v, 13, str);
|
||||
SS.TW.ShowEditControlWithColorPicker(9+2*v, 13, SS.modelColor[v]);
|
||||
|
||||
SS.TW.edit.meaning = EDIT_COLOR;
|
||||
SS.TW.edit.i = v;
|
||||
}
|
||||
|
|
1
dsc.h
1
dsc.h
|
@ -90,6 +90,7 @@ public:
|
|||
double DivPivoting(Vector delta);
|
||||
Vector ClosestOrtho(void);
|
||||
void MakeMaxMin(Vector *maxv, Vector *minv);
|
||||
Vector ClampWithin(double minv, double maxv);
|
||||
static bool BoundingBoxesDisjoint(Vector amax, Vector amin,
|
||||
Vector bmax, Vector bmin);
|
||||
static bool BoundingBoxIntersectsLine(Vector amax, Vector amin,
|
||||
|
|
|
@ -231,6 +231,8 @@ void glxBitmapCharQuad(char c, double x, double y);
|
|||
#define TEXTURE_BACKGROUND_IMG 10
|
||||
#define TEXTURE_BITMAP_FONT 20
|
||||
#define TEXTURE_DRAW_PIXELS 30
|
||||
#define TEXTURE_COLOR_PICKER_2D 40
|
||||
#define TEXTURE_COLOR_PICKER_1D 50
|
||||
|
||||
|
||||
#define arraylen(x) (sizeof((x))/sizeof((x)[0]))
|
||||
|
|
|
@ -324,9 +324,7 @@ void TextWindow::ScreenCreateCustomStyle(int link, DWORD v) {
|
|||
|
||||
void TextWindow::ScreenChangeBackgroundColor(int link, DWORD v) {
|
||||
DWORD rgb = SS.backgroundColor;
|
||||
char str[300];
|
||||
sprintf(str, "%.2f, %.2f, %.2f", REDf(rgb), GREENf(rgb), BLUEf(rgb));
|
||||
SS.TW.ShowEditControl(v, 3, str);
|
||||
SS.TW.ShowEditControlWithColorPicker(v, 3, rgb);
|
||||
SS.TW.edit.meaning = EDIT_BACKGROUND_COLOR;
|
||||
}
|
||||
|
||||
|
@ -536,9 +534,7 @@ void TextWindow::ScreenChangeStyleColor(int link, DWORD v) {
|
|||
} else {
|
||||
oops();
|
||||
}
|
||||
char str[300];
|
||||
sprintf(str, "%.2f, %.2f, %.2f", REDf(rgb), GREENf(rgb), BLUEf(rgb));
|
||||
SS.TW.ShowEditControl(row, col, str);
|
||||
SS.TW.ShowEditControlWithColorPicker(row, col, rgb);
|
||||
SS.TW.edit.style = hs;
|
||||
SS.TW.edit.meaning = em;
|
||||
}
|
||||
|
|
364
textwin.cpp
364
textwin.cpp
|
@ -67,6 +67,7 @@ void TextWindow::ClearSuper(void) {
|
|||
}
|
||||
|
||||
void TextWindow::HideEditControl(void) {
|
||||
editControl.colorPicker.show = false;
|
||||
HideTextEditControl();
|
||||
}
|
||||
|
||||
|
@ -80,6 +81,21 @@ void TextWindow::ShowEditControl(int halfRow, int col, char *s) {
|
|||
ShowTextEditControl(x - 3, y + 2, s);
|
||||
}
|
||||
|
||||
void TextWindow::ShowEditControlWithColorPicker(int halfRow, int col, DWORD rgb)
|
||||
{
|
||||
char str[1024];
|
||||
sprintf(str, "%.2f, %.2f, %.2f", REDf(rgb), GREENf(rgb), BLUEf(rgb));
|
||||
|
||||
SS.later.showTW = true;
|
||||
|
||||
editControl.colorPicker.show = true;
|
||||
editControl.colorPicker.rgb = rgb;
|
||||
editControl.colorPicker.h = 0;
|
||||
editControl.colorPicker.s = 0;
|
||||
editControl.colorPicker.v = 1;
|
||||
ShowEditControl(halfRow, col, str);
|
||||
}
|
||||
|
||||
void TextWindow::ClearScreen(void) {
|
||||
int i, j;
|
||||
for(i = 0; i < MAX_ROWS; i++) {
|
||||
|
@ -295,6 +311,17 @@ void TextWindow::Show(void) {
|
|||
}
|
||||
}
|
||||
Printf(false, "");
|
||||
|
||||
// Make sure there's room for the color picker
|
||||
if(editControl.colorPicker.show) {
|
||||
int pickerHeight = 25;
|
||||
int halfRow = editControl.halfRow;
|
||||
if(top[rows-1] - halfRow < pickerHeight && rows < MAX_ROWS) {
|
||||
rows++;
|
||||
top[rows-1] = halfRow + pickerHeight;
|
||||
}
|
||||
}
|
||||
|
||||
InvalidateText();
|
||||
}
|
||||
|
||||
|
@ -430,6 +457,330 @@ void TextWindow::DrawOrHitTestIcons(int how, double mx, double my)
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Given (x, y, z) = (h, s, v) in [0,6), [0,1], [0,1], return (x, y, z) =
|
||||
// (r, g, b) all in [0, 1].
|
||||
//----------------------------------------------------------------------------
|
||||
Vector TextWindow::HsvToRgb(Vector hsv) {
|
||||
if(hsv.x >= 6) hsv.x -= 6;
|
||||
|
||||
Vector rgb;
|
||||
double hmod2 = hsv.x;
|
||||
while(hmod2 >= 2) hmod2 -= 2;
|
||||
double x = (1 - fabs(hmod2 - 1));
|
||||
if(hsv.x < 1) {
|
||||
rgb = Vector::From(1, x, 0);
|
||||
} else if(hsv.x < 2) {
|
||||
rgb = Vector::From(x, 1, 0);
|
||||
} else if(hsv.x < 3) {
|
||||
rgb = Vector::From(0, 1, x);
|
||||
} else if(hsv.x < 4) {
|
||||
rgb = Vector::From(0, x, 1);
|
||||
} else if(hsv.x < 5) {
|
||||
rgb = Vector::From(x, 0, 1);
|
||||
} else {
|
||||
rgb = Vector::From(1, 0, x);
|
||||
}
|
||||
double c = hsv.y*hsv.z;
|
||||
double m = 1 - hsv.z;
|
||||
rgb = rgb.ScaledBy(c);
|
||||
rgb = rgb.Plus(Vector::From(m, m, m));
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
BYTE *TextWindow::HsvPattern2d(void) {
|
||||
static BYTE Texture[256*256*3];
|
||||
static bool Init;
|
||||
|
||||
if(!Init) {
|
||||
int i, j, p;
|
||||
p = 0;
|
||||
for(i = 0; i < 256; i++) {
|
||||
for(j = 0; j < 256; j++) {
|
||||
Vector hsv = Vector::From(6.0*i/255.0, 1.0*j/255.0, 1);
|
||||
Vector rgb = HsvToRgb(hsv);
|
||||
rgb = rgb.ScaledBy(255);
|
||||
Texture[p++] = (BYTE)rgb.x;
|
||||
Texture[p++] = (BYTE)rgb.y;
|
||||
Texture[p++] = (BYTE)rgb.z;
|
||||
}
|
||||
}
|
||||
Init = true;
|
||||
}
|
||||
return Texture;
|
||||
}
|
||||
|
||||
BYTE *TextWindow::HsvPattern1d(double h, double s) {
|
||||
static BYTE Texture[256*4];
|
||||
|
||||
int i, p;
|
||||
p = 0;
|
||||
for(i = 0; i < 256; i++) {
|
||||
Vector hsv = Vector::From(6*h, s, 1.0*(255 - i)/255.0);
|
||||
Vector rgb = HsvToRgb(hsv);
|
||||
rgb = rgb.ScaledBy(255);
|
||||
Texture[p++] = (BYTE)rgb.x;
|
||||
Texture[p++] = (BYTE)rgb.y;
|
||||
Texture[p++] = (BYTE)rgb.z;
|
||||
// Needs a padding byte, to make things four-aligned
|
||||
p++;
|
||||
}
|
||||
return Texture;
|
||||
}
|
||||
|
||||
void TextWindow::ColorPickerDone(void) {
|
||||
char str[1024];
|
||||
DWORD rgb = editControl.colorPicker.rgb;
|
||||
sprintf(str, "%.2f, %.2f, %.3f", REDf(rgb), GREENf(rgb), BLUEf(rgb));
|
||||
EditControlDone(str);
|
||||
}
|
||||
|
||||
bool TextWindow::DrawOrHitTestColorPicker(int how, bool leftDown,
|
||||
double x, double y)
|
||||
{
|
||||
bool mousePointerAsHand = false;
|
||||
|
||||
if(how == HOVER && !leftDown) {
|
||||
editControl.colorPicker.picker1dActive = false;
|
||||
editControl.colorPicker.picker2dActive = false;
|
||||
}
|
||||
|
||||
if(!editControl.colorPicker.show) return false;
|
||||
if(how == CLICK || (how == HOVER && leftDown)) InvalidateText();
|
||||
|
||||
static const DWORD BaseColor[12] = {
|
||||
RGB(255, 0, 0),
|
||||
RGB( 0, 255, 0),
|
||||
RGB( 0, 0, 255),
|
||||
|
||||
RGB( 0, 255, 255),
|
||||
RGB(255, 0, 255),
|
||||
RGB(255, 255, 0),
|
||||
|
||||
RGB(255, 127, 0),
|
||||
RGB(255, 0, 127),
|
||||
RGB( 0, 255, 127),
|
||||
RGB(127, 255, 0),
|
||||
RGB(127, 0, 255),
|
||||
RGB( 0, 127, 255),
|
||||
};
|
||||
|
||||
int width, height;
|
||||
GetTextWindowSize(&width, &height);
|
||||
|
||||
int px = LEFT_MARGIN + CHAR_WIDTH*editControl.col;
|
||||
int py = (editControl.halfRow - SS.TW.scrollPos)*(LINE_HEIGHT/2);
|
||||
|
||||
py += LINE_HEIGHT + 5;
|
||||
|
||||
static const int WIDTH = 16, HEIGHT = 12;
|
||||
static const int PITCH = 18, SIZE = 15;
|
||||
|
||||
px = min(px, width - (WIDTH*PITCH + 40));
|
||||
|
||||
int pxm = px + WIDTH*PITCH + 11,
|
||||
pym = py + HEIGHT*PITCH + 7;
|
||||
|
||||
int bw = 6;
|
||||
if(how == PAINT) {
|
||||
glColor4d(0.2, 0.2, 0.2, 1);
|
||||
glxAxisAlignedQuad(px, pxm+bw, py, pym+bw);
|
||||
glColor4d(0.0, 0.0, 0.0, 1);
|
||||
glxAxisAlignedQuad(px+(bw/2), pxm+(bw/2), py+(bw/2), pym+(bw/2));
|
||||
} else {
|
||||
if(x < px || x > pxm+(bw/2) ||
|
||||
y < py || y > pym+(bw/2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
px += (bw/2);
|
||||
py += (bw/2);
|
||||
|
||||
int i, j;
|
||||
for(i = 0; i < WIDTH/2; i++) {
|
||||
for(j = 0; j < HEIGHT; j++) {
|
||||
Vector rgb;
|
||||
DWORD d;
|
||||
if(i == 0 && j < 8) {
|
||||
d = SS.modelColor[j];
|
||||
rgb = Vector::From(REDf(d), GREENf(d), BLUEf(d));
|
||||
} else if(i == 0) {
|
||||
double a = (j - 8.0)/3.0;
|
||||
rgb = Vector::From(a, a, a);
|
||||
} else {
|
||||
d = BaseColor[j];
|
||||
rgb = Vector::From(REDf(d), GREENf(d), BLUEf(d));
|
||||
if(i >= 2 && i <= 4) {
|
||||
double a = (i == 2) ? 0.2 : (i == 3) ? 0.3 : 0.4;
|
||||
rgb = rgb.Plus(Vector::From(a, a, a));
|
||||
}
|
||||
if(i >= 5 && i <= 7) {
|
||||
double a = (i == 5) ? 0.7 : (i == 6) ? 0.4 : 0.18;
|
||||
rgb = rgb.ScaledBy(a);
|
||||
}
|
||||
}
|
||||
|
||||
rgb = rgb.ClampWithin(0, 1);
|
||||
int sx = px + 5 + PITCH*(i + 8) + 4, sy = py + 5 + PITCH*j;
|
||||
|
||||
if(how == PAINT) {
|
||||
glColor4d(CO(rgb), 1);
|
||||
glxAxisAlignedQuad(sx, sx+SIZE, sy, sy+SIZE);
|
||||
} else if(how == CLICK) {
|
||||
if(x >= sx && x <= sx+SIZE && y >= sy && y <= sy+SIZE) {
|
||||
editControl.colorPicker.rgb = RGBf(rgb.x, rgb.y, rgb.z);
|
||||
ColorPickerDone();
|
||||
}
|
||||
} else if(how == HOVER) {
|
||||
if(x >= sx && x <= sx+SIZE && y >= sy && y <= sy+SIZE) {
|
||||
mousePointerAsHand = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int hxm, hym;
|
||||
int hx = px + 5, hy = py + 5;
|
||||
hxm = hx + PITCH*7 + SIZE;
|
||||
hym = hy + PITCH*2 + SIZE;
|
||||
if(how == PAINT) {
|
||||
glxColorRGB(editControl.colorPicker.rgb);
|
||||
glxAxisAlignedQuad(hx, hxm, hy, hym);
|
||||
} else if(how == CLICK) {
|
||||
if(x >= hx && x <= hxm && y >= hy && y <= hym) {
|
||||
ColorPickerDone();
|
||||
}
|
||||
} else if(how == HOVER) {
|
||||
if(x >= hx && x <= hxm && y >= hy && y <= hym) {
|
||||
mousePointerAsHand = true;
|
||||
}
|
||||
}
|
||||
|
||||
hy += PITCH*3;
|
||||
|
||||
hxm = hx + PITCH*7 + SIZE;
|
||||
hym = hy + PITCH*1 + SIZE;
|
||||
// The one-dimensional thing to pick the color's value
|
||||
if(how == PAINT) {
|
||||
glBindTexture(GL_TEXTURE_2D, TEXTURE_COLOR_PICKER_1D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 256, 0,
|
||||
GL_RGB, GL_UNSIGNED_BYTE,
|
||||
HsvPattern1d(editControl.colorPicker.h,
|
||||
editControl.colorPicker.s));
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2d(0, 0);
|
||||
glVertex2d(hx, hy);
|
||||
|
||||
glTexCoord2d(1, 0);
|
||||
glVertex2d(hx, hym);
|
||||
|
||||
glTexCoord2d(1, 1);
|
||||
glVertex2d(hxm, hym);
|
||||
|
||||
glTexCoord2d(0, 1);
|
||||
glVertex2d(hxm, hy);
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
double cx = hx+(hxm-hx)*(1 - editControl.colorPicker.v);
|
||||
glColor4d(0, 0, 0, 1);
|
||||
glLineWidth(1);
|
||||
glBegin(GL_LINES);
|
||||
glVertex2d(cx, hy);
|
||||
glVertex2d(cx, hym);
|
||||
glEnd();
|
||||
glEnd();
|
||||
} else if(how == CLICK ||
|
||||
(how == HOVER && leftDown && editControl.colorPicker.picker1dActive))
|
||||
{
|
||||
if(x >= hx && x <= hxm && y >= hy && y <= hym) {
|
||||
editControl.colorPicker.v = 1 - (x - hx)/(hxm - hx);
|
||||
|
||||
Vector rgb = HsvToRgb(Vector::From(
|
||||
6*editControl.colorPicker.h,
|
||||
editControl.colorPicker.s,
|
||||
editControl.colorPicker.v));
|
||||
editControl.colorPicker.rgb = RGBf(rgb.x, rgb.y, rgb.z);
|
||||
|
||||
editControl.colorPicker.picker1dActive = true;
|
||||
}
|
||||
}
|
||||
// and advance our vertical position
|
||||
hy += PITCH*2;
|
||||
|
||||
hxm = hx + PITCH*7 + SIZE;
|
||||
hym = hy + PITCH*6 + SIZE;
|
||||
// Two-dimensional thing to pick a color by hue and saturation
|
||||
if(how == PAINT) {
|
||||
glBindTexture(GL_TEXTURE_2D, TEXTURE_COLOR_PICKER_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0,
|
||||
GL_RGB, GL_UNSIGNED_BYTE, HsvPattern2d());
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2d(0, 0);
|
||||
glVertex2d(hx, hy);
|
||||
|
||||
glTexCoord2d(1, 0);
|
||||
glVertex2d(hx, hym);
|
||||
|
||||
glTexCoord2d(1, 1);
|
||||
glVertex2d(hxm, hym);
|
||||
|
||||
glTexCoord2d(0, 1);
|
||||
glVertex2d(hxm, hy);
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glColor4d(1, 1, 1, 1);
|
||||
glLineWidth(1);
|
||||
double cx = hx+(hxm-hx)*editControl.colorPicker.h,
|
||||
cy = hy+(hym-hy)*editControl.colorPicker.s;
|
||||
glBegin(GL_LINES);
|
||||
glVertex2d(cx - 5, cy);
|
||||
glVertex2d(cx + 4, cy);
|
||||
glVertex2d(cx, cy - 5);
|
||||
glVertex2d(cx, cy + 4);
|
||||
glEnd();
|
||||
} else if(how == CLICK ||
|
||||
(how == HOVER && leftDown && editControl.colorPicker.picker2dActive))
|
||||
{
|
||||
if(x >= hx && x <= hxm && y >= hy && y <= hym) {
|
||||
double h = (x - hx)/(hxm - hx),
|
||||
s = (y - hy)/(hym - hy);
|
||||
editControl.colorPicker.h = h;
|
||||
editControl.colorPicker.s = s;
|
||||
|
||||
Vector rgb = HsvToRgb(Vector::From(
|
||||
6*editControl.colorPicker.h,
|
||||
editControl.colorPicker.s,
|
||||
editControl.colorPicker.v));
|
||||
editControl.colorPicker.rgb = RGBf(rgb.x, rgb.y, rgb.z);
|
||||
|
||||
editControl.colorPicker.picker2dActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
SetMousePointerToHand(mousePointerAsHand);
|
||||
return true;
|
||||
}
|
||||
|
||||
void TextWindow::Paint(void) {
|
||||
int width, height;
|
||||
GetTextWindowSize(&width, &height);
|
||||
|
@ -446,7 +797,8 @@ void TextWindow::Paint(void) {
|
|||
|
||||
glTranslated(-1, 1, 0);
|
||||
glScaled(2.0/width, -2.0/height, 1);
|
||||
glTranslated(0, 0, 0);
|
||||
// Make things round consistently, avoiding exact integer boundary
|
||||
glTranslated(-0.1, -0.1, 0);
|
||||
|
||||
halfRows = height / (LINE_HEIGHT/2);
|
||||
|
||||
|
@ -580,10 +932,18 @@ void TextWindow::Paint(void) {
|
|||
|
||||
// The header has some icons that are drawn separately from the text
|
||||
DrawOrHitTestIcons(PAINT, 0, 0);
|
||||
|
||||
// And we may show a color picker for certain editable fields
|
||||
DrawOrHitTestColorPicker(PAINT, false, 0, 0);
|
||||
}
|
||||
|
||||
void TextWindow::MouseEvent(bool leftClick, double x, double y) {
|
||||
void TextWindow::MouseEvent(bool leftClick, bool leftDown, double x, double y) {
|
||||
if(TextEditControlIsVisible() || GraphicsEditControlIsVisible()) {
|
||||
if(DrawOrHitTestColorPicker(leftClick ? CLICK : HOVER, leftDown, x, y))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(leftClick) {
|
||||
HideEditControl();
|
||||
HideGraphicsEditControl();
|
||||
|
|
17
ui.h
17
ui.h
|
@ -69,7 +69,7 @@ public:
|
|||
|
||||
// These are called by the platform-specific code.
|
||||
void Paint(void);
|
||||
void MouseEvent(bool leftDown, double x, double y);
|
||||
void MouseEvent(bool isClick, bool leftDown, double x, double y);
|
||||
void MouseScroll(double x, double y, int delta);
|
||||
void MouseLeave(void);
|
||||
void ScrollbarEvent(int newPos);
|
||||
|
@ -81,6 +81,12 @@ public:
|
|||
void TimerCallback(void);
|
||||
Point2d oldMousePos;
|
||||
HideShowIcon *hoveredIcon, *tooltippedIcon;
|
||||
|
||||
Vector HsvToRgb(Vector hsv);
|
||||
BYTE *HsvPattern2d(void);
|
||||
BYTE *HsvPattern1d(double h, double s);
|
||||
void ColorPickerDone(void);
|
||||
bool DrawOrHitTestColorPicker(int how, bool leftDown, double x, double y);
|
||||
|
||||
void Init(void);
|
||||
void MakeColorTable(const Color *in, float *out);
|
||||
|
@ -181,11 +187,18 @@ public:
|
|||
int halfRow;
|
||||
int col;
|
||||
|
||||
bool showColorPicker;
|
||||
struct {
|
||||
DWORD rgb;
|
||||
double h, s, v;
|
||||
bool show;
|
||||
bool picker1dActive;
|
||||
bool picker2dActive;
|
||||
} colorPicker;
|
||||
} editControl;
|
||||
|
||||
void HideEditControl(void);
|
||||
void ShowEditControl(int halfRow, int col, char *s);
|
||||
void ShowEditControlWithColorPicker(int halfRow, int col, DWORD rgb);
|
||||
|
||||
void ClearSuper(void);
|
||||
|
||||
|
|
14
util.cpp
14
util.cpp
|
@ -736,6 +736,20 @@ Vector Vector::ClosestOrtho(void) {
|
|||
}
|
||||
}
|
||||
|
||||
Vector Vector::ClampWithin(double minv, double maxv) {
|
||||
Vector ret = *this;
|
||||
|
||||
if(ret.x < minv) ret.x = minv;
|
||||
if(ret.y < minv) ret.y = minv;
|
||||
if(ret.z < minv) ret.z = minv;
|
||||
|
||||
if(ret.x > maxv) ret.x = maxv;
|
||||
if(ret.y > maxv) ret.y = maxv;
|
||||
if(ret.z > maxv) ret.z = maxv;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Vector::MakeMaxMin(Vector *maxv, Vector *minv) {
|
||||
maxv->x = max(maxv->x, x);
|
||||
maxv->y = max(maxv->y, y);
|
||||
|
|
|
@ -458,7 +458,7 @@ LRESULT CALLBACK TextWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
// And process the actual message
|
||||
int x = LOWORD(lParam);
|
||||
int y = HIWORD(lParam);
|
||||
SS.TW.MouseEvent(msg == WM_LBUTTONDOWN, x, y);
|
||||
SS.TW.MouseEvent(msg == WM_LBUTTONDOWN, wParam & MK_LBUTTON, x, y);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
O(n*log(n)) assembly of edges into contours
|
||||
good color picker
|
||||
make group model color use new color picker
|
||||
fix anti-aliased edge bug with filled contours
|
||||
crude DXF, HPGL import
|
||||
a request to import a plane thing
|
||||
make export assemble only contours in same group
|
||||
|
|
Loading…
Reference in New Issue