zeus_grid 0.8.6 copy "zeus_grid: ^0.8.6" to clipboard
zeus_grid: ^0.8.6 copied to clipboard

A high-performance, tactical grid engine for Flutter. Featuring an immutable state-driven drag-and-resize system with built-in collision detection.

ZeusGrid: Grid Based Container Engine #

ZeusGrid is a Flutter package that provides a normalised coordinated canvas for building high-density, interactive dashboards. Unlike responsive layouts that "reflow" content, ZeusGrid treats the screen as a tactical map where every element has a fixed, logical position.

Features #

📐 Smart Proportional Scaling #

The entire grid acts like a "living canvas." Instead of elements jumping around or stacking when you move from a desktop to a tablet, the grid perfectly shrinks or grows to fit the screen. Your layout remains consistent, meaning your most important data is always exactly where you expect it to be.

[Main Page]

Resize #

Multi-Axis Resizing: Tactical "Grab Bars" on every side allow you to stretch or shrink modules to highlight the data that matters most right now.

Visual Feedback: The interface communicates with you—turning Cyan when a move is perfect and Red if you’re trying to overlap another module.

Move #

[Edit Page]

Simply press and hold any module to "un-dock" it from the grid. The interface provides instant feedback, allowing you to slide complex data monitors across the screen.

As you move a module, the system automatically aligns it to the underlying grid units. This eliminates "messy" layouts and ensures every pixel of your screen is utilized efficiently.

[Collision]

Storage #

The menu is a sleek, animated drawer that stays hidden during standard monitoring but slides into view instantly when you enter Edit Mode. This maximizes your screen real estate for high-density data.

The Arsenal is "Grid-Aware." If you remove a module from your dashboard, it instantly returns to the Arsenal. If you drag a module onto the grid, it disappears from the menu—ensuring you never have duplicate data monitors cluttering your workspace.

Getting started #

Define Your Modules #

// 1. Modules currently displayed on the grid
List<ZeusModule> myModules = [
  ZeusModule(id: 'module_a', x: 0, y: 0, w: 40, h: 30),
];

// 2. Modules waiting in the "Arsenal" side menu
List<ZeusModule> myArsenal = [
  ZeusModule(id: 'module_b', x: 0, y: 0, w: 80, h: 30),
  ZeusModule(id: 'module_c', x: 0, y: 0, w: 30, h: 20),
];

Initialise the ZeusGrid #

Switch(
  value: _isEditing,
  onChanged: (v) => setState(() => _isEditing = v),
  activeColor: Colors.greenAccent,
),
ZeusGrid(
	isEditing: _isEditMode,
	modules: myModules,
	onGenerateContent: (id) => MyModuleWidget(id),
	onModuleUpdate: (m) => setState(() => sync(m)),
	onModuleRemove: (id) => setState(() => remove(id)),
);

Parameters #

Styling (Optional) #

Styling has been made simple by defining gridStyle, moduleStyle, menuStyle in ZeusGrid().

ZeusGrid(
	gridStyle: GridStyle(lineColor: Colors.blueGrey.withOpacity(0.1)),
	moduleStyle: ModuleStyle(borderRadius: BorderRadius.circular(12), color: Colors.black),
	menuStyle: menuStyle: MenuStyle(width: 250, backgroundColor: Colors.black87),
)

Handling State & Persistence #

ZeusGrid follows a Unidirectional Data Flow pattern. The widget does not manage its own internal list of modules. Instead, it notifies the parent application when a user interacts with a module, allowing you to sync changes to a database, a state provider (Riverpod/Bloc), or local storage.

onModuleUpdate(ZeusModule module)

This callback fires whenever a module is moved or resized and the user releases their finger/mouse.

The Payload: Returns a new ZeusModule instance with updated x, y, w, h coordinates.

Usage: Use this to update your "Single Source of Truth."

Example:

 onModuleUpdate: (m) => setState(() {
	 final fromArsenalIndex = myArsenal.indexWhere(
	   (item) => item.id == m.id,
	 );

	if (fromArsenalIndex != -1) {
	  myArsenal.removeAt(fromArsenalIndex);
	  myModules.add(m);
	} else {
	   final i = myModules.indexWhere((item) => item.id == m.id);
	   if (i != -1) myModules[i] = m;
	}
}),

onModuleRemove(String id)

This callback fires when the user taps the Red Close Button on a module in Edit Mode.

The Payload: Returns the unique String id of the module to be removed.

Usage: Use this to move a module from your "Active" list back to your "Arsenal" (unplaced) list.

Example:

onModuleRemove: (id) => setState(() {
  // 🎯 MOVE: Grid -> Arsenal
  final removedIndex = myModules.indexWhere((m) => m.id == id);
  if (removedIndex != -1) {
    final removedModule = myModules.removeAt(removedIndex);
    myArsenal.add(removedModule);
  }
}),

Why this Architecture? #

By exposing these callbacks, the package remains highly portable.

Persistence: You can easily hook this up to Shared Preferences or Firebase so your layout persists across app restarts.

Validation: You can prevent certain modules from being moved or deleted based on user permissions (e.g., "Guest" users can't delete the Server Status card).

Global Sync: In a multi-user environment, you can broadcast the onModuleUpdate via WebSockets so the dashboard moves in real-time for everyone.

Additional #

This is intently built for a personal project and i saw the other dashboard packages didn't quite give me what i was looking for so i made my own, thought i would share that with everyone. Feel free to improve on it and let me know any improvements can be made :)

"Buy Me A Coffee"

0
likes
0
points
424
downloads

Publisher

unverified uploader

Weekly Downloads

A high-performance, tactical grid engine for Flutter. Featuring an immutable state-driven drag-and-resize system with built-in collision detection.

License

unknown (license)

Dependencies

flutter

More

Packages that depend on zeus_grid