HeyCHのブログ

慢性疲労のへいちゃんです

【C#】Windows フォームアプリケーションでPanelのスワイプ

今回の記事は、Windows フォームアプリケーションでPanelのスワイプをやってみようという事で書いていきます。
内容はないよう…コードだけですね。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TeraPanelDrag {
    public partial class Form1 : Form {
        Point mousePoint;
        int panel1X, panel2X;
        int panel1Y, panel2Y;
        public Form1() {
            InitializeComponent();
            panel1X = panel1.Location.X;
            panel2X = panel2.Location.X;
            panel1Y = panel1.Location.Y;
            panel2Y = panel2.Location.Y;
        }
        private void panel1_MouseDown(object sender, MouseEventArgs e) {
            if (e.Button != MouseButtons.Left) return;
            panel1.Capture = true;
            mousePoint = new Point(e.X, e.Y);
        }

        private void panel2_MouseDown(object sender, MouseEventArgs e) {
            if (e.Button != MouseButtons.Left) return;
            panel2.Capture = true;
            mousePoint = new Point(e.X, e.Y);
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e) {
            if (panel1.Capture && e.Button == MouseButtons.Left) {
                panel1.Location = new Point(panel1.Location.X + e.X - mousePoint.X, panel1.Location.Y);
            }
        }

        private void panel2_MouseMove(object sender, MouseEventArgs e) {
            if (panel2.Capture && e.Button == MouseButtons.Left) {
                panel2.Location = new Point(panel2.Location.X + e.X - mousePoint.X, panel2.Location.Y);
            }
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e) {
            panel1.Capture = false;

            int mouseValue;

            mouseValue = panel1.Location.X - panel1X;

            if (Math.Abs(mouseValue) < (panel1.Width / 2)) {
                panel1.Location = new Point(panel1X, panel1Y);
                panel2.Location = new Point(panel2X, panel2Y);
            } else if (mouseValue < 0) {
                panel1.Location = new Point(panel2X, panel2Y);
                panel2.Location = new Point(panel1X, panel1Y);
            } else {
                panel1.Location = new Point(panel1X, panel1Y);
                panel2.Location = new Point(panel2X, panel2Y);
            }
        }

        private void panel2_MouseUp(object sender, MouseEventArgs e) {
            panel1.Capture = false;

            int mouseValue;

            mouseValue = panel2.Location.X - panel1X;//panel2はpanel1の位置

            if (Math.Abs(mouseValue) < (panel2.Width / 2)) {
                panel1.Location = new Point(panel2X, panel2Y);
                panel2.Location = new Point(panel1X, panel1Y);
            } else if (mouseValue < 0) {
                panel1.Location = new Point(panel2X, panel2Y);
                panel2.Location = new Point(panel1X, panel1Y);
            } else {
                panel1.Location = new Point(panel1X, panel1Y);
                panel2.Location = new Point(panel2X, panel2Y);
            }
        }
    }
}

以上のようにする事でパネルをスワイプし、panel1とpanel2を切り替えることができます。

f:id:HeyCH:20200514000639p:plain
f:id:HeyCH:20200514000658p:plain

アニメーション付き

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TeraPanelDrag {
    public partial class Form1 : Form {
        Point mousePoint;
        int panel1X, panel2X;
        int panel1Y, panel2Y;
        public Form1() {
            InitializeComponent();
            panel1X = panel1.Location.X;
            panel2X = panel2.Location.X;
            panel1Y = panel1.Location.Y;
            panel2Y = panel2.Location.Y;
        }
        private void panel1_MouseDown(object sender, MouseEventArgs e) {
            if (e.Button != MouseButtons.Left) return;
            panel1.Capture = true;
            mousePoint = new Point(e.X, e.Y);
        }

        private void panel2_MouseDown(object sender, MouseEventArgs e) {
            if (e.Button != MouseButtons.Left) return;
            panel2.Capture = true;
            mousePoint = new Point(e.X, e.Y);
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e) {
            if (panel1.Capture && e.Button == MouseButtons.Left) {
                panel1.Location = new Point(panel1.Location.X + e.X - mousePoint.X, panel1.Location.Y);
            }
        }

        private void panel2_MouseMove(object sender, MouseEventArgs e) {
            if (panel2.Capture && e.Button == MouseButtons.Left) {
                panel2.Location = new Point(panel2.Location.X + e.X - mousePoint.X, panel2.Location.Y);
            }
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e) {
            panel1.Capture = false;

            int mouseValue;

            mouseValue = panel1.Location.X - panel1X;

            if (Math.Abs(mouseValue) < (panel1.Width / 2)) {
                panel1.Location = new Point(panel1X, panel1Y);
                panel2.Location = new Point(panel2X, panel2Y);
            } else if (mouseValue < 0) {
                panel1.Location = new Point(panel2X, panel2Y);
                //panel2.Location = new Point(panel1X, panel1Y);
                Animate(10, 10, (frame, frequency) => {
                    if (panel2.Location.X == panel1X) return false;
                    panel2.Location = new Point(panel1X*2 - (panel1X * frame) / frequency, panel1Y);
                    return true;
                });
            } else {
                panel1.Location = new Point(panel1X, panel1Y);
                panel2.Location = new Point(panel2X, panel2Y);
            }
        }

        private void panel2_MouseUp(object sender, MouseEventArgs e) {
            panel1.Capture = false;

            int mouseValue;

            mouseValue = panel2.Location.X - panel1X;//panel2はpanel1の位置

            if (Math.Abs(mouseValue) < (panel2.Width / 2)) {
                panel1.Location = new Point(panel2X, panel2Y);
                panel2.Location = new Point(panel1X, panel1Y);
            } else if (mouseValue < 0) {
                panel1.Location = new Point(panel2X, panel2Y);
                panel2.Location = new Point(panel1X, panel1Y);
            } else {
                //panel1.Location = new Point(panel1X, panel1Y);
                Animate(10, 10, (frame, frequency) => {
                    if (panel1.Location.X == panel1X) return false;
                    panel1.Location = new Point(panel1X * frame / frequency, panel1Y);
                    return true;
                });
                panel2.Location = new Point(panel2X, panel2Y);
            }
        }
        //https://qiita.com/Zuishin/items/0de2c21fbac5d0190c8b
        //からコピー
        public static void Animate(int interval, int frequency, Func<int, int, bool> callback) {
            var timer = new System.Windows.Forms.Timer();
            timer.Interval = interval;
            int frame = 0;
            timer.Tick += (sender, e) =>
            {
                if (callback(frame, frequency) == false || frame >= frequency) {
                    timer.Stop();
                }
                frame++;
            };
            timer.Start();
        }
    }
}