Add Windows runner files for high DPI support and console output
- Created runner.exe.manifest to enable DPI awareness and dark mode support. - Implemented utility functions in utils.cpp and utils.h for console creation and command line argument handling. - Developed Win32Window class in win32_window.cpp and win32_window.h to manage high DPI-aware windows, including theme updates and message handling.
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:notas/models/note.dart';
|
||||
|
||||
// Small presentational widget for a note inside the grid.
|
||||
// Keep this widget lightweight and layout-agnostic: it should not force
|
||||
// width/height constraints (so it works inside different parent layouts
|
||||
// like MasonryGridView or Draggable feedback). Visual styling only.
|
||||
|
||||
class NoteCard extends StatefulWidget {
|
||||
const NoteCard({super.key, required this.note, this.onTap, this.isDragging = false});
|
||||
|
||||
final Note note;
|
||||
final VoidCallback? onTap;
|
||||
final bool isDragging;
|
||||
|
||||
@override
|
||||
State<NoteCard> createState() => _NoteCardState();
|
||||
}
|
||||
|
||||
class _NoteCardState extends State<NoteCard> {
|
||||
bool _isPressed = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final bool showGrabbing = widget.isDragging || _isPressed;
|
||||
|
||||
return MouseRegion(
|
||||
cursor: showGrabbing ? SystemMouseCursors.grabbing : SystemMouseCursors.grab,
|
||||
child: GestureDetector(
|
||||
onTapDown: widget.onTap == null
|
||||
? null
|
||||
: (_) {
|
||||
setState(() {
|
||||
_isPressed = true;
|
||||
});
|
||||
},
|
||||
onTapUp: widget.onTap == null
|
||||
? null
|
||||
: (_) {
|
||||
setState(() {
|
||||
_isPressed = false;
|
||||
});
|
||||
},
|
||||
onTapCancel: widget.onTap == null
|
||||
? null
|
||||
: () {
|
||||
setState(() {
|
||||
_isPressed = false;
|
||||
});
|
||||
},
|
||||
onTap: widget.onTap,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color.fromRGBO(24, 25, 26, 1),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: Colors.white24, width: 1),
|
||||
),
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context, BoxConstraints constraints) {
|
||||
// Estimate whether the body will exceed 20 lines without always
|
||||
// running the expensive TextPainter layout. This heuristic counts
|
||||
// newline characters and estimates wrapped lines based on an
|
||||
// average characters-per-line to handle many short lines well.
|
||||
final List<String> rawLines = widget.note.body.split('\n');
|
||||
const int avgCharsPerLine = 40;
|
||||
int estimatedLines = 0;
|
||||
for (final String line in rawLines) {
|
||||
estimatedLines += (line.trim().length ~/ avgCharsPerLine) + 1;
|
||||
}
|
||||
|
||||
final bool needsPreciseMeasurement = estimatedLines > 20;
|
||||
final bool isBodyTruncated;
|
||||
|
||||
if (needsPreciseMeasurement) {
|
||||
final TextPainter textPainter = TextPainter(
|
||||
text: TextSpan(
|
||||
text: widget.note.body,
|
||||
style: const TextStyle(color: Colors.white70, fontSize: 14),
|
||||
),
|
||||
maxLines: 20,
|
||||
textDirection: TextDirection.ltr,
|
||||
)..layout(maxWidth: constraints.maxWidth);
|
||||
|
||||
isBodyTruncated = textPainter.didExceedMaxLines;
|
||||
} else {
|
||||
isBodyTruncated = false;
|
||||
}
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
widget.note.title,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
widget.note.body,
|
||||
style: const TextStyle(color: Colors.white70, fontSize: 14),
|
||||
maxLines: 20,
|
||||
overflow: TextOverflow.clip,
|
||||
),
|
||||
if (isBodyTruncated) ...[
|
||||
const SizedBox(height: 4),
|
||||
const Text(
|
||||
'...',
|
||||
style: TextStyle(
|
||||
color: Colors.white54,
|
||||
fontSize: 18,
|
||||
height: 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user