crossword_generator 1.2.0 copy "crossword_generator: ^1.2.0" to clipboard
crossword_generator: ^1.2.0 copied to clipboard

A Dart library for generating crossword puzzles.

Crossword Generator #

A Flutter library for generating and displaying interactive crossword puzzles. Customize the appearance and behavior of crossword grids, and easily integrate them into your Flutter applications.

Features #

  • Generate crossword layouts from a list of words and descriptions.
  • Interactive crossword grid with cell selection and navigation.
  • Customizable styles for cells, including colors and text styles.
  • Reveal letters or entire words.
  • Automatically validate and highlight completed words.
  • Navigate between words using buttons.
  • Expose completion event to notify when the crossword is fully completed.

Installation #

Add the following to your pubspec.yaml file:

dependencies:
  crossword_generator: ^1.0.0

Then run flutter pub get to install the package.

Usage #

Basic Example #

Here's a basic example of how to use the CrosswordWidget:

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

void main() {
  runApp(CrosswordApp());
}

class CrosswordApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Crossword Generator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: CrosswordHomePage(),
    );
  }
}

class CrosswordHomePage extends StatefulWidget {
  @override
  _CrosswordHomePageState createState() => _CrosswordHomePageState();
}

class _CrosswordHomePageState extends State<CrosswordHomePage> {
  final TextEditingController _controller = TextEditingController();
  Function? _revealCurrentCellLetter;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Crossword Generator'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: SingleChildScrollView(
          child: Column(
            children: [
              TextField(
                controller: _controller,
                maxLines: 5,
                decoration: InputDecoration(
                  hintText: 'Enter words on separate lines...',
                  border: OutlineInputBorder(),
                ),
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: () {
                  if (_controller.text.isNotEmpty) {
                    List<String> wordList = _controller.text.split(RegExp(r'[ \r\n,;:-]+')).where((word) => word.isNotEmpty).toList();
                    List<Map<String, dynamic>> inputJson = wordList.map((word) => {'answer': word.toLowerCase(), 'description': 'Description for $word'}).toList();

                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) => Scaffold(
                          appBar: AppBar(
                            title: Text('Crossword Puzzle'),
                            actions: [
                              IconButton(
                                icon: Icon(Icons.help),
                                onPressed: () {
                                  if (_revealCurrentCellLetter != null) {
                                    _revealCurrentCellLetter!();
                                  }
                                },
                              ),
                            ],
                          ),
                          body: CrosswordWidget(
                            words: inputJson,
                            style: CrosswordStyle(
                              currentCellColor: Color.fromARGB(255, 84, 255, 129),
                              wordHighlightColor: Color.fromARGB(255, 200, 255, 200),
                              wordCompleteColor: Color.fromARGB(255, 255, 249, 196),
                              cellTextStyle: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
                              descriptionButtonStyle: ElevatedButton.styleFrom(
                                backgroundColor: Colors.blue,
                              ),
                              cellBuilder: (context, cell, isSelected, isHighlighted, isCompleted) {
                                return Container(
                                  width: 30,
                                  height: 30,
                                  alignment: Alignment.center,
                                  margin: EdgeInsets.all(1),
                                  decoration: BoxDecoration(
                                    border: Border.all(color: Colors.black),
                                    color: isCompleted
                                        ? Color.fromARGB(255, 255, 249, 196)
                                        : isSelected
                                            ? Color.fromARGB(255, 84, 255, 129)
                                            : isHighlighted
                                                ? Color.fromARGB(255, 200, 255, 200)
                                                : Colors.white,
                                  ),
                                  child: Text(
                                    cell.toUpperCase(),
                                    style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
                                  ),
                                );
                              },
                            ),
                            onRevealCurrentCellLetter: (revealCurrentCellLetter) {
                              _revealCurrentCellLetter = revealCurrentCellLetter;
                            },
                            onCrosswordCompleted: () {
                              // Handle crossword completion
                              showDialog(
                                context: context,
                                builder: (context) {
                                  return AlertDialog(
                                    title: Text('Congratulations!'),
                                    content: Text('You have completed the crossword puzzle.'),
                                    actions: [
                                      TextButton(
                                        child: Text('OK'),
                                        onPressed: () {
                                          Navigator.of(context).pop();
                                        },
                                      ),
                                    ],
                                  );
                                },
                              );
                            },
                          ),
                        ),
                      ),
                    );
                  }
                },
                child: Text('Generate Layout'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Customizing Styles #

You can customize the appearance of the crossword grid by providing a CrosswordStyle object to the CrosswordWidget. Here's an example:

CrosswordWidget(
  words: inputJson,
  style: CrosswordStyle(
    currentCellColor: Colors.blue,
    wordHighlightColor: Colors.yellow,
    wordCompleteColor: Colors.green,
    cellTextStyle: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
    descriptionButtonStyle: ElevatedButton.styleFrom(
      backgroundColor: Colors.blue,
    ),
    cellBuilder: (context, cell, isSelected, isHighlighted, isCompleted) {
      return Container(
        width: 30,
        height: 30,
        alignment: Alignment.center,
        margin: EdgeInsets.all(1),
        decoration: BoxDecoration(
          border: Border.all(color: Colors.black),
          color: isCompleted
              ? Colors.green
              : isSelected
                  ? Colors.blue
                  : isHighlighted
                      ? Colors.yellow
                      : Colors.white,
        ),
        child: Text(
          cell.toUpperCase(),
          style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
        ),
      );
    },
  ),
  onRevealCurrentCellLetter: (revealCurrentCellLetter) {
    _revealCurrentCellLetter = revealCurrentCellLetter;
  },
  onCrosswordCompleted: () {
    // Handle crossword completion
    showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          title: Text('Congratulations!'),
          content: Text('You have completed the crossword puzzle.'),
          actions: [
            TextButton(
              child: Text('OK'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  },
);

UI Example #

Here's an example of the UI generated by the CrosswordWidget:

Crossword Example

Methods #

  • revealCurrentCellLetter(): Reveals the letter in the currently selected cell.

Acknowledgements #

Special thanks to Michael Wehar for the original layout generation code in JavaScript, which inspired the layout generation logic in this library.

License #

This project is licensed under the MIT License - see the LICENSE file for details.

Contributions #

Contributions are welcome! Please open an issue or submit a pull request.

Contact #

For any questions or suggestions, feel free to contact at [support+crossword-generator@speakm.com].

1
likes
110
points
72
downloads

Publisher

verified publisherspeakm.com

Weekly Downloads

A Dart library for generating crossword puzzles.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on crossword_generator