public override void DrawGUI(Rect rect)
    {
        //update both visual lists
        UpdateCornerList();
        UpdatePatternList();
        //update layout rects
        UpdateLayoutRects(rect);

        //draw key selection header
        VxlGUI.DrawRect(_rect_selectheader, "DarkGradient");
        GUI.Label(_rect_selectheader, _title, GUI.skin.GetStyle("LeftLightHeader"));
        //draw key selection list
        VxlGUI.DrawRect(_rect_selectscroll, "DarkWhite");
        _selectscroll = GUI.BeginScrollView(_rect_selectscroll, _selectscroll, _rect_select_content);
        _cornerlist.DoList(_rect_select_content);
        GUI.EndScrollView();
        //draw add pattern template
        EditorGUI.BeginChangeCheck();
        VxlGUI.DrawRect(_rect_temparea, "DarkGrey");
        GUI.Label(_rect_tempheader, "Corner Pattern", "PatHeader");
        GUI.Label(_rect_voxelid, "Voxel IDs:", "LeftMedPatLabel");
        GUI.Label(_rect_above, "Above", "RightMedPatLabel");
        GUI.Label(_rect_below, "Below", "RightMedPatLabel");
        GUI.Label(_rect_d5, "D5", "MidMedPatLabel");
        GUI.Label(_rect_d1, "D1", "MidMedPatLabel");
        GUI.Label(_rect_d3, "D3", "MidMedPatLabel");
        int  a0    = EditorGUI.IntField(_rect_above_d5, _addpat.a0, "MidPatIntField");
        int  a1    = EditorGUI.IntField(_rect_above_d1, _addpat.a1, "MidPatIntField");
        int  a2    = EditorGUI.IntField(_rect_above_d3, _addpat.a2, "MidPatIntField");
        int  b0    = EditorGUI.IntField(_rect_below_d5, _addpat.b0, "MidPatIntField");
        int  b1    = EditorGUI.IntField(_rect_below_d1, _addpat.b1, "MidPatIntField");
        int  b2    = EditorGUI.IntField(_rect_below_d3, _addpat.b2, "MidPatIntField");
        bool xflip = EditorGUI.Foldout(_rect_flipx, _addpat.xflip, "FlipX", true, "LightFoldout");
        bool yflip = EditorGUI.Foldout(_rect_flipy, _addpat.yflip, "FlipY", true, "LightFoldout");

        //apply change
        if (EditorGUI.EndChangeCheck())
        {
            _addpat       = new CornerPattern(xflip, yflip, a0, a1, a2, b0, b1, b2);
            _repaint_menu = true;
        }



        bool invalid_corner = _cornerlist.count <= 0 || _cornerlist.index < 0 || _cornerlist.index >= _cornerlist.count;
        bool invalid_exists = target != null && target.CornerPatternExists(_addpat);

        EditorGUI.BeginDisabledGroup(target == null || _addpat.IsEmpty() || invalid_corner || invalid_exists);
        if (GUI.Button(_rect_tempbutton, "Add", GUI.skin.GetStyle("PatButton")))
        {
            if (target != null)
            {
                Undo.RecordObject(target, "Add Corner Pattern");
                target.AddCornerPattern(_corners[_cornerlist.index], _addpat);
                _repaint_menu = false;
                //dirty target object
                EditorUtility.SetDirty(target);
                //update pattern list
                UpdatePatternList();
            }
        }
        EditorGUI.EndDisabledGroup();

        //draw pattern header
        VxlGUI.DrawRect(_rect_patheader, "DarkGradient");
        GUI.Label(_rect_patheader, "Patterns", GUI.skin.GetStyle("LeftLightHeader"));
        //draw pattern list
        VxlGUI.DrawRect(_rect_patscroll, "DarkWhite");
        _patscroll = GUI.BeginScrollView(_rect_patscroll, _patscroll, _rect_patcontent);
        _patternlist.DoList(_rect_patcontent);
        GUI.EndScrollView();
        //draw pattern panel
        VxlGUI.DrawRect(_rect_patpanel, "DarkGradient");
        float button_width    = Mathf.Min(60f, _rect_patpanel.width / 2f);
        bool  invalid_pattern = _patternlist.count <= 0 || _patternlist.index < 0 || _patternlist.index >= _patternlist.count;

        EditorGUI.BeginDisabledGroup(target == null || invalid_pattern || invalid_corner);
        if (GUI.Button(VxlGUI.GetLeftElement(_rect_patpanel, 0, button_width), "Delete", GUI.skin.GetStyle("LightButton")))
        {
            if (target != null)
            {
                Undo.RecordObject(target, "Delete Corner Pattern");
                target.DeleteCornerPattern(_corners[_cornerlist.index], _patterns[_patternlist.index]);
                _repaint_menu = false;
                //dirty target object
                EditorUtility.SetDirty(target);
                //update pattern list
                UpdatePatternList();
            }
        }
        EditorGUI.EndDisabledGroup();
    }