Compare commits
1 Commits
master
...
single-win
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b7a605c44c |
|
@ -161,6 +161,11 @@ void TextWindow::ScreenChangeAutosaveInterval(int link, uint32_t v) {
|
|||
SS.TW.edit.meaning = Edit::AUTOSAVE_INTERVAL;
|
||||
}
|
||||
|
||||
void TextWindow::ScreenChangeTextPaneEnabled(int link, uint32_t v) {
|
||||
SS.GW.dockTextWindow = !SS.GW.dockTextWindow;
|
||||
ShowTextWindow(SS.GW.showTextWindow && !SS.GW.dockTextWindow);
|
||||
}
|
||||
|
||||
void TextWindow::ShowConfiguration() {
|
||||
int i;
|
||||
Printf(true, "%Ft user color (r, g, b)");
|
||||
|
@ -303,6 +308,11 @@ void TextWindow::ShowConfiguration() {
|
|||
Printf(false, "%Ba %d %Fl%Ll%f[change]%E",
|
||||
SS.autosaveInterval, &ScreenChangeAutosaveInterval);
|
||||
|
||||
Printf(false, "");
|
||||
Printf(false, " %Fd%f%Ll%s single window UI%E",
|
||||
&ScreenChangeTextPaneEnabled,
|
||||
SS.GW.dockTextWindow ? CHECK_TRUE : CHECK_FALSE);
|
||||
|
||||
if(canvas) {
|
||||
const char *gl_vendor, *gl_renderer, *gl_version;
|
||||
canvas->GetIdent(&gl_vendor, &gl_renderer, &gl_version);
|
||||
|
|
22
src/draw.cpp
22
src/draw.cpp
|
@ -751,14 +751,7 @@ void GraphicsWindow::Paint() {
|
|||
|
||||
havePainted = true;
|
||||
|
||||
int w, h;
|
||||
GetGraphicsWindowSize(&w, &h);
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
Camera camera = GetCamera();
|
||||
Lighting lighting = GetLighting();
|
||||
|
||||
if(!SS.ActiveGroupsOkay()) {
|
||||
// Draw a different background whenever we're having solve problems.
|
||||
RgbaColor bgColor = Style::Color(Style::DRAW_ERROR);
|
||||
|
@ -770,9 +763,22 @@ void GraphicsWindow::Paint() {
|
|||
ForceTextWindowShown();
|
||||
}
|
||||
|
||||
int windowWidth, windowHeight;
|
||||
GetGraphicsWindowSize(&windowWidth, &windowHeight);
|
||||
if(showTextWindow && dockTextWindow) {
|
||||
width = windowWidth - textDockWidth;
|
||||
height = windowHeight;
|
||||
|
||||
SS.TW.Paint(canvas, windowWidth - textDockWidth, 0, textDockWidth, windowHeight);
|
||||
} else {
|
||||
width = windowWidth;
|
||||
height = windowHeight;
|
||||
}
|
||||
Camera camera = GetCamera();
|
||||
|
||||
auto renderStartTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
canvas->NewFrame();
|
||||
canvas->NewFrame(0, 0, width, height);
|
||||
canvas->SetCamera(camera);
|
||||
canvas->SetLighting(lighting);
|
||||
Draw(canvas.get());
|
||||
|
|
|
@ -235,7 +235,7 @@ void GraphicsWindow::Init() {
|
|||
drawOccludedAs = DrawOccludedAs::INVISIBLE;
|
||||
|
||||
showTextWindow = true;
|
||||
ShowTextWindow(showTextWindow);
|
||||
ShowTextWindow(showTextWindow && !dockTextWindow);
|
||||
|
||||
showSnapGrid = false;
|
||||
context.active = false;
|
||||
|
@ -687,7 +687,7 @@ void GraphicsWindow::EnsureValidActives() {
|
|||
RadioMenuByCmd(Command::UNITS_MM, SS.viewUnits == Unit::MM);
|
||||
RadioMenuByCmd(Command::UNITS_INCHES, SS.viewUnits == Unit::INCHES);
|
||||
|
||||
ShowTextWindow(SS.GW.showTextWindow);
|
||||
ShowTextWindow(showTextWindow && !dockTextWindow);
|
||||
CheckMenuByCmd(Command::SHOW_TEXT_WND, /*checked=*/SS.GW.showTextWindow);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
@ -722,7 +722,7 @@ void GraphicsWindow::ForceTextWindowShown() {
|
|||
if(!showTextWindow) {
|
||||
showTextWindow = true;
|
||||
CheckMenuByCmd(Command::SHOW_TEXT_WND, /*checked=*/true);
|
||||
ShowTextWindow(true);
|
||||
ShowTextWindow(!dockTextWindow);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,9 +75,27 @@ void GraphicsWindow::StartDraggingBySelection() {
|
|||
if(hover.entity.v) StartDraggingByEntity(hover.entity);
|
||||
}
|
||||
|
||||
bool GraphicsWindow::ConvertMouseCoords(double *x, double *y) {
|
||||
if(showTextWindow && dockTextWindow) {
|
||||
if(*x > width) {
|
||||
*x -= width;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert to OpenGL coordinates.
|
||||
*x = *x - width / 2;
|
||||
*y = height / 2 - *y;
|
||||
return false;
|
||||
}
|
||||
|
||||
void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
|
||||
bool middleDown, bool rightDown, bool shiftDown, bool ctrlDown)
|
||||
{
|
||||
bool middleDown, bool rightDown, bool shiftDown, bool ctrlDown) {
|
||||
if(ConvertMouseCoords(&x, &y)) {
|
||||
SS.TW.MouseEvent(/*isClick=*/(leftDown || middleDown || rightDown), leftDown, x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
if(GraphicsEditControlIsVisible()) return;
|
||||
if(context.active) return;
|
||||
|
||||
|
@ -470,6 +488,11 @@ void GraphicsWindow::ClearPending() {
|
|||
}
|
||||
|
||||
void GraphicsWindow::MouseMiddleOrRightDown(double x, double y) {
|
||||
if(ConvertMouseCoords(&x, &y)) {
|
||||
SS.TW.MouseEvent(/*isClick=*/true, /*leftDown=*/false, x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
if(GraphicsEditControlIsVisible()) return;
|
||||
|
||||
orig.offset = offset;
|
||||
|
@ -498,6 +521,8 @@ void GraphicsWindow::ContextMenuListStyles() {
|
|||
}
|
||||
|
||||
void GraphicsWindow::MouseRightUp(double x, double y) {
|
||||
if(ConvertMouseCoords(&x, &y)) return;
|
||||
|
||||
SS.extraLine.draw = false;
|
||||
InvalidateGraphics();
|
||||
|
||||
|
@ -893,7 +918,14 @@ bool GraphicsWindow::ConstrainPointByHovered(hEntity pt) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||
void GraphicsWindow::MouseLeftDown(double origMx, double origMy) {
|
||||
double mx = origMx,
|
||||
my = origMy;
|
||||
if(ConvertMouseCoords(&mx, &my)) {
|
||||
SS.TW.MouseEvent(/*isClick=*/true, /*leftDown=*/true, mx, my);
|
||||
return;
|
||||
}
|
||||
|
||||
orig.mouseDown = true;
|
||||
|
||||
if(GraphicsEditControlIsVisible()) {
|
||||
|
@ -912,7 +944,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
|||
bool hasConstraintSuggestion = SS.GW.pending.hasSuggestion;
|
||||
|
||||
// Make sure the hover is up to date.
|
||||
MouseMoved(mx, my, /*leftDown=*/false, /*middleDown=*/false, /*rightDown=*/false,
|
||||
MouseMoved(origMx, origMy, /*leftDown=*/false, /*middleDown=*/false, /*rightDown=*/false,
|
||||
/*shiftDown=*/false, /*ctrlDown=*/false);
|
||||
orig.mouse.x = mx;
|
||||
orig.mouse.y = my;
|
||||
|
@ -1232,6 +1264,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
|||
}
|
||||
|
||||
void GraphicsWindow::MouseLeftUp(double mx, double my) {
|
||||
if(ConvertMouseCoords(&mx, &my)) return;
|
||||
|
||||
orig.mouseDown = false;
|
||||
hoverWasSelectedOnMousedown = false;
|
||||
|
||||
|
@ -1272,6 +1306,8 @@ void GraphicsWindow::MouseLeftUp(double mx, double my) {
|
|||
}
|
||||
|
||||
void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) {
|
||||
if(ConvertMouseCoords(&mx, &my)) return;
|
||||
|
||||
if(GraphicsEditControlIsVisible()) return;
|
||||
SS.TW.HideEditControl();
|
||||
|
||||
|
@ -1335,13 +1371,19 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) {
|
|||
}
|
||||
hStyle hs = c->disp.style;
|
||||
if(hs.v == 0) hs.v = Style::CONSTRAINT;
|
||||
ShowGraphicsEditControl((int)p2.x, (int)p2.y,
|
||||
SS.TW.editControl.inDock = false;
|
||||
ShowGraphicsEditControl((int)p2.x + width / 2, height / 2 - (int)p2.y,
|
||||
(int)(VectorFont::Builtin()->GetHeight(Style::TextHeight(hs))),
|
||||
editMinWidthChar, editValue);
|
||||
editMinWidthChar, editValue, /*forDock=*/false);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsWindow::EditControlDone(const char *s) {
|
||||
if(SS.TW.editControl.inDock) {
|
||||
SS.TW.EditControlDone(s);
|
||||
return;
|
||||
}
|
||||
|
||||
HideGraphicsEditControl();
|
||||
Constraint *c = SK.GetConstraint(constraintBeingEdited);
|
||||
|
||||
|
@ -1416,6 +1458,11 @@ bool GraphicsWindow::KeyDown(int c) {
|
|||
}
|
||||
|
||||
void GraphicsWindow::MouseScroll(double x, double y, int delta) {
|
||||
if(ConvertMouseCoords(&x, &y)) {
|
||||
// FIXME SS.TW.MouseScroll(x, y, delta);
|
||||
return;
|
||||
}
|
||||
|
||||
double offsetRight = offset.Dot(projRight);
|
||||
double offsetUp = offset.Dot(projUp);
|
||||
|
||||
|
|
|
@ -287,7 +287,7 @@ CONVERT(Rect)
|
|||
}
|
||||
|
||||
- (void)mouseMoved:(NSEvent*)event {
|
||||
NSPoint point = [self ij_to_xy:[self convertPoint:[event locationInWindow] fromView:nil]];
|
||||
NSPoint point = [self xyFromEvent:event];
|
||||
NSUInteger flags = [event modifierFlags];
|
||||
NSUInteger buttons = [NSEvent pressedMouseButtons];
|
||||
SolveSpace::SS.GW.MouseMoved(point.x, point.y,
|
||||
|
@ -311,7 +311,7 @@ CONVERT(Rect)
|
|||
}
|
||||
|
||||
- (void)mouseDown:(NSEvent*)event {
|
||||
NSPoint point = [self ij_to_xy:[self convertPoint:[event locationInWindow] fromView:nil]];
|
||||
NSPoint point = [self xyFromEvent:event];
|
||||
if([event clickCount] == 1)
|
||||
SolveSpace::SS.GW.MouseLeftDown(point.x, point.y);
|
||||
else if([event clickCount] == 2)
|
||||
|
@ -319,7 +319,7 @@ CONVERT(Rect)
|
|||
}
|
||||
|
||||
- (void)rightMouseDown:(NSEvent*)event {
|
||||
NSPoint point = [self ij_to_xy:[self convertPoint:[event locationInWindow] fromView:nil]];
|
||||
NSPoint point = [self xyFromEvent:event];
|
||||
SolveSpace::SS.GW.MouseMiddleOrRightDown(point.x, point.y);
|
||||
}
|
||||
|
||||
|
@ -328,18 +328,18 @@ CONVERT(Rect)
|
|||
}
|
||||
|
||||
- (void)mouseUp:(NSEvent*)event {
|
||||
NSPoint point = [self ij_to_xy:[self convertPoint:[event locationInWindow] fromView:nil]];
|
||||
NSPoint point = [self xyFromEvent:event];
|
||||
SolveSpace::SS.GW.MouseLeftUp(point.x, point.y);
|
||||
}
|
||||
|
||||
- (void)rightMouseUp:(NSEvent*)event {
|
||||
NSPoint point = [self ij_to_xy:[self convertPoint:[event locationInWindow] fromView:nil]];
|
||||
NSPoint point = [self xyFromEvent:event];
|
||||
self->_lastContextMenuEvent = event;
|
||||
SolveSpace::SS.GW.MouseRightUp(point.x, point.y);
|
||||
}
|
||||
|
||||
- (void)scrollWheel:(NSEvent*)event {
|
||||
NSPoint point = [self ij_to_xy:[self convertPoint:[event locationInWindow] fromView:nil]];
|
||||
NSPoint point = [self xyFromEvent:event];
|
||||
SolveSpace::SS.GW.MouseScroll(point.x, point.y, (int)-[event deltaY]);
|
||||
}
|
||||
|
||||
|
@ -369,16 +369,11 @@ CONVERT(Rect)
|
|||
}
|
||||
|
||||
- (void)startEditing:(NSString*)text at:(NSPoint)xy withHeight:(double)fontHeight
|
||||
withMinWidthInChars:(int)minWidthChars {
|
||||
// Convert to ij (vs. xy) style coordinates
|
||||
withMinWidthInChars:(int)minWidthChars usingMonospace:(BOOL)isMonospace {
|
||||
NSSize size = [self convertSizeToBacking:[self bounds].size];
|
||||
NSPoint point = {
|
||||
.x = xy.x + size.width / 2,
|
||||
.y = xy.y - size.height / 2
|
||||
};
|
||||
NSPoint point = [self convertPointFromBacking:NSMakePoint(xy.x, size.height - xy.y)];
|
||||
[[self window] makeKeyWindow];
|
||||
[super startEditing:text at:[self convertPointFromBacking:point]
|
||||
withHeight:fontHeight usingMonospace:FALSE];
|
||||
[super startEditing:text at:point withHeight:fontHeight usingMonospace:isMonospace];
|
||||
[self prepareEditorWithMinWidthInChars:minWidthChars];
|
||||
}
|
||||
|
||||
|
@ -404,12 +399,11 @@ CONVERT(Rect)
|
|||
[self stopEditing];
|
||||
}
|
||||
|
||||
- (NSPoint)ij_to_xy:(NSPoint)ij {
|
||||
// Convert to xy (vs. ij) style coordinates,
|
||||
// with (0, 0) at center
|
||||
- (NSPoint)xyFromEvent:event {
|
||||
NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil]
|
||||
NSSize size = [self bounds].size;
|
||||
return [self convertPointToBacking:(NSPoint){
|
||||
.x = ij.x - size.width / 2, .y = ij.y - size.height / 2 }];
|
||||
.x = point.x, .y = size.height - point.y }];
|
||||
}
|
||||
@end
|
||||
|
||||
|
@ -492,11 +486,12 @@ bool FullScreenIsActive(void) {
|
|||
}
|
||||
|
||||
void ShowGraphicsEditControl(int x, int y, int fontHeight, int minWidthChars,
|
||||
const std::string &str) {
|
||||
const std::string &str, bool forDock) {
|
||||
[GWView startEditing:[NSString stringWithUTF8String:str.c_str()]
|
||||
at:(NSPoint){(CGFloat)x, (CGFloat)y}
|
||||
withHeight:fontHeight
|
||||
withMinWidthInChars:minWidthChars];
|
||||
withHeight:(forDock ? 15 : fontHeight)
|
||||
withMinWidthInChars:minWidthChars
|
||||
usingMonospace:(forDock ? TRUE : FALSE)];
|
||||
}
|
||||
|
||||
void HideGraphicsEditControl(void) {
|
||||
|
@ -1062,7 +1057,7 @@ double GetScreenDpi() {
|
|||
return (displayPixelSize.width / displayPhysicalSize.width) * 25.4f;
|
||||
}
|
||||
|
||||
void InvalidateText(void) {
|
||||
void InvalidateText() {
|
||||
NSSize size = [TWView convertSizeToBacking:[TWView frame].size];
|
||||
size.height = (SS.TW.top[SS.TW.rows - 1] + 1) * TextWindow::LINE_HEIGHT / 2;
|
||||
[TWView setFrameSize:[TWView convertSizeFromBacking:size]];
|
||||
|
|
|
@ -298,6 +298,17 @@ public:
|
|||
glXDestroyContext(_xdisplay, _glcontext);
|
||||
}
|
||||
|
||||
void set_cursor_hand(bool is_hand) {
|
||||
realize();
|
||||
|
||||
Gdk::CursorType type = is_hand ? Gdk::HAND1 : Gdk::ARROW;
|
||||
#ifdef HAVE_GTK3
|
||||
get_window()->set_cursor(Gdk::Cursor::create(type));
|
||||
#else
|
||||
get_window()->set_cursor(Gdk::Cursor(type));
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
/* Draw on a GLX framebuffer object, then read pixels out and draw them on
|
||||
the Cairo context. Slower, but you get to overlay nice widgets. */
|
||||
|
@ -353,6 +364,11 @@ public:
|
|||
|
||||
_entry.signal_activate().
|
||||
connect(sigc::mem_fun(this, &EditorOverlay::on_activate));
|
||||
|
||||
_entry.signal_motion_notify_event().
|
||||
connect(sigc::mem_fun(this, &EditorOverlay::on_editor_motion_notify_event));
|
||||
_entry.signal_button_press_event().
|
||||
connect(sigc::mem_fun(this, &EditorOverlay::on_editor_button_press_event));
|
||||
}
|
||||
|
||||
void start_editing(int x, int y, int font_height, bool is_monospace, int minWidthChars,
|
||||
|
@ -451,6 +467,14 @@ protected:
|
|||
_signal_editing_done(_entry.get_text());
|
||||
}
|
||||
|
||||
bool on_editor_motion_notify_event(GdkEventMotion *event) {
|
||||
return _underlay.event((GdkEvent*) event);
|
||||
}
|
||||
|
||||
bool on_editor_button_press_event(GdkEventButton *event) {
|
||||
return _underlay.event((GdkEvent*) event);
|
||||
}
|
||||
|
||||
private:
|
||||
Gtk::Widget &_underlay;
|
||||
Gtk::Entry _entry;
|
||||
|
@ -495,22 +519,12 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
bool on_configure_event(GdkEventConfigure *event) override {
|
||||
_w = event->width;
|
||||
_h = event->height;
|
||||
|
||||
return GlWidget::on_configure_event(event);;
|
||||
}
|
||||
|
||||
void on_gl_draw() override {
|
||||
SS.GW.Paint();
|
||||
}
|
||||
|
||||
bool on_motion_notify_event(GdkEventMotion *event) override {
|
||||
int x, y;
|
||||
ij_to_xy(event->x, event->y, x, y);
|
||||
|
||||
SS.GW.MouseMoved(x, y,
|
||||
SS.GW.MouseMoved(event->x, event->y,
|
||||
event->state & GDK_BUTTON1_MASK,
|
||||
event->state & GDK_BUTTON2_MASK,
|
||||
event->state & GDK_BUTTON3_MASK,
|
||||
|
@ -521,20 +535,17 @@ protected:
|
|||
}
|
||||
|
||||
bool on_button_press_event(GdkEventButton *event) override {
|
||||
int x, y;
|
||||
ij_to_xy(event->x, event->y, x, y);
|
||||
|
||||
switch(event->button) {
|
||||
case 1:
|
||||
if(event->type == GDK_BUTTON_PRESS)
|
||||
SS.GW.MouseLeftDown(x, y);
|
||||
SS.GW.MouseLeftDown(event->x, event->y);
|
||||
else if(event->type == GDK_2BUTTON_PRESS)
|
||||
SS.GW.MouseLeftDoubleClick(x, y);
|
||||
SS.GW.MouseLeftDoubleClick(event->x, event->y);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
SS.GW.MouseMiddleOrRightDown(x, y);
|
||||
SS.GW.MouseMiddleOrRightDown(event->x, event->y);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -542,16 +553,13 @@ protected:
|
|||
}
|
||||
|
||||
bool on_button_release_event(GdkEventButton *event) override {
|
||||
int x, y;
|
||||
ij_to_xy(event->x, event->y, x, y);
|
||||
|
||||
switch(event->button) {
|
||||
case 1:
|
||||
SS.GW.MouseLeftUp(x, y);
|
||||
SS.GW.MouseLeftUp(event->x, event->y);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
SS.GW.MouseRightUp(x, y);
|
||||
SS.GW.MouseRightUp(event->x, event->y);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -559,10 +567,7 @@ protected:
|
|||
}
|
||||
|
||||
bool on_scroll_event(GdkEventScroll *event) override {
|
||||
int x, y;
|
||||
ij_to_xy(event->x, event->y, x, y);
|
||||
|
||||
SS.GW.MouseScroll(x, y, (int)-DeltaYOfScrollEvent(event));
|
||||
SS.GW.MouseScroll(event->x, event->y, (int)-DeltaYOfScrollEvent(event));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -572,15 +577,6 @@ protected:
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
int _w, _h;
|
||||
void ij_to_xy(double i, double j, int &x, int &y) {
|
||||
// Convert to xy (vs. ij) style coordinates,
|
||||
// with (0, 0) at center
|
||||
x = (int)i - _w / 2;
|
||||
y = _h / 2 - (int)j;
|
||||
}
|
||||
};
|
||||
|
||||
class GraphicsWindowGtk : public Gtk::Window {
|
||||
|
@ -748,16 +744,9 @@ bool FullScreenIsActive(void) {
|
|||
}
|
||||
|
||||
void ShowGraphicsEditControl(int x, int y, int fontHeight, int minWidthChars,
|
||||
const std::string &val) {
|
||||
Gdk::Rectangle rect = GW->get_widget().get_allocation();
|
||||
|
||||
// Convert to ij (vs. xy) style coordinates,
|
||||
// and compensate for the input widget height due to inverse coord
|
||||
int i, j;
|
||||
i = x + rect.get_width() / 2;
|
||||
j = -y + rect.get_height() / 2;
|
||||
|
||||
GW->get_overlay().start_editing(i, j, fontHeight, /*is_monospace=*/false, minWidthChars, val);
|
||||
const std::string &val, bool forDock) {
|
||||
GW->get_overlay().start_editing(x, y, fontHeight,
|
||||
/*is_monospace=*/forDock, minWidthChars, val);
|
||||
}
|
||||
|
||||
void HideGraphicsEditControl(void) {
|
||||
|
@ -1260,34 +1249,22 @@ public:
|
|||
Gdk::LEAVE_NOTIFY_MASK);
|
||||
}
|
||||
|
||||
void set_cursor_hand(bool is_hand) {
|
||||
Glib::RefPtr<Gdk::Window> gdkwin = get_window();
|
||||
if(gdkwin) { // returns NULL if not realized
|
||||
Gdk::CursorType type = is_hand ? Gdk::HAND1 : Gdk::ARROW;
|
||||
#ifdef HAVE_GTK3
|
||||
gdkwin->set_cursor(Gdk::Cursor::create(type));
|
||||
#else
|
||||
gdkwin->set_cursor(Gdk::Cursor(type));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void on_gl_draw() override {
|
||||
SS.TW.Paint();
|
||||
}
|
||||
|
||||
bool on_motion_notify_event(GdkEventMotion *event) override {
|
||||
SS.TW.MouseEvent(/*leftClick*/ false,
|
||||
/*leftDown*/ event->state & GDK_BUTTON1_MASK,
|
||||
SS.TW.MouseEvent(/*isClick=*/false,
|
||||
/*leftDown=*/event->state & GDK_BUTTON1_MASK,
|
||||
event->x, event->y);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool on_button_press_event(GdkEventButton *event) override {
|
||||
SS.TW.MouseEvent(/*leftClick*/ event->type == GDK_BUTTON_PRESS,
|
||||
/*leftDown*/ event->state & GDK_BUTTON1_MASK,
|
||||
SS.TW.MouseEvent(/*isClick=*/event->type == GDK_BUTTON_PRESS,
|
||||
/*leftDown=*/event->state & GDK_BUTTON1_MASK,
|
||||
event->x, event->y);
|
||||
|
||||
return true;
|
||||
|
@ -1333,11 +1310,6 @@ public:
|
|||
|
||||
_overlay.signal_editing_done().
|
||||
connect(sigc::mem_fun(this, &TextWindowGtk::on_editing_done));
|
||||
|
||||
_overlay.get_entry().signal_motion_notify_event().
|
||||
connect(sigc::mem_fun(this, &TextWindowGtk::on_editor_motion_notify_event));
|
||||
_overlay.get_entry().signal_button_press_event().
|
||||
connect(sigc::mem_fun(this, &TextWindowGtk::on_editor_button_press_event));
|
||||
}
|
||||
|
||||
Gtk::VScrollbar &get_scrollbar() {
|
||||
|
@ -1388,14 +1360,6 @@ protected:
|
|||
SS.TW.EditControlDone(value.c_str());
|
||||
}
|
||||
|
||||
bool on_editor_motion_notify_event(GdkEventMotion *event) {
|
||||
return _widget.event((GdkEvent*) event);
|
||||
}
|
||||
|
||||
bool on_editor_button_press_event(GdkEventButton *event) {
|
||||
return _widget.event((GdkEvent*) event);
|
||||
}
|
||||
|
||||
private:
|
||||
Gtk::VScrollbar _scrollbar;
|
||||
TextWidget _widget;
|
||||
|
@ -1423,6 +1387,11 @@ double GetScreenDpi() {
|
|||
}
|
||||
|
||||
void InvalidateText(void) {
|
||||
if(SS.GW.dockTextWindow) {
|
||||
InvalidateGraphics();
|
||||
return;
|
||||
}
|
||||
|
||||
TW->get_widget().queue_draw();
|
||||
}
|
||||
|
||||
|
@ -1431,7 +1400,11 @@ void MoveTextScrollbarTo(int pos, int maxPos, int page) {
|
|||
}
|
||||
|
||||
void SetMousePointerToHand(bool is_hand) {
|
||||
TW->get_widget().set_cursor_hand(is_hand);
|
||||
if(SS.GW.dockTextWindow) {
|
||||
GW->get_widget().set_cursor_hand(is_hand);
|
||||
} else {
|
||||
TW->get_widget().set_cursor_hand(is_hand);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowTextEditControl(int x, int y, const std::string &val) {
|
||||
|
|
|
@ -908,17 +908,12 @@ bool SolveSpace::TextEditControlIsVisible()
|
|||
return IsWindowVisible(TextEditControl) ? true : false;
|
||||
}
|
||||
void SolveSpace::ShowGraphicsEditControl(int x, int y, int fontHeight, int minWidthChars,
|
||||
const std::string &str)
|
||||
const std::string &str, bool forDock)
|
||||
{
|
||||
if(GraphicsEditControlIsVisible()) return;
|
||||
|
||||
RECT r;
|
||||
GetClientRect(GraphicsWnd, &r);
|
||||
x = x + (r.right - r.left)/2;
|
||||
y = (r.bottom - r.top)/2 - y;
|
||||
|
||||
ShowEditControl(GraphicsEditControl, x, y, fontHeight, minWidthChars,
|
||||
/*isMonospace=*/false, Widen(str));
|
||||
/*isMonospace=*/forDock, Widen(str));
|
||||
}
|
||||
void SolveSpace::HideGraphicsEditControl()
|
||||
{
|
||||
|
@ -971,12 +966,6 @@ LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||
tme.hwndTrack = GraphicsWnd;
|
||||
TrackMouseEvent(&tme);
|
||||
|
||||
// Convert to xy (vs. ij) style coordinates, with (0, 0) at center
|
||||
RECT r;
|
||||
GetClientRect(GraphicsWnd, &r);
|
||||
x = x - (r.right - r.left)/2;
|
||||
y = (r.bottom - r.top)/2 - y;
|
||||
|
||||
LastMousePos.x = x;
|
||||
LastMousePos.y = y;
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ public:
|
|||
virtual void SetCamera(const Camera &camera, bool filp = FLIP_FRAMEBUFFER) = 0;
|
||||
virtual void SetLighting(const Lighting &lighting) = 0;
|
||||
|
||||
virtual void NewFrame() = 0;
|
||||
virtual void NewFrame(int left, int top, int width, int height) = 0;
|
||||
virtual void FlushFrame() = 0;
|
||||
virtual std::shared_ptr<Pixmap> ReadFrame() = 0;
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ public:
|
|||
void SetCamera(const Camera &camera, bool filp = FLIP_FRAMEBUFFER) override;
|
||||
void SetLighting(const Lighting &lighting) override;
|
||||
|
||||
void NewFrame() override;
|
||||
void NewFrame(int left, int top, int width, int height) override;
|
||||
void FlushFrame() override;
|
||||
std::shared_ptr<Pixmap> ReadFrame() override;
|
||||
|
||||
|
@ -705,8 +705,6 @@ void OpenGl1Renderer::InvalidatePixmap(std::shared_ptr<const Pixmap> pm) {
|
|||
void OpenGl1Renderer::UpdateProjection(bool flip) {
|
||||
UnSelectPrimitive();
|
||||
|
||||
glViewport(0, 0, camera.width, camera.height);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
|
@ -753,7 +751,11 @@ void OpenGl1Renderer::UpdateProjection(bool flip) {
|
|||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void OpenGl1Renderer::NewFrame() {
|
||||
void OpenGl1Renderer::NewFrame(int left, int top, int width, int height) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(left, top, width, height);
|
||||
glViewport(left, top, width, height);
|
||||
|
||||
glEnable(GL_NORMALIZE);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
|
|
@ -134,7 +134,7 @@ public:
|
|||
void SetCamera(const Camera &c, bool flip) override;
|
||||
void SetLighting(const Lighting &l) override;
|
||||
|
||||
void NewFrame() override;
|
||||
void NewFrame(int left, int top, int width, int height) override;
|
||||
void FlushFrame() override;
|
||||
std::shared_ptr<Pixmap> ReadFrame() override;
|
||||
|
||||
|
@ -542,8 +542,6 @@ void OpenGl2Renderer::DrawPixmap(std::shared_ptr<const Pixmap> pm,
|
|||
}
|
||||
|
||||
void OpenGl2Renderer::UpdateProjection(bool flip) {
|
||||
glViewport(0, 0, camera.width, camera.height);
|
||||
|
||||
double mat1[16];
|
||||
double mat2[16];
|
||||
|
||||
|
@ -611,12 +609,16 @@ void OpenGl2Renderer::UpdateProjection(bool flip) {
|
|||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void OpenGl2Renderer::NewFrame() {
|
||||
void OpenGl2Renderer::NewFrame(int left, int top, int width, int height) {
|
||||
if(!initialized) {
|
||||
Init();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(left, top, width, height);
|
||||
glViewport(left, top, width, height);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
|
|
|
@ -102,6 +102,9 @@ void SolveSpaceUI::Init() {
|
|||
RefreshRecentMenus();
|
||||
// Autosave timer
|
||||
autosaveInterval = CnfThawInt(5, "AutosaveInterval");
|
||||
// Single-window UI
|
||||
GW.dockTextWindow = CnfThawBool(false, "DockTextWindow");
|
||||
GW.textDockWidth = CnfThawInt(420, "TextDockWidth");
|
||||
|
||||
// The default styles (colors, line widths, etc.) are also stored in the
|
||||
// configuration file, but we will automatically load those as we need
|
||||
|
@ -217,6 +220,9 @@ void SolveSpaceUI::Exit() {
|
|||
CnfFreezeBool(showToolbar, "ShowToolbar");
|
||||
// Autosave timer
|
||||
CnfFreezeInt(autosaveInterval, "AutosaveInterval");
|
||||
// Single-window UI
|
||||
CnfFreezeBool(GW.dockTextWindow, "DockTextWindow");
|
||||
CnfFreezeInt(GW.textDockWidth, "TextDockWidth");
|
||||
|
||||
// And the default styles, colors and line widths and such.
|
||||
Style::FreezeDefaultStyles();
|
||||
|
|
|
@ -244,7 +244,7 @@ void RadioMenuByCmd(Command id, bool selected);
|
|||
void EnableMenuByCmd(Command id, bool enabled);
|
||||
|
||||
void ShowGraphicsEditControl(int x, int y, int fontHeight, int minWidthChars,
|
||||
const std::string &str);
|
||||
const std::string &str, bool forDock);
|
||||
void HideGraphicsEditControl();
|
||||
bool GraphicsEditControlIsVisible();
|
||||
void ShowTextEditControl(int x, int y, const std::string &str);
|
||||
|
@ -374,8 +374,10 @@ std::string Basename(std::string filename, bool stripExtension = false);
|
|||
std::string Dirname(std::string filename);
|
||||
bool ReadFile(const std::string &filename, std::string *data);
|
||||
bool WriteFile(const std::string &filename, const std::string &data);
|
||||
|
||||
void Message(const char *str, ...);
|
||||
void Error(const char *str, ...);
|
||||
|
||||
void CnfFreezeBool(bool v, const std::string &name);
|
||||
void CnfFreezeColor(RgbaColor v, const std::string &name);
|
||||
bool CnfThawBool(bool v, const std::string &name);
|
||||
|
@ -749,6 +751,7 @@ public:
|
|||
Unit viewUnits;
|
||||
int afterDecimalMm;
|
||||
int afterDecimalInch;
|
||||
|
||||
int autosaveInterval; // in minutes
|
||||
|
||||
std::string MmToString(double v);
|
||||
|
|
|
@ -251,7 +251,11 @@ void TextWindow::ClearSuper() {
|
|||
|
||||
void TextWindow::HideEditControl() {
|
||||
editControl.colorPicker.show = false;
|
||||
HideTextEditControl();
|
||||
if(editControl.inDock) {
|
||||
HideGraphicsEditControl();
|
||||
} else {
|
||||
HideTextEditControl();
|
||||
}
|
||||
}
|
||||
|
||||
void TextWindow::ShowEditControl(int col, const std::string &str, int halfRow) {
|
||||
|
@ -262,7 +266,13 @@ void TextWindow::ShowEditControl(int col, const std::string &str, int halfRow) {
|
|||
int x = LEFT_MARGIN + CHAR_WIDTH*col;
|
||||
int y = (halfRow - SS.TW.scrollPos)*(LINE_HEIGHT/2);
|
||||
|
||||
ShowTextEditControl(x, y + 18, str);
|
||||
if(SS.GW.dockTextWindow) {
|
||||
editControl.inDock = true;
|
||||
ShowGraphicsEditControl(SS.GW.width + x, y + 18, TextWindow::CHAR_HEIGHT, 30, str,
|
||||
/*forDock=*/true);
|
||||
} else {
|
||||
ShowTextEditControl(x, y + 18, str);
|
||||
}
|
||||
}
|
||||
|
||||
void TextWindow::ShowEditControlWithColorPicker(int col, RgbaColor rgb)
|
||||
|
@ -510,20 +520,33 @@ void TextWindow::Show() {
|
|||
}
|
||||
}
|
||||
|
||||
InvalidateText();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void TextWindow::Invalidate() {
|
||||
if(SS.GW.dockTextWindow && SS.GW.showTextWindow) {
|
||||
InvalidateGraphics();
|
||||
} else {
|
||||
InvalidateText();
|
||||
}
|
||||
}
|
||||
|
||||
void TextWindow::TimerCallback()
|
||||
{
|
||||
tooltippedButton = hoveredButton;
|
||||
InvalidateText();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void TextWindow::DrawOrHitTestIcons(UiCanvas *uiCanvas, TextWindow::DrawOrHitHow how,
|
||||
double mx, double my)
|
||||
{
|
||||
int width, height;
|
||||
GetTextWindowSize(&width, &height);
|
||||
if(SS.GW.dockTextWindow) {
|
||||
GetGraphicsWindowSize(&width, &height);
|
||||
width = SS.GW.textDockWidth;
|
||||
} else {
|
||||
GetTextWindowSize(&width, &height);
|
||||
}
|
||||
|
||||
int x = 20, y = 33 + LINE_HEIGHT;
|
||||
y -= scrollPos*(LINE_HEIGHT/2);
|
||||
|
@ -562,7 +585,7 @@ void TextWindow::DrawOrHitTestIcons(UiCanvas *uiCanvas, TextWindow::DrawOrHitHow
|
|||
}
|
||||
|
||||
if(how != PAINT && hoveredButton != oldHovered) {
|
||||
InvalidateText();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
if(tooltippedButton && !tooltippedButton->Tooltip().empty()) {
|
||||
|
@ -673,7 +696,7 @@ bool TextWindow::DrawOrHitTestColorPicker(UiCanvas *uiCanvas, DrawOrHitHow how,
|
|||
}
|
||||
|
||||
if(!editControl.colorPicker.show) return false;
|
||||
if(how == CLICK || (how == HOVER && leftDown)) InvalidateText();
|
||||
if(how == CLICK || (how == HOVER && leftDown)) Invalidate();
|
||||
|
||||
static const RgbaColor BaseColor[12] = {
|
||||
RGBi(255, 0, 0),
|
||||
|
@ -693,7 +716,13 @@ bool TextWindow::DrawOrHitTestColorPicker(UiCanvas *uiCanvas, DrawOrHitHow how,
|
|||
};
|
||||
|
||||
int width, height;
|
||||
GetTextWindowSize(&width, &height);
|
||||
if(SS.GW.dockTextWindow) {
|
||||
GetGraphicsWindowSize(&width, &height);
|
||||
width = SS.GW.textDockWidth;
|
||||
} else {
|
||||
GetTextWindowSize(&width, &height);
|
||||
}
|
||||
dbp("%d %d %d %d", width, height, (int)x, (int)y);
|
||||
|
||||
int px = LEFT_MARGIN + CHAR_WIDTH*editControl.col;
|
||||
int py = (editControl.halfRow - SS.TW.scrollPos)*(LINE_HEIGHT/2);
|
||||
|
@ -858,6 +887,11 @@ void TextWindow::Paint() {
|
|||
int width, height;
|
||||
GetTextWindowSize(&width, &height);
|
||||
|
||||
Paint(canvas, 0, 0, width, height);
|
||||
}
|
||||
|
||||
void TextWindow::Paint(std::shared_ptr<ViewportCanvas> canvas,
|
||||
int viewportLeft, int viewportTop, int width, int height) {
|
||||
Camera camera = {};
|
||||
camera.width = width;
|
||||
camera.height = height;
|
||||
|
@ -865,7 +899,7 @@ void TextWindow::Paint() {
|
|||
camera.offset.x = -(double)camera.width / 2.0;
|
||||
camera.offset.y = -(double)camera.height / 2.0;
|
||||
|
||||
canvas->NewFrame();
|
||||
canvas->NewFrame(viewportLeft, viewportTop, width, height);
|
||||
canvas->SetCamera(camera);
|
||||
|
||||
UiCanvas uiCanvas = {};
|
||||
|
@ -1062,7 +1096,7 @@ void TextWindow::MouseEvent(bool leftClick, bool leftDown, double x, double y) {
|
|||
prevHoveredCol != hoveredCol)
|
||||
{
|
||||
InvalidateGraphics();
|
||||
InvalidateText();
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1071,7 +1105,7 @@ void TextWindow::MouseLeave() {
|
|||
hoveredButton = NULL;
|
||||
hoveredRow = 0;
|
||||
hoveredCol = 0;
|
||||
InvalidateText();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void TextWindow::ScrollbarEvent(int newPos) {
|
||||
|
@ -1085,7 +1119,7 @@ void TextWindow::ScrollbarEvent(int newPos) {
|
|||
if(newPos != scrollPos) {
|
||||
scrollPos = newPos;
|
||||
MoveTextScrollbarTo(scrollPos, top[rows - 1] + 1, halfRows);
|
||||
InvalidateText();
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
14
src/ui.h
14
src/ui.h
|
@ -203,6 +203,7 @@ public:
|
|||
|
||||
// These are called by the platform-specific code.
|
||||
void Paint();
|
||||
void Paint(std::shared_ptr<ViewportCanvas> canvas, int left, int top, int width, int height);
|
||||
void MouseEvent(bool isClick, bool leftDown, double x, double y);
|
||||
void MouseScroll(double x, double y, int delta);
|
||||
void MouseLeave();
|
||||
|
@ -232,6 +233,7 @@ public:
|
|||
void ClearScreen();
|
||||
|
||||
void Show();
|
||||
void Invalidate();
|
||||
|
||||
// State for the screen that we are showing in the text window.
|
||||
enum class Screen : uint32_t {
|
||||
|
@ -341,6 +343,8 @@ public:
|
|||
bool picker1dActive;
|
||||
bool picker2dActive;
|
||||
} colorPicker;
|
||||
|
||||
bool inDock;
|
||||
} editControl;
|
||||
|
||||
void HideEditControl();
|
||||
|
@ -445,6 +449,7 @@ public:
|
|||
static void ScreenChangeExportOffset(int link, uint32_t v);
|
||||
static void ScreenChangeGCodeParameter(int link, uint32_t v);
|
||||
static void ScreenChangeAutosaveInterval(int link, uint32_t v);
|
||||
static void ScreenChangeTextPaneEnabled(int link, uint32_t v);
|
||||
static void ScreenChangeStyleName(int link, uint32_t v);
|
||||
static void ScreenChangeStyleMetric(int link, uint32_t v);
|
||||
static void ScreenChangeStyleTextAngle(int link, uint32_t v);
|
||||
|
@ -715,12 +720,16 @@ public:
|
|||
Command toolbarTooltipped;
|
||||
int toolbarMouseX, toolbarMouseY;
|
||||
|
||||
// Text window interaction
|
||||
bool showTextWindow;
|
||||
bool dockTextWindow;
|
||||
double textDockWidth;
|
||||
|
||||
// This sets what gets displayed.
|
||||
bool showWorkplanes;
|
||||
bool showNormals;
|
||||
bool showPoints;
|
||||
bool showConstraints;
|
||||
bool showTextWindow;
|
||||
bool showShaded;
|
||||
bool showEdges;
|
||||
bool showOutlines;
|
||||
|
@ -746,8 +755,9 @@ public:
|
|||
|
||||
// These are called by the platform-specific code.
|
||||
void Paint();
|
||||
bool ConvertMouseCoords(double *x, double *y);
|
||||
void MouseMoved(double x, double y, bool leftDown, bool middleDown,
|
||||
bool rightDown, bool shiftDown, bool ctrlDown);
|
||||
bool rightDown, bool shiftDown, bool ctrlDown);
|
||||
void MouseLeftDown(double x, double y);
|
||||
void MouseLeftUp(double x, double y);
|
||||
void MouseLeftDoubleClick(double x, double y);
|
||||
|
|
Loading…
Reference in New Issue
Block a user