Skip to content

Commit

Permalink
Allow docking text window into graphics window.
Browse files Browse the repository at this point in the history
It can be convenient to dock the text window onto the graphics
window, e.g. for fullscreen support, for window managers that
don't handle two side-by-side windows easily, for ease of dragging,
etc. Also, emscripten only provides access to one OpenGL context,
so it's a requirement for a WebGL port.

This isn't yet fully usable: it misses scrollbar support, and
there is no way to resize the dock.
  • Loading branch information
whitequark committed Nov 19, 2016
1 parent 4362954 commit b7a605c
Show file tree
Hide file tree
Showing 14 changed files with 228 additions and 151 deletions.
10 changes: 10 additions & 0 deletions src/confscreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)");
Expand Down Expand Up @@ -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);
Expand Down
22 changes: 14 additions & 8 deletions src/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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());
Expand Down
6 changes: 3 additions & 3 deletions src/graphicswin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ void GraphicsWindow::Init() {
drawOccludedAs = DrawOccludedAs::INVISIBLE;

showTextWindow = true;
ShowTextWindow(showTextWindow);
ShowTextWindow(showTextWindow && !dockTextWindow);

showSnapGrid = false;
context.active = false;
Expand Down Expand Up @@ -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__)
Expand Down Expand Up @@ -722,7 +722,7 @@ void GraphicsWindow::ForceTextWindowShown() {
if(!showTextWindow) {
showTextWindow = true;
CheckMenuByCmd(Command::SHOW_TEXT_WND, /*checked=*/true);
ShowTextWindow(true);
ShowTextWindow(!dockTextWindow);
}
}

Expand Down
59 changes: 53 additions & 6 deletions src/mouse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -498,6 +521,8 @@ void GraphicsWindow::ContextMenuListStyles() {
}

void GraphicsWindow::MouseRightUp(double x, double y) {
if(ConvertMouseCoords(&x, &y)) return;

SS.extraLine.draw = false;
InvalidateGraphics();

Expand Down Expand Up @@ -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()) {
Expand All @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand Down
39 changes: 17 additions & 22 deletions src/platform/cocoamain.mm
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ - (void) updateTrackingAreas
}

- (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,
Expand All @@ -311,15 +311,15 @@ - (void)otherMouseDragged:(NSEvent*)event {
}

- (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)
SolveSpace::SS.GW.MouseLeftDoubleClick(point.x, point.y);
}

- (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);
}

Expand All @@ -328,18 +328,18 @@ - (void)otherMouseDown:(NSEvent*)event {
}

- (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]);
}

Expand Down Expand Up @@ -369,16 +369,11 @@ - (void)keyDown:(NSEvent*)event {
}

- (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];
}

Expand All @@ -404,12 +399,11 @@ - (void)cancelOperation:(id)sender {
[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

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -1062,7 +1057,7 @@ void GetTextWindowSize(int *w, int *h) {
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]];
Expand Down

0 comments on commit b7a605c

Please sign in to comment.