2D Range Value Picker / 二維值選取控制器

donetUserControl_2D-Value-Adjust

如果是一般的 range value 選取, 還可以用 scrollbar 之類的東西蒙混過去。但二維值就不行了,maxscript 的 default ui controllers 沒這樣的東西, 而 .net default windows form controllers 也沒這樣的東西, 所以只好自己動手做...


首先是做一個 .net UserControl。底圖的十字部分用 jpeg 圖檔解決,dragging circle 用 label 解決。
重點在 public event EventHandler Map2DValueChanged;
要建立這個 event ,這樣才能在 maxscript 裡頭偵測到事件觸發。

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

namespace WindowsFormsControlLibrary1
{
    public partial class Map2D : UserControl
    {
        public Map2D()
        {
            InitializeComponent();
        }

        private bool bLeftDown = false;
        private void label1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                bLeftDown = true;
            }
        }

        private void label1_MouseUp(object sender, MouseEventArgs e)
        {
            bLeftDown = false;
        }

        private const int offset_x = 16;
        private const int offset_y = 13;

        private void label1_MouseMove(object sender, MouseEventArgs e)
        {
            Label l = (Label)sender;
            Point _point = this.PointToClient(Cursor.Position);

            if (_point.X < 0) _point.X = 0;
            if (_point.Y < 0) _point.Y = 0;

            if (_point.X > 100) _point.X = 100;
            if (_point.Y > 100) _point.Y = 100;

            if (bLeftDown == true)
            {
                l.Left = _point.X - offset_x;
                l.Top = _point.Y - offset_y;

                if (this.Map2DValueChanged != null)
                    this.Map2DValueChanged(this, e);
            }
        }

        public float _X
        {
            get
            {
                float x = ((float)(label1.Left + offset_x - 50)) / ((float)5.0);
                return x;
            }
        }

        public float _Y
        {
            get
            {
                float y = ((float)(50 - label1.Top - offset_y)) / ((float)5.0);
                return y;
            }
        }

        public event EventHandler Map2DValueChanged;
    }
}

Build project 後就可以拿到 UserControl 的 dll,然後交給 maxscript 去使用。

Assembly = dotNetClass "System.Reflection.Assembly"
Assembly.loadfrom ("C:/WindowsFormsControlLibrary1.dll")

rollout allControls "Facial Controller"
(
	dotNetControl jawMap2d "WindowsFormsControlLibrary1.Map2D"
	
	
	on jawMap2d Map2DValueChanged do
	(
		in coordsys parent $cir_JawMove.position = [jawMap2d._X,0,jawMap2d._Y]
	)
) 

createDialog allControls 120 120