Создание собственного курсора и правильная реализация | Использование позиционированного виджета - PullRequest
0 голосов
/ 18 апреля 2020

У меня есть главное дерево файлов дротиков:

Profile
  MaterialApp
    Material
      Stack
        Homepage
        Positioned
          OverlaySizing
        CursorTest

Эти два вопроса - это OverlaySizing и CursorTest Widgets. Основой функциональности c должно быть то, что домашняя страница - это нарисованный снизу виджет, который покрывает всю страницу, средний виджет - это позиционированный виджет с дочерним элементом OverlaySizing, который просто печатает MediaQueries в нижней правой части экрана для целей отладки, а самый верхний нарисованный виджет должен быть квадратным, который использует aws квадрат 10x10, где находится мышь.

Main.dart

import 'package:flutter/material.dart';

import 'themes/themes.dart';

import 'debug/sizing.dart';
import 'debug/featureTesting.dart';

import 'dart:html' as html;

import 'pages/homepage.dart';


//  Entry point for app
void main() {
  runApp(Profile());
}

class Profile extends StatelessWidget {

  //  Starting build function that builds whole widget tree.
  //  Starts with Material app to give default text theme and supplies 
  //    custom color theming.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'TWB',
      theme: originalTheme(),
      home: Material( //  Must surround the page with a Material widget for Material properties.
        child: Stack(
          children: [
            Homepage(),  //  The Homepage widget that the houses the UI
            Positioned(
              bottom: 5,
              right: 5,
              child: OverlaySizing(),  //  Container that prints the MediaQuery info
            ),
            CursorTest(  //  Widget to print a square where the mouse is.
              appContainer: html.window.document.getElementById('app-container'),
            ),
          ],
        ),
      )
    );
  }
}

sizing.dart

import 'package:flutter/material.dart';

//  A wrapping Widget that prints Sizing information overtop
//    a child widget tree using a Stack.

class OverlaySizing extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Column(  
      children: [
        Text(
          'Orientation: ' + MediaQuery.of(context).orientation.toString(),
          style: Theme.of(context).textTheme.overline
        ),
        Text(
          'Size: ' + MediaQuery.of(context).size.toString(),
          style: Theme.of(context).textTheme.overline
        )
      ]
    );
  }
}

testingFeature.dart

import 'package:flutter/material.dart';

//  CursorTest
import 'dart:html' as html;

class CursorTest extends StatefulWidget {

  final html.Element appContainer;

  CursorTest({
    Key key,
    @required this.appContainer,  //  Have to pass the body element to change the cursor for the page
  }): super(key: key);

  @override
  _CursorTestState createState() => _CursorTestState();
}

class _CursorTestState extends State<CursorTest> {

  double mouseX;
  double mouseY;

    //  function that sets the state to update the widget location to where the mouse is.
  void _updateMouseLocation(PointerEvent details) {
      //  Uses the body element to disable the graphical cursor to redraw my own.  
    widget.appContainer.style.cursor = 'none';
    setState(() {
      mouseX = details.position.dx;
      mouseY = details.position.dy;
    });
  }

  @override
  Widget build(BuildContext context) {

      //  A Box widget to draw as the cursor rather than use the default cursor.    
    Widget boxCursor = Container(
      width: 10,
      height: 10,
      decoration: BoxDecoration(
        color: Colors.grey,
      )
    );

      //  MouseRegion widget allows to grab the location of the mouse whenever the mouse moves
    return MouseRegion(
      onHover: _updateMouseLocation,
      child: Positioned(  // QUESTION: DOES THIS POSITION WIDGET WORK?
        top: mouseX,
        left: mouseY,
        child: Column(  // Draws the cursor and text with location of mouse.
          children: [
            boxCursor,
            Text(
              '${mouseX.toStringAsFixed(2)}, ${mouseY.toStringAsFixed(2)}',
              style: Theme.of(context).textTheme.overline,
            )
          ]
        ),
      )
    );
  }
}

При запуске кода без виджета CursorText домашняя страница отображается правильно, а виджет OverlaySizing точно отображает размер страницы и корректно обновляется при изменении размера страницы.

Когда я добавляю виджет CursorTest, виджет OverlaySizing не обновляется при изменении размера страницы, и перерисовка курсора не происходит, пока курсор по умолчанию все еще там. Я не могу понять, почему это происходит. У меня такое ощущение, что это как-то связано со стеком и позиционированием. Есть ли кто-нибудь, кто может пролить некоторый свет на то, в чем здесь проблема?

Насколько я понимаю, Stack принимает размер родительского элемента, который является Material, то есть размером всей страницы. Домашняя страница будет размером стека, поскольку она не определяет его собственный размер. OverlaySizing - это размер объектов Text внутри него, который расположен в правом нижнем углу стека. И CursorText должен иметь тот же размер, который определен boxCursor, и размещаться в стеке. Где этот лог c терпит неудачу?

Я понимаю, что веб-флаттер нестабилен, и есть некоторые причуды, но поскольку нет официальной документации по настройке курсора, мне пришлось искать решения, и те немногие, которые я пробовал, либо делают весь экран пустой или вызывает ошибки. Это решение является самым близким, что я пришел. Спасибо за помощь!

...