yangyin
2025-03-27 b0de14c2670b9ff0079dacfb4b7457b438368f11
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
// COPYRIGHT (C) Tom. ALL RIGHTS RESERVED.
// THE AntdUI PROJECT IS AN WINFORM LIBRARY LICENSED UNDER THE Apache-2.0 License.
// LICENSED UNDER THE Apache License, VERSION 2.0 (THE "License")
// YOU MAY NOT USE THIS FILE EXCEPT IN COMPLIANCE WITH THE License.
// YOU MAY OBTAIN A COPY OF THE LICENSE AT
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE
// DISTRIBUTED UNDER THE LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING PERMISSIONS AND
// LIMITATIONS UNDER THE License.
// GITEE: https://gitee.com/antdui/AntdUI
// GITHUB: https://github.com/AntdUI/AntdUI
// CSDN: https://blog.csdn.net/v_132
// QQ: 17379620
 
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
 
namespace AntdUI
{
    public class LayeredFormCalendarTime : ILayeredFormOpacityDown
    {
        bool ShowSecond = true;
        public LayeredFormCalendarTime(TimePicker _control, Rectangle rect_read, TimeSpan date, Action<TimeSpan> _action)
        {
            _control.Parent.SetTopMost(Handle);
            control = _control;
            ShowSecond = _control.Format.Contains("s");
            PARENT = _control;
            action = _action;
            scrollY_h = new ScrollY(this);
            scrollY_m = new ScrollY(this);
            scrollY_s = new ScrollY(this);
 
            hover_button = new ITaskOpacity(this);
            hover_buttonok = new ITaskOpacity(this);
 
            #region 数据
 
            calendar_time = new List<CalendarT>(24 + 120);
            for (int i = 0; i < 24; i++) calendar_time.Add(new CalendarT(0, i, i));
            for (int i = 0; i < 60; i++) calendar_time.Add(new CalendarT(1, i, i));
            if (ShowSecond)
            {
                for (int i = 0; i < 60; i++) calendar_time.Add(new CalendarT(2, i, i));
            }
 
            #endregion
 
            float dpi = Config.Dpi;
            if (dpi != 1F)
            {
                Radius = _control.Radius * dpi;
                t_height = (int)(t_height * dpi);
                t_time = (int)(t_time * dpi);
                t_time_height = (int)(t_time_height * dpi);
                t_button = (int)(t_button * dpi);
            }
            else Radius = _control.Radius;
 
            t_width = t_time * (ShowSecond ? 3 : 2);
 
            Font = new Font(_control.Font.FontFamily, 11.2F);
 
            SelDate = date;
 
            var point = _control.PointToScreen(Point.Empty);
            EndHeight = t_height + t_button + 20;
            int r_w = t_width + 20;
            SetSize(r_w, 0);
 
            #region 布局
 
            int size_time_one = (int)(t_time * 0.857F);
            int size_time_height_one = (int)(t_time_height * 0.93F);
 
            var rect_s_h = new Rectangle(10, 18, t_time, t_height - 8);
            rect_read_h = new Rectangle(rect_s_h.Right - t_time, rect_s_h.Y, t_time, rect_s_h.Height);
            rect_read_m = new Rectangle(rect_s_h.Right, rect_s_h.Y, t_time, rect_s_h.Height);
            rect_read_s = new Rectangle(rect_s_h.Right + t_time, rect_s_h.Y, t_time, rect_s_h.Height);
            scrollY_h.SizeChange(rect_s_h);
            rect_s_h.Width += t_time;
            scrollY_m.SizeChange(rect_s_h);
            rect_s_h.Width += t_time;
            scrollY_s.SizeChange(rect_s_h);
 
            int endh2 = t_height - (t_time_height - (int)size_time_height_one);
            scrollY_h.SetVrSize(t_time_height * 24, endh2);
            scrollY_m.SetVrSize(t_time_height * 60, endh2);
            scrollY_s.SetVrSize(t_time_height * 60, endh2);
 
            int _x = (t_time - size_time_one) / 2, _y = (t_time_height - size_time_height_one) / 2;
            foreach (var it in calendar_time)
            {
                it.rect = new Rectangle(10 + t_time * it.x, 10 + 4 + t_time_height * it.y, t_time, t_time_height);
                it.rect_read = new Rectangle(it.rect.X + _x, it.rect.Y + _y, size_time_one, size_time_height_one);
            }
 
            var find_h = calendar_time.Find(a => a.x == 0 && a.t == SelDate.Hours);
            if (find_h != null) scrollY_h.Value = find_h.rect.Y - find_h.rect.Height;
            var find_m = calendar_time.Find(a => a.x == 1 && a.t == SelDate.Minutes);
            if (find_m != null) scrollY_m.Value = find_m.rect.Y - find_m.rect.Height;
            var find_s = calendar_time.Find(a => a.x == 2 && a.t == SelDate.Seconds);
            if (find_s != null) scrollY_s.Value = find_s.rect.Y - find_s.rect.Height;
 
            #endregion
 
            rect_button = new Rectangle(10, 10 + t_height, t_width / 2, t_button);
            rect_buttonok = new Rectangle(rect_button.Right, rect_button.Top, rect_button.Width, rect_button.Height);
            CLocation(point, _control.Placement, _control.DropDownArrow, ArrowSize, 10, r_w, EndHeight, rect_read, ref Inverted, ref ArrowAlign);
        }
 
        #region 属性
 
        TimeSpan SelDate;
 
        #region 参数
 
        IControl control;
 
        float Radius = 6;
        int t_width = 0, t_button = 38, t_time = 56, t_height = 224, t_time_height = 30;
        TAlign ArrowAlign = TAlign.None;
        int ArrowSize = 8;
 
        ScrollY scrollY_h, scrollY_m, scrollY_s;
 
        /// <summary>
        /// 回调
        /// </summary>
        Action<TimeSpan> action;
 
        #endregion
 
        #region 日期
 
        DateTime DateNow = DateTime.Now;
        List<CalendarT> calendar_time;
 
        #endregion
 
        #endregion
 
        #region 渲染
 
        string button_text = Localization.Provider?.GetLocalizedString("Now") ?? "此刻";
        string OKButton = Localization.Provider?.GetLocalizedString("OK") ?? "确定";
        StringFormat s_f = Helper.SF();
        public override Bitmap PrintBit()
        {
            var rect = TargetRectXY;
            var rect_read = new Rectangle(10, 10, rect.Width - 20, rect.Height - 20);
            Bitmap original_bmp = new Bitmap(rect.Width, rect.Height);
            using (var g = Graphics.FromImage(original_bmp).High())
            {
                using (var path = rect_read.RoundPath(Radius))
                {
                    DrawShadow(g, rect, rect.Width, EndHeight);
                    using (var brush = new SolidBrush(Style.Db.BgElevated))
                    {
                        g.FillPath(brush, path);
                        if (ArrowAlign != TAlign.None) g.FillPolygon(brush, ArrowAlign.AlignLines(ArrowSize, rect, rect_read));
                    }
                }
 
                using (var brush_fore = new SolidBrush(Style.Db.TextBase))
                {
                    using (var bmp = new Bitmap(t_width + 20, t_height + 20))
                    using (var brush_bg = new SolidBrush(Style.Db.PrimaryBg))
                    {
                        using (var g2 = Graphics.FromImage(bmp).HighLay())
                        {
                            g2.TranslateTransform(0, -scrollY_h.Value);
                            for (int i = 0; i < calendar_time.Count; i++)
                            {
                                if (i == 24)
                                {
                                    g2.ResetTransform();
                                    g2.TranslateTransform(0, -scrollY_m.Value);
                                }
                                else if (i == 84)
                                {
                                    g2.ResetTransform();
                                    g2.TranslateTransform(0, -scrollY_s.Value);
                                }
                                var it = calendar_time[i];
                                using (var path = it.rect_read.RoundPath(Radius))
                                {
                                    switch (it.x)
                                    {
                                        case 0:
                                            if (it.t == SelDate.Hours) g2.FillPath(brush_bg, path);
                                            break;
                                        case 1:
                                            if (it.t == SelDate.Minutes) g2.FillPath(brush_bg, path);
                                            break;
                                        case 2:
                                            if (it.t == SelDate.Seconds) g2.FillPath(brush_bg, path);
                                            break;
                                    }
                                    if (it.hover)
                                    {
                                        using (var brush_hove = new SolidBrush(Style.Db.FillTertiary))
                                        {
                                            g2.FillPath(brush_hove, path);
                                        }
                                    }
                                    g2.DrawStr(it.v, Font, brush_fore, it.rect_read, s_f);
                                }
                            }
                        }
                        g.DrawImage(bmp, new Rectangle(0, 10, bmp.Width, bmp.Height), new Rectangle(0, 10, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
                    }
                    scrollY_h.Paint(g);
                    scrollY_m.Paint(g);
                    scrollY_s.Paint(g);
 
                    using (var brush_active = new SolidBrush(Style.Db.Primary))
                    {
                        if (hover_button.Animation)
                        {
                            g.DrawStr(button_text, Font, brush_active, rect_button, s_f);
                            using (var brush_hove = new SolidBrush(Helper.ToColor(hover_button.Value, Style.Db.PrimaryActive)))
                            {
                                g.DrawStr(button_text, Font, brush_hove, rect_button, s_f);
                            }
                        }
                        else if (hover_button.Switch)
                        {
                            using (var brush_hove = new SolidBrush(Style.Db.PrimaryActive))
                            {
                                g.DrawStr(button_text, Font, brush_hove, rect_button, s_f);
                            }
                        }
                        else g.DrawStr(button_text, Font, brush_active, rect_button, s_f);
 
                        if (hover_buttonok.Animation)
                        {
                            g.DrawStr(OKButton, Font, brush_active, rect_buttonok, s_f);
                            using (var brush_hove = new SolidBrush(Helper.ToColor(hover_buttonok.Value, Style.Db.PrimaryActive)))
                            {
                                g.DrawStr(OKButton, Font, brush_hove, rect_buttonok, s_f);
                            }
                        }
                        else if (hover_buttonok.Switch)
                        {
                            using (var brush_hove = new SolidBrush(Style.Db.PrimaryActive))
                            {
                                g.DrawStr(OKButton, Font, brush_hove, rect_buttonok, s_f);
                            }
                        }
                        else g.DrawStr(OKButton, Font, brush_active, rect_buttonok, s_f);
                    }
                }
            }
            return original_bmp;
        }
 
        Rectangle rect_read_h, rect_read_m, rect_read_s;
 
        Bitmap? shadow_temp = null;
        /// <summary>
        /// 绘制阴影
        /// </summary>
        /// <param name="g">GDI</param>
        /// <param name="rect_client">客户区域</param>
        /// <param name="shadow_width">最终阴影宽度</param>
        /// <param name="shadow_height">最终阴影高度</param>
        void DrawShadow(Graphics g, Rectangle rect_client, int shadow_width, int shadow_height)
        {
            if (Config.ShadowEnabled)
            {
                if (shadow_temp == null || (shadow_temp.Width != shadow_width || shadow_temp.Height != shadow_height))
                {
                    shadow_temp?.Dispose();
                    using (var path = new Rectangle(10, 10, shadow_width - 20, shadow_height - 20).RoundPath(Radius))
                    {
                        shadow_temp = path.PaintShadow(shadow_width, shadow_height);
                    }
                }
                g.DrawImage(shadow_temp, rect_client, 0.2F);
            }
        }
 
        #endregion
 
        #region 鼠标
 
        ITaskOpacity hover_button, hover_buttonok;
        Rectangle rect_button = new Rectangle(-20, -20, 10, 10), rect_buttonok = new Rectangle(-20, -20, 10, 10);
 
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
 
            if (rect_read_h.Contains(e.Location)) scrollY_h.MouseDown(e.Location);
            else if (rect_read_m.Contains(e.Location)) scrollY_m.MouseDown(e.Location);
            else if (rect_read_s.Contains(e.Location)) scrollY_s.MouseDown(e.Location);
        }
 
        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (scrollY_h.MouseMove(e.Location) && scrollY_m.MouseMove(e.Location) && scrollY_s.MouseMove(e.Location))
            {
                int count = 0, hand = 0;
                bool _hover_button = rect_button.Contains(e.Location),
                 _hover_buttonok = rect_buttonok.Contains(e.Location);
 
                if (_hover_button != hover_button.Switch) count++;
                if (_hover_buttonok != hover_buttonok.Switch) count++;
 
                hover_button.Switch = _hover_button;
                hover_buttonok.Switch = _hover_buttonok;
                if (hover_button.Switch || hover_buttonok.Switch)
                {
                    hand++;
                }
                else
                {
                    if (calendar_time != null)
                    {
                        foreach (var it in calendar_time)
                        {
                            switch (it.x)
                            {
                                case 1:
                                    if (it.Contains(e.Location, 0, scrollY_m.Value, out var change1)) hand++;
                                    if (change1) count++;
                                    break;
                                case 2:
                                    if (it.Contains(e.Location, 0, scrollY_s.Value, out var change2)) hand++;
                                    if (change2) count++;
                                    break;
                                case 0:
                                default:
                                    if (it.Contains(e.Location, 0, scrollY_h.Value, out var change0)) hand++;
                                    if (change0) count++;
                                    break;
                            }
                        }
                    }
                }
                if (count > 0) Print();
                SetCursor(hand > 0);
            }
            else SetCursor(false);
            base.OnMouseMove(e);
        }
 
        protected override void OnMouseLeave(EventArgs e)
        {
            scrollY_h.Leave();
            scrollY_m.Leave();
            scrollY_s.Leave();
            if (calendar_time != null)
            {
                foreach (var it in calendar_time)
                {
                    it.hover = false;
                }
            }
            SetCursor(false);
            Print();
            base.OnMouseLeave(e);
        }
 
        protected override void OnMouseUp(MouseEventArgs e)
        {
            scrollY_h.MouseUp(e.Location);
            scrollY_m.MouseUp(e.Location);
            scrollY_s.MouseUp(e.Location);
            if (e.Button == MouseButtons.Left)
            {
                if (rect_button.Contains(e.Location))
                {
                    DateNow = DateTime.Now;
                    SelDate = new TimeSpan(DateNow.Hour, DateNow.Minute, DateNow.Second);
                    action(SelDate);
                    var find_h = calendar_time.Find(a => a.x == 0 && a.t == SelDate.Hours);
                    if (find_h != null) scrollY_h.Value = find_h.rect.Y - find_h.rect.Height;
                    var find_m = calendar_time.Find(a => a.x == 1 && a.t == SelDate.Minutes);
                    if (find_m != null) scrollY_m.Value = find_m.rect.Y - find_m.rect.Height;
                    var find_s = calendar_time.Find(a => a.x == 2 && a.t == SelDate.Seconds);
                    if (find_s != null) scrollY_s.Value = find_s.rect.Y - find_s.rect.Height;
                    Print();
                    return;
                }
                else if (rect_buttonok.Contains(e.Location))
                {
                    action(SelDate);
                    IClose();
                    return;
                }
 
                foreach (var it in calendar_time)
                {
                    switch (it.x)
                    {
                        case 1:
                            if (it.Contains(e.Location, 0, scrollY_m.Value, out _))
                            {
                                SelDate = new TimeSpan(SelDate.Hours, it.t, SelDate.Seconds);
                                Print();
                                return;
                            }
                            break;
                        case 2:
                            if (it.Contains(e.Location, 0, scrollY_s.Value, out _))
                            {
                                SelDate = new TimeSpan(SelDate.Hours, SelDate.Minutes, it.t);
                                Print();
                                return;
                            }
                            break;
                        case 0:
                        default:
                            if (it.Contains(e.Location, 0, scrollY_h.Value, out _))
                            {
                                SelDate = new TimeSpan(it.t, SelDate.Minutes, SelDate.Seconds);
                                Print();
                                return;
                            }
                            break;
                    }
                }
            }
            base.OnMouseUp(e);
        }
 
        protected override void OnMouseWheel(MouseEventArgs e)
        {
            if (e.Delta != 0)
            {
                if (rect_read_h.Contains(e.Location))
                {
                    scrollY_h.MouseWheel(e.Delta);
                    Print();
                }
                else if (rect_read_m.Contains(e.Location))
                {
                    scrollY_m.MouseWheel(e.Delta);
                    Print();
                }
                else if (rect_read_s.Contains(e.Location))
                {
                    scrollY_s.MouseWheel(e.Delta);
                    Print();
                }
            }
            base.OnMouseWheel(e);
        }
 
        #endregion
    }
}