포스트

미팅 시간 제한 앱(데스크탑)

file_1

미팅 시간 타이머 앱. 압축 풀어서 exe파일 실행.

바이러스 없음. 소스코드가 간단하므로 확인할 수 있음.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import 'dart:async';
import 'package:flutter/material.dart';
import 'dart:math';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: TimerHomePage(),
    );
  }
}

class TimerHomePage extends StatefulWidget {
  @override
  _TimerHomePageState createState() => _TimerHomePageState();
}

class _TimerHomePageState extends State {
  final TextEditingController _hourController = TextEditingController(text: '00');
  final TextEditingController _minuteController = TextEditingController(text: '00');
  final TextEditingController _secondController = TextEditingController(text: '00');
  double _progress = 0; // 타이머 진행률 (0.0에서 1.0까지)
  Timer? _timer;
  int _totalTime = 0; // 총 시간(초 단위)

  // 타이머의 경과 시간과 남은 시간을 포맷팅하여 반환하는 함수
  String formatDuration(int seconds) {
    final int hours = seconds ~/ 3600;
    final int minutes = (seconds % 3600) ~/ 60;
    final int remainingSeconds = seconds % 60;
    return '${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}:${remainingSeconds.toString().padLeft(2, '0')}';
  }

// _startTimer 함수 내에서 경과된 시간과 남은 시간을 계산하고 업데이트하는 부분
  void _startTimer() {
    int elapsedTime = 0;

    _totalTime = (int.tryParse(_hourController.text) ?? 0) * 3600 +
        (int.tryParse(_minuteController.text) ?? 0) * 60 +
        (int.tryParse(_secondController.text) ?? 0);

    _timer?.cancel(); // 기존 타이머가 있다면 취소
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      setState(() {
        elapsedTime++;
        _progress = elapsedTime / _totalTime;
        if (_progress >= 1) {
          _timer?.cancel();
          _showTimeUpDialog();
          _progress = 0; // 타이머 초기화
          _totalTime = 0;
        }
      });
    });
  }


  void _showTimeUpDialog() {
    showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          title: Text('회의 시간 종료'),
          content: Text('설정한 회의 시간이 종료되었습니다.'),
          actions: [
            TextButton(
              child: Text('확인'),
              onPressed: () {
                Navigator.of(context).pop(); // 다이얼로그 닫기
              },
            ),
          ],
        );
      },
    );
  }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            CustomPaint(
              painter: TimerPainter(progress: _progress),
              child: Container(
                width: 200,
                height: 200,
                alignment: Alignment.center,
                child: _timer != null && _timer!.isActive
                    ? Text("${formatDuration(((_totalTime * _progress).round()))} / ${formatDuration(_totalTime)}")
                    : Text("시간을 설정하세요"),
              ),
            ),
            SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Flexible(
                  child: TextField(
                    controller: _hourController,
                    decoration: InputDecoration(
                      labelText: '시간 (hh)',
                    ),
                    keyboardType: TextInputType.number,
                    textAlign: TextAlign.center,
                  ),
                ),
                SizedBox(width: 10),
                Flexible(
                  child: TextField(
                    controller: _minuteController,
                    decoration: InputDecoration(
                      labelText: '분 (mm)',
                    ),
                    keyboardType: TextInputType.number,
                    textAlign: TextAlign.center,
                  ),
                ),
                SizedBox(width: 10),
                Flexible(
                  child: TextField(
                    controller: _secondController,
                    decoration: InputDecoration(
                      labelText: '초 (ss)',
                    ),
                    keyboardType: TextInputType.number,
                    textAlign: TextAlign.center,
                  ),
                ),
              ],
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _startTimer,
              child: Text('시작'),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _timer?.cancel();
    _hourController.dispose();
    _minuteController.dispose();
    _secondController.dispose();
    super.dispose();
  }
}

class TimerPainter extends CustomPainter {
  final double progress;

  TimerPainter({required this.progress});

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()
      ..color = Colors.blue
      ..strokeWidth = 8
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke;

    Offset center = Offset(size.width / 2, size.height / 2);
    double radius = size.width / 2;
    double angle = 2 * pi * progress;

    canvas.drawArc(Rect.fromCircle(center: center, radius: radius), -pi / 2, angle, false, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.