Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Suggestion] [Windows] Use a Flutter widget for top resizing region overlay #48

Closed
damywise opened this issue Jan 15, 2022 · 9 comments
Closed

Comments

@damywise
Copy link
Contributor

damywise commented Jan 15, 2022

If anything else fail, I suggest we make a widget that simulates the original behavior for the top region of the app in titleBarStyle hidden.
When said widget is hovered, change the cursor to SystemMouseCursors.resizeUp or resizeUpLeftDownRight or resizeUpRightDownLeft.
When said widget is clicked, call native event for resizing like in the now discontinued window_utils package, there exist a function startResize(DragPosition position).

@damywise
Copy link
Contributor Author

Changed my mind. Now I think this is a stupid suggestion lol.
Might as well replace all borders with widgets.

@damywise damywise changed the title [Suggestion] [Windows] Use a Flutter widget for top resizing region overlay [Suggestion] [Windows] Use a Flutter widget for resizing region overlay Jan 16, 2022
@damywise damywise changed the title [Suggestion] [Windows] Use a Flutter widget for resizing region overlay [Suggestion] [Windows] Use a Flutter widget for top resizing region overlay Jan 17, 2022
@damywise
Copy link
Contributor Author

I managed to do this btw except when double clicking the top border doesn't do anything when it should've maximised the window vertically.

@damywise damywise reopened this Jan 17, 2022
@lijy91
Copy link
Member

lijy91 commented Jan 17, 2022

Can you share your code?

@damywise
Copy link
Contributor Author

damywise commented Jan 17, 2022

Here's the widget code,

import 'package:flutter/material.dart';
import 'package:window_manager/window_manager.dart';

class WindowsFrame extends StatefulWidget {
  final Widget child;
  final bool active;

  const WindowsFrame({
    Key? key,
    required this.child,
    required this.active,
  }) : super(key: key);

  @override
  State<WindowsFrame> createState() => _WindowsFrameState();
}

class _WindowsFrameState extends State<WindowsFrame> with WindowListener {
  final ValueNotifier<bool> isMaximised = ValueNotifier(false);

  @override
  void initState() {
    windowManager.addListener(this);
    super.initState();
  }

  @override
  void onWindowMaximize() {
    super.onWindowMaximize();
    setState(() {
      isMaximised.value = true;
    });
  }

  @override
  void onWindowUnmaximize() {
    super.onWindowUnmaximize();
    setState(() {
      isMaximised.value = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (!widget.active) return widget.child;
    const width = 8.0;
    const height = 8.0;
    return Stack(
      children: [
        /// App
        ValueListenableBuilder(
          valueListenable: isMaximised,
          builder: (BuildContext context, bool value, Widget? child) =>
              Container(
            padding: value ? const EdgeInsets.only(top: 8) : null,
            decoration: BoxDecoration(
              border: Border(
                top: BorderSide(color: Colors.black.withOpacity(.56), width: 1),
              ),
            ),
            child: widget.child,
          ),
        ),

        /// Resizing widgets
        Stack(
          fit: StackFit.expand,
          children: <Widget>[
            Positioned(
              top: 0,
              left: 0,
              height: height,
              width: width,
              child: MouseRegion(
                cursor: !isMaximised.value
                    ? SystemMouseCursors.resizeUpLeft
                    : SystemMouseCursors.basic,
                child: GestureDetector(
                  onPanStart: (_) =>
                      windowManager.startResize(DragPosition.topLeft),
                ),
              ),
            ),
            Positioned(
              top: 0,
              left: width,
              right: width,
              height: height,
              child: MouseRegion(
                cursor: !isMaximised.value
                    ? SystemMouseCursors.resizeUpDown
                    : SystemMouseCursors.basic,
                child: GestureDetector(
                  //TODO: doubleTap Maximize Vertical
                  onPanStart: (_) =>
                      windowManager.startResize(DragPosition.top),
                ),
              ),
            ),
            Positioned(
              top: 0,
              right: 0,
              height: height,
              width: width,
              child: MouseRegion(
                cursor: !isMaximised.value
                    ? SystemMouseCursors.resizeUpRight
                    : SystemMouseCursors.basic,
                child: GestureDetector(
                  onPanStart: (_) =>
                      windowManager.startResize(DragPosition.topRight),
                ),
              ),
            ),
          ],
        ),
      ],
    );
  }
}

@damywise
Copy link
Contributor Author

I added this to window_manager.dart

  Future<void> startResize(DragPosition position) {
    return _channel.invokeMethod<bool>(
      'startResize',
      {
        "top": position == DragPosition.top ||
            position == DragPosition.topLeft ||
            position == DragPosition.topRight,
        "bottom": position == DragPosition.bottom ||
            position == DragPosition.bottomLeft ||
            position == DragPosition.bottomRight,
        "right": position == DragPosition.right ||
            position == DragPosition.topRight ||
            position == DragPosition.bottomRight,
        "left": position == DragPosition.left ||
            position == DragPosition.topLeft ||
            position == DragPosition.bottomLeft,
      },
    );
  }
enum DragPosition {
  top,
  left,
  right,
  bottom,
  topLeft,
  bottomLeft,
  topRight,
  bottomRight
}

@damywise
Copy link
Contributor Author

damywise commented Jan 17, 2022

In window_manager_plugin.cpp

	else if (method_name.compare("startResize") == 0)
	{
        const flutter::EncodableMap &args = std::get<flutter::EncodableMap>(*method_call.arguments());
        window_manager->StartResize(args);
        result->Success(flutter::EncodableValue(true));
	}

@damywise
Copy link
Contributor Author

In window_manager.cpp

    void WindowManager::StartResize(const flutter::EncodableMap &args);
void WindowManager::StartResize(const flutter::EncodableMap &args)
{
	bool top = std::get<bool>(args.at(flutter::EncodableValue("top")));
	bool bottom = std::get<bool>(args.at(flutter::EncodableValue("bottom")));
	bool left = std::get<bool>(args.at(flutter::EncodableValue("left")));
	bool right = std::get<bool>(args.at(flutter::EncodableValue("right")));
	HWND hWnd = GetMainWindow();
	ReleaseCapture();
	LONG command = SC_SIZE;
	if (top && !bottom && !right && !left)
	{
	  command |= WMSZ_TOP;
	}
	else if (top && left && !bottom && !right)
	{
	  command |= WMSZ_TOPLEFT;
	}
	else if (left && !top && !bottom && !right)
	{
	  command |= WMSZ_LEFT;
	}
	else if (right && !top && !left && !bottom)
	{
	  command |= WMSZ_RIGHT;
	}
	else if (top && right && !left && !bottom)
	{
	  command |= WMSZ_TOPRIGHT;
	}
	else if (bottom && !top && !right && !left)
	{
	  command |= WMSZ_BOTTOM;
	}
	else if (bottom && left && !top && !right)
	{
	  command |= WMSZ_BOTTOMLEFT;
	}
	else if (bottom && right && !top && !left)
	{
	  command |= WMSZ_BOTTOMRIGHT;
	}
	SendMessage(hWnd, WM_SYSCOMMAND, command, 0);
}

@damywise
Copy link
Contributor Author

damywise commented Feb 4, 2022

Should I make a PR for the startResize() function?

@lijy91
Copy link
Member

lijy91 commented Feb 20, 2022

Merged pr and added DragToResizeArea example in main branch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants