С Новым годом! Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/11: Рейтинг темы: голосов - 11, средняя оценка - 5.00
46 / 20 / 5
Регистрация: 29.12.2015
Сообщений: 1,863
1
.NET 2.x

Компонент SEGA палитры

07.07.2018, 19:52. Показов 1955. Ответов 27
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте. Нужна помощь в создании компонента SEGA палитры на основе PictureBox и таблицы

Нужно сделать отрисовку палитры и при этом сделать также выделение цвета в палитре и при выборе цвета чтобы он также подсвечивался рамочкой. Пока что у меня сделано в виде обычного PictureBox и говнокода
C#
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
Bitmap SetSEGAPalette()
        {
            //Переменная палитры SEGA по цветам RGB
            var col = new double[8];
 
            col[0] = 0.0;
            col[1] = 2.0;
            col[2] = 4.0;
            col[3] = 6.0;
            col[4] = 8.0;
            col[5] = 10.0;
            col[6] = 12.0;
            col[7] = 14.0;
 
            var x = 0;
            var y = 0;
 
            Bitmap CDH_PaleteBuf = new Bitmap(pb_SEGAPalette.Width, pb_SEGAPalette.Height);
            Graphics g = Graphics.FromImage(CDH_PaleteBuf);
 
            for (int i = 0; i < 8; i++)
            {
 
                y = (i / 4) * (128);
                x = (i % 4) * (128);
 
                for (int l = 0; l < 8; l++)
                {
                    for (int k = 0; k < 8; k++)
                    {
 
                        SolidBrush br = new SolidBrush(Color.FromArgb(255, (int)(col[k] * 255 / 14), (int)(col[l] * 255 / 14), (int)(col[i] * 255 / 14)));
 
                        g.FillRectangle(br, x, y, 16, 16);
 
                        y += 16;
                    }
 
                    y -= 128;
                    x += 16;
                }
            }
 
            pb_SEGAPalette.Image = CDH_PaleteBuf;
            return CDH_PaleteBuf;
        }
 
        void SetRectSEGAPalete(int x, int y)
        {
            var xi = (int)(x / 16);
            var yi = (int)(y / 16);
 
            Bitmap CDH_PaleteBuf = SetSEGAPalette();
            Graphics g = Graphics.FromImage(CDH_PaleteBuf);
 
            if (xi < 4 || yi < 4)
            {
                g.DrawRectangle(new Pen(Color.White, 2), (xi * 16), (yi * 16), 16, 16);
            }
            else
            {
                g.DrawRectangle(new Pen(Color.Black, 2), (xi * 16), (yi * 16), 16, 16);
            }
        }
И то это только 2 вещи. А именно рамка при выборе цвета и сама палитра. И при двежении мышки по pictureBox вызывается вот это:
SetRectSEGAPalete()
что каждый раз делает перерисовку палитры и рамки и не эфективно это.
Лучше для этого сделать свой компонент.

Подскажите с чего начать?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.07.2018, 19:52
Ответы с готовыми решениями:

Создание SEGA палитры на PictureBox
Здравствуйте. Есть код на языке PureBasic ;{ создание глобальной палитры Global Dim...

Тема. Создание программ с использованием объектов Палитры компонент Standart и Additional
вариант 1 1. Напишите программу, которая выведет в центре экрана следующий текст: &quot;To be or not...

Sega: нет изображения
подключаю всё вроде правильно включаю а изображения нет что делать?

Windows xp + naomi 2 sega
Добрый вечер. Имеется данная приставка с сгоревшим gd rom. Написал скрипт на питоне для запуска...

27
557 / 534 / 225
Регистрация: 02.11.2016
Сообщений: 1,538
07.07.2018, 22:47 2
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
что каждый раз делает перерисовку палитры и рамки и не эфективно это
Вам не нужно при каждом движении мыши перерисовывать палитру. Для начала проверяйте вышел ли курсор за пределы текущего квадрата и перерисовывайте только если вышел, а не каждый раз. А перерисовывать палитру придется в любом случае, хоть свой контрол Вы напишите, хоть еще что то... Так что насчет эффективности вопрос спорный.
0
46 / 20 / 5
Регистрация: 29.12.2015
Сообщений: 1,863
07.07.2018, 22:55  [ТС] 3
Цитата Сообщение от Shogun31337 Посмотреть сообщение
Вам не нужно при каждом движении мыши перерисовывать палитру. Для начала проверяйте вышел ли курсор за пределы текущего квадрата и перерисовывайте только если вышел, а не каждый раз. А перерисовывать палитру придется в любом случае, хоть свой контрол Вы напишите, хоть еще что то... Так что насчет эффективности вопрос спорный.
Как я тогда буду рамку рисовать. Говорю нужен компонент а так как сторонних нет то прийдется свой создать.
0
8943 / 4855 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
07.07.2018, 22:56 4
Зачем вообще динамически генерировать цвета, если их всего 8? Сделать 8 картинок нужного цвета и их использовать. Ну рамку ещё накладывать
0
557 / 534 / 225
Регистрация: 02.11.2016
Сообщений: 1,538
07.07.2018, 23:01 5
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Говорю нужен компонент
Ну дело хозяйское...
0
46 / 20 / 5
Регистрация: 29.12.2015
Сообщений: 1,863
07.07.2018, 23:03  [ТС] 6
Цитата Сообщение от ViterAlex Посмотреть сообщение
Зачем вообще динамически генерировать цвета, если их всего 8? Сделать 8 картинок нужного цвета и их использовать. Ну рамку ещё накладывать
8 * 8 * 8
Это по твоему 8. Вот рисуемая палитра:
Компонент SEGA палитры
0
8943 / 4855 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
08.07.2018, 01:55 7
Лучший ответ Сообщение было отмечено Alexandr_7 как решение

Решение

Alexandr_7, согласен, погорячился. Вот тебе контрол.
Кликните здесь для просмотра всего текста
C#
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
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
 
namespace SegaPalette.Controls
{
    [DefaultProperty("SelectedColor")]
    [DefaultEvent("SelectedColorChanged")]
    public class SegaPalette : Control
    {
        private Color[,] _colors;
        private Rectangle _hoverRect = Rectangle.Empty;
        private Color _selectedColor;
 
        public event EventHandler<SelectedColorChangedEventArgs> SelectedColorChanged;
        /// <summary>
        /// Выбранный цвет
        /// </summary>
        public Color SelectedColor
        {
            get { return _selectedColor; }
            protected set
            {
                if (_selectedColor != value)
                {
                    var oldColor = _selectedColor;
                    _selectedColor = value;
                    OnSelectedColorChanged(new SelectedColorChangedEventArgs { NewColor = _selectedColor, OldColor = oldColor });
                }
            }
        }
 
        protected virtual void OnSelectedColorChanged(SelectedColorChangedEventArgs e)
        {
            SelectedColorChanged?.Invoke(this, e);
        }
 
        private int _side;
        /// <summary>
        /// Размер квадрата одного цвета
        /// </summary>
        protected virtual int Side
        {
            get => _side; set
            {
                _side = value;
                _hoverRect.Width = _side;
                _hoverRect.Height = _side;
            }
        }
 
        public SegaPalette()
        {
            SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true);
            SetColors();
            Side = 8;
        }
        //Определение цветов палитры
        private void SetColors()
        {
            _colors = new Color[8, 64];
            var col = new double[8] { 0, 2, 4, 6, 8, 10, 12, 14 };
            var norm = new Func<double, int>((val) => (int)(val * 255 / 14));
 
            for (int i = 0; i < 8; i++)
                for (int l = 0; l < 8; l++)
                    for (int k = 0; k < 8; k++)
                        _colors[l, k + 8 * i] = Color.FromArgb(255, norm(col[k]), norm(col[l]), norm(col[i]));
        }
        //Прорисовка контрола
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            using (var b = new SolidBrush(Color.Empty))
                for (int i = 0; i < 8; i++)
                    for (int j = 0; j < 64; j++)
                    {
                        b.Color = _colors[i, j];
                        var x = _side * (j % 32);
                        var y = i * _side + 8 * _side * (j / 32);
                        e.Graphics.FillRectangle(b, x, y, _side, _side);
                    }
            //Прямоугольник выделения
            e.Graphics.DrawRectangle(Pens.White, _hoverRect);
        }
 
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            //Положение выделения
            var pt = new Point((e.X / _side) * _side, (e.Y / _side) * _side);
            if (pt != _hoverRect.Location)
            {
                _hoverRect.Location = pt;
                Invalidate();
            }
        }
        //Смена выбранного цвета
        protected override void OnMouseClick(MouseEventArgs e)
        {
            base.OnMouseClick(e);
            var i = _hoverRect.X / _side;
            var j = _hoverRect.Y / _side;
            i += 32 * (j / 8);
            j %= 8;
            SelectedColor = _colors[j, i];
        }
 
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            //Размер формы в пропорции 2:1
            Width = (Width / 32) * 32;
            Height = Width / 2;
            Side = Width / 32;
        }
 
        protected override Cursor DefaultCursor => Cursors.Hand;
 
        protected override Size DefaultSize => new Size(256, 128);
    }
 
    public class SelectedColorChangedEventArgs
    {
        public Color OldColor { get; set; }
        public Color NewColor { get; set; }
    }
}

Выделение выбранного цвета белым прямоугольником, событие смены выбранного цвета, правильные пропорции при изменении размера.
Миниатюры
Компонент SEGA палитры  
Вложения
Тип файла: zip SegaPalette.zip (14.5 Кб, 2 просмотров)
3
46 / 20 / 5
Регистрация: 29.12.2015
Сообщений: 1,863
08.07.2018, 02:18  [ТС] 8
Цитата Сообщение от ViterAlex Посмотреть сообщение
Alexandr_7, согласен, погорячился. Вот тебе контрол.
Класно еще бы рамочку при выборе цвета. Единственное что палитра неверная. Она не совпадает с картинкой. Да и вообще ее можно и не рисовать а загружать уже готовую картинку палитры

А так правильное рисование палитры это с верхеу вниз с лева на право а не с лево на право с веху вниз

В Sega она идет так:

Пример одного квадратика 8 x 8
Код
0 20 40 60 80 A0 C0 E0
2 22 42 62 82 A2 C2 E2
4 24 44 64 84 A4 C4 E4
6 26 46 66 86 A6 C6 E6
8 28 48 68 88 A8 C8 E8
A 2A 4A 6A 8A AA CA EA
C 2C 4C 6C 8C AC CC EC
E 2E 4E 6E 8E AE CE E8
Есть формула которая переводит к слову вот она

Sega_Color * 255 / 14

Где Sega_Color это цвет из таблицы (Шестнадцетеричное значение от 0 до 14 увеличивается на 2)

И да. Цвет в SEGA BGR а не RGB
0
8943 / 4855 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
08.07.2018, 02:23 9
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
правильное рисование палитры это с верхеу вниз с лева на право а не с лево на право с веху вниз
Будет тебе домашнее задание. Там исправить всего одну строчку
1
46 / 20 / 5
Регистрация: 29.12.2015
Сообщений: 1,863
08.07.2018, 05:05  [ТС] 10
Цитата Сообщение от ViterAlex Посмотреть сообщение
Будет тебе домашнее задание. Там исправить всего одну строчку
Да это легко. Но еще мне нужно чтобы узнать цвет можно при перемещении мышкки а именно событие которое будет происходить при смене цвета при движении мышки не только при клики.

А цвет рамочки лучше делать инверсией выбранного но так как там вроде можно задать цвет рамочки то достаточно событие при перемещении мышки но именно что со срабатыванием по квадратикам. Возврат координат желательно. Кординат относительно кубиков.

Добавлено через 54 минуты
Слушай помоги с одним. Как сделать из координат _hoverRect.X и _hoverRect.Y координаты под _colors
Не могу формулу подобрать.
0
Эксперт .NET
6511 / 4087 / 1606
Регистрация: 09.05.2015
Сообщений: 9,553
08.07.2018, 05:09 11
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Не могу формулу подобрать.
А в OnMouseClick что тогда?
1
46 / 20 / 5
Регистрация: 29.12.2015
Сообщений: 1,863
08.07.2018, 06:04  [ТС] 12
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            using (var b = new SolidBrush(Color.Empty))
            {
                for (int i = 0; i < 8; i++)
                    for (int j = 0; j < 64; j++)
                    {
                        b.Color = _colors[i, j];
                        var x = _side * (j % 32);
                        var y = i * _side + 8 * _side * (j / 32);
                        e.Graphics.FillRectangle(b, x, y, _side, _side);
                    }
                //Прямоугольник выделения
                var clri = _hoverRect.X / _side;
                var clrj = _hoverRect.Y / _side;
                clri += 32 * (clrj / 8);
                clrj %= 8;
                var clr = _colors[clrj, clri];
                var pen = new Pen(Color.FromArgb(clr.A, 0xFF - clr.R, 0xFF - clr.G, 0xFF - clr.B));
                e.Graphics.DrawRectangle(pen, _hoverRect);
            }
        }
Вот теперь идеально. Ещеб рамочку мигающию на выбранном цвете но сам врядле я смогу сделать да и это так косметка. Главное что удобный компонент для выбора цвета приставки сеги теперь есть.

Добавлено через 6 минут
Хотя в принцыпе почему не смогу. Создать дополнительный элемент рамочки и изменять его на mouseclick ну и прикрутить таймер в котором менять альфа канал. В теории должно получится!

Добавлено через 6 минут
Только вопрос если изменять значение переменной которое будет отвечать за альфа канал рамки то будет ли срабатывать Paint

Добавлено через 34 минуты
В принцыпе сделал мерцание. Но над бы оптимизировать. Так как я всегда говнокодом
Вот весь код:
C#
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
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
 
namespace SegaPalette.Controls
{
    [DefaultProperty("SelectedColor")]
    [DefaultEvent("SelectedColorChanged")]
    public class SegaPalette : Control
    {
        private Color[,] _colors;
        private Rectangle _hoverRect = Rectangle.Empty;
        private Rectangle _hoverSelectRect = Rectangle.Empty;
        private static int _AnimAlphaHoverSelectRect = 255;
        private Timer _tmrAnimAlphaHoverSelectRect = new  Timer()
        {
            Interval = 100,
            Enabled = true
        };
 
        void _tmrAnimAlphaHoverSelectRect_Tick(object sender, EventArgs e)
        {
            if (_AnimAlphaHoverSelectRect == 255)
            {
                _AnimAlphaHoverSelectRect = 0;
                Invalidate();
                return;
            }
            else
            {
                _AnimAlphaHoverSelectRect = 255;
                Invalidate();
                return;
            }
        }
 
        private Color _selectedColor;
 
        public event EventHandler<SelectedColorChangedEventArgs> SelectedColorChanged;
        /// <summary>
        /// Выбранный цвет
        /// </summary>
        public Color SelectedColor
        {
            get { return _selectedColor; }
            protected set
            {
                if (_selectedColor != value)
                {
                    var oldColor = _selectedColor;
                    _selectedColor = value;
                    OnSelectedColorChanged(new SelectedColorChangedEventArgs { NewColor = _selectedColor, OldColor = oldColor });
                }
            }
        }
 
        protected virtual void OnSelectedColorChanged(SelectedColorChangedEventArgs e)
        {
            SelectedColorChanged?.Invoke(this, e);
        }
 
        private int _side;
        /// <summary>
        /// Размер квадрата одного цвета
        /// </summary>
        protected virtual int Side
        {
            get => _side; set
            {
                _side = value;
 
                _hoverRect.Width = _side;
                _hoverRect.Height = _side;
 
                _hoverSelectRect.Width = _side;
                _hoverSelectRect.Height = _side;
            }
        }
 
        public SegaPalette()
        {
            _tmrAnimAlphaHoverSelectRect.Tick += _tmrAnimAlphaHoverSelectRect_Tick;
            SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true);
            SetColors();
            Side = 8;
        }
        //Определение цветов палитры
        private void SetColors()
        {
            _colors = new Color[8, 64];
            var col = new double[8] { 0, 2, 4, 6, 8, 10, 12, 14 };
            var norm = new Func<double, int>((val) => (int)(val * 255 / 14));
 
            for (int i = 0; i < 8; i++)
                for (int l = 0; l < 8; l++)
                    for (int k = 0; k < 8; k++)
                        _colors[k, l + 8 * i] = Color.FromArgb(255, norm(col[k]), norm(col[l]), norm(col[i]));
        }
        //Прорисовка контрола
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            using (var b = new SolidBrush(Color.Empty))
            {
                for (int i = 0; i < 8; i++)
                    for (int j = 0; j < 64; j++)
                    {
                        b.Color = _colors[i, j];
                        var x = _side * (j % 32);
                        var y = i * _side + 8 * _side * (j / 32);
                        e.Graphics.FillRectangle(b, x, y, _side, _side);
                    }
                //Прямоугольник выделения
                var clri = _hoverRect.X / _side;
                var clrj = _hoverRect.Y / _side;
                clri += 32 * (clrj / 8);
                clrj %= 8;
                var clr = _colors[clrj, clri];
                var pen = new Pen(Color.FromArgb(clr.A, 0xFF - clr.R, 0xFF - clr.G, 0xFF - clr.B));
                e.Graphics.DrawRectangle(pen, _hoverRect);
 
                //Прямоугольник выбранного цвета
                clri = _hoverSelectRect.X / _side;
                clrj = _hoverSelectRect.Y / _side;
                clri += 32 * (clrj / 8);
                clrj %= 8;
                clr = _colors[clrj, clri];
                pen = new Pen(Color.FromArgb(_AnimAlphaHoverSelectRect, 0xFF - clr.R, 0xFF - clr.G, 0xFF - clr.B), 2);
                e.Graphics.DrawRectangle(pen, _hoverSelectRect);
            }
        }
 
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            //Положение выделения
            var pt = new Point((e.X / _side) * _side, (e.Y / _side) * _side);
            if (pt != _hoverRect.Location)
            {
                _hoverRect.Location = pt;
                Invalidate();
            }
        }
        //Смена выбранного цвета
        protected override void OnMouseClick(MouseEventArgs e)
        {
            base.OnMouseClick(e);
            _hoverSelectRect = _hoverRect;
            Invalidate();
            var i = _hoverRect.X / _side;
            var j = _hoverRect.Y / _side;
            i += 32 * (j / 8);
            j %= 8;
            SelectedColor = _colors[j, i];
        }
 
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            //Размер формы в пропорции 2:1
            Width = (Width / 32) * 32;
            Height = Width / 2;
            Side = Width / 32;
        }
 
        protected override Cursor DefaultCursor => Cursors.Hand;
 
        protected override Size DefaultSize => new Size(256, 128);
    }
 
    public class SelectedColorChangedEventArgs
    {
        public Color OldColor { get; set; }
        public Color NewColor { get; set; }
    }
}
0
8943 / 4855 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
08.07.2018, 09:20 13
Чтобы не мерцало, обновлять нужно только то место, где находится курсор + пару пикселей. Получение цвета из координат вынести в отдельный метод, так же и инверсию цвета:
Кликните здесь для просмотра всего текста
C#
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
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
 
namespace SegaPalette.Controls
{
    [DefaultProperty("SelectedColor")]
    [DefaultEvent("SelectedColorChanged")]
    public class SegaPalette : Control
    {
        private Color[,] _colors;
        private Rectangle _hoverRect = Rectangle.Empty;
        private Color _selectedColor;
        private Color _hoverColor;
        private Timer _animateSelection = new Timer { Interval = 100 };
 
        public event EventHandler<SelectedColorChangedEventArgs> SelectedColorChanged;
        /// <summary>
        /// Выбранный цвет
        /// </summary>
        public Color SelectedColor
        {
            get { return _selectedColor; }
            protected set
            {
                if (_selectedColor != value)
                {
                    var oldColor = _selectedColor;
                    _selectedColor = value;
                    OnSelectedColorChanged(new SelectedColorChangedEventArgs { NewColor = _selectedColor, OldColor = oldColor });
                }
            }
        }
 
        protected virtual void OnSelectedColorChanged(SelectedColorChangedEventArgs e)
        {
            SelectedColorChanged?.Invoke(this, e);
        }
 
        private int _side;
        /// <summary>
        /// Размер квадрата одного цвета
        /// </summary>
        protected virtual int Side
        {
            get => _side; set
            {
                _side = value;
                _hoverRect.Width = _side;
                _hoverRect.Height = _side;
            }
        }
 
        public SegaPalette()
        {
            SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true);
            SetColors();
            Side = 8;
            _animateSelection.Tick += _animateSelection_Tick;
            _animateSelection.Start();
        }
 
        private void _animateSelection_Tick(object sender, EventArgs e)
        {
            var inc = _hoverColor.A >= 224 ? -32 : 32;
            _hoverColor = Color.FromArgb((_hoverColor.A + inc) % 255, _hoverColor);
            var rect = _hoverRect;
            rect.Inflate(2, 2);
            Invalidate(rect);
        }
 
        //Определение цветов палитры
        private void SetColors()
        {
            _colors = new Color[8, 64];
            var col = new double[8] { 0, 2, 4, 6, 8, 10, 12, 14 };
            var norm = new Func<double, int>((val) => (int)(val * 255 / 14));
 
            for (int i = 0; i < 8; i++)
                for (int l = 0; l < 8; l++)
                    for (int k = 0; k < 8; k++)
                        _colors[l, k + 8 * i] = Color.FromArgb(255, norm(col[l]), norm(col[k]), norm(col[i]));
        }
        private Color Inverse(Color color)
        {
            return Color.FromArgb(color.A, 255 - color.R, 255 - color.G, 255 - color.B);
        }
 
        private Color GetColor(int x, int y)
        {
            var i = _hoverRect.X / _side;
            var j = _hoverRect.Y / _side;
            i += 32 * (j / 8);
            j %= 8;
            return _colors[j, i];
        }
 
        //Прорисовка контрола
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            using (var b = new SolidBrush(Color.Empty))
                for (int i = 0; i < 8; i++)
                    for (int j = 0; j < 64; j++)
                    {
                        b.Color = _colors[i, j];
                        var x = _side * (j % 32);
                        var y = i * _side + 8 * _side * (j / 32);
                        e.Graphics.FillRectangle(b, x, y, _side, _side);
                    }
            //Прямоугольник выделения
            using (var pen = new Pen(Inverse(_hoverColor), 2) { Alignment = PenAlignment.Inset })
            {
                e.Graphics.DrawRectangle(pen, _hoverRect);
            }
        }
 
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            //Положение выделения
            var pt = new Point((e.X / _side) * _side, (e.Y / _side) * _side);
            if (pt != _hoverRect.Location)
            {
                _hoverRect.Location = pt;
                _hoverColor = Color.FromArgb(_hoverColor.A, GetColor(e.X, e.Y));
                Invalidate();
            }
        }
        //Смена выбранного цвета
        protected override void OnMouseClick(MouseEventArgs e)
        {
            base.OnMouseClick(e);
 
            SelectedColor = GetColor(e.X, e.Y);
        }
 
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            //Размер формы в пропорции 2:1
            Width = (Width / 32) * 32;
            Height = Width / 2;
            Side = Width / 32;
        }
 
        protected override Cursor DefaultCursor => Cursors.Hand;
 
        protected override Size DefaultSize => new Size(256, 128);
    }
 
    public class SelectedColorChangedEventArgs
    {
        public Color OldColor { get; set; }
        public Color NewColor { get; set; }
    }
}
0
46 / 20 / 5
Регистрация: 29.12.2015
Сообщений: 1,863
09.07.2018, 17:40  [ТС] 14
Еще такой вопрос. А как сделать компонент в виде отдельной dll я про то достаточно ли данный код поместить в приложение dll библиотеки? Или потребует изменений. И если достаточно то какой вид DLL подойдет лучше?

Просто использование возможно потребуется в нескольких местах.

Плюс еще добавить пару методов для конвертации цвета из SEGA палитры в Color и обратно.
0
8943 / 4855 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
09.07.2018, 17:50 15
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
А как сделать компонент в виде отдельной dll
Собственно, я и выложил проект в виде отдельной dll. Делается очень просто: нужно создать проект типа Class Library (Библиотека классов)
0
46 / 20 / 5
Регистрация: 29.12.2015
Сообщений: 1,863
09.07.2018, 17:58  [ТС] 16
Цитата Сообщение от ViterAlex Посмотреть сообщение
Собственно, я и выложил проект в виде отдельной dll. Делается очень просто: нужно создать проект типа Class Library (Библиотека классов)
Нет там компонент в виде контрола (шаблона омпонентов) но я так понял что разницы никакой.

Только какой тип библиотеки выбрать
Компонент SEGA палитры

Хорошо бы без привязки NET Framework судя по всему это должно быть Библиотека классов устаревшая переносимая хотя если всеже ET прийдется использовать то тогда хотябы версии 2.0
0
8943 / 4855 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
09.07.2018, 18:03 17
Alexandr_7, контрол под WinForms, поэтому по-любому нужна библиотека под Net Framework.
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
там компонент в виде контрола (шаблона омпонентов) но я так понял что разницы никакой
контрол — это тоже класс, поэтому разницы никакой
0
46 / 20 / 5
Регистрация: 29.12.2015
Сообщений: 1,863
09.07.2018, 19:23  [ТС] 18
При создании класса компонента создаются 2 метода

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
 
namespace SEGA_Palette
{
    public partial class AL7_SegaPalette : Component
    {
        public AL7_SegaPalette()
        {
            InitializeComponent();
        }
 
        public AL7_SegaPalette(IContainer container)
        {
            container.Add(this);
 
            InitializeComponent();
        }
    }
}
Для чего нужен public AL7_SegaPalette(IContainer container)
0
8943 / 4855 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
09.07.2018, 19:28 19
Alexandr_7, этот метод вызывается при добавлении, скажем, на форму в дизайнере и в качестве контейнера передаётся форма. Называется это внедрением зависимости (dependency injection)
0
46 / 20 / 5
Регистрация: 29.12.2015
Сообщений: 1,863
09.07.2018, 19:31  [ТС] 20
Добавлено через 46 секунд
Цитата Сообщение от ViterAlex Посмотреть сообщение
Alexandr_7, этот метод вызывается при добавлении, скажем, на форму в дизайнере и в качестве контейнера передаётся форма. Называется это внедрением зависимости (dependency injection)
Я так понял оно не нужно для палитры сега. Ну раз этого нет в вашем примере.
0
09.07.2018, 19:31
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.07.2018, 19:31
Помогаю со студенческими работами здесь

Завасает джойстик в эмуляторе Sega
Здравствуйте, установил эмулятор сега, GENS. Подсоединил к нему джойстик DVTech, раньше работал...

Найти стратегию по описанию (SEGA)
На приставке SEGA раньше была малопопулярная пошаговая стратегия, называлась из двух слов...

Sega Genesis - Создание рогалика
Решил создать игру на Sega Genesis/Megadrive, на вооружение взял Assembler. Вопрос следующий:...

Интересует название игры для SEGA
Помню такая странноватая игрушка была мною куплена, её очень расхваливал продавец. Я тогда в ней не...

Приставки Sega, Dandy на нашем компьютере
Популярные приставки детства на компе, кто еще не знает - качаем и вспоминаем беззаботные годы! В...

Sega Genesis - Ничего не выводится на экране эмулятора
Работаю по материалу: https://huguesjohnson.com/programming/genesis/tiles-sprites/ Вот код: ;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Книги и учебные ресурсы по C#
InfoMaster 08.01.2025
Базовые учебники и руководства Одной из лучших книг для начинающих является "C# 10 и . NET 6 для начинающих" Эндрю Троелсена и Филиппа Джепикса . Книга последовательно раскрывает основные концепции. . .
Что такое NullReferenceEx­­­ception и как исправить?
InfoMaster 08.01.2025
NullReferenceException - одно из самых распространенных исключений, с которым сталкиваются разработчики на C#. Это исключение возникает при попытке обратиться к членам объекта (методам, свойствам или. . .
Что такое Null Pointer Exception (NPE) и как это исправить?
InfoMaster 08.01.2025
Null Pointer Exception (NPE) - это одно из самых распространенных исключений в Java, которое возникает при попытке использовать ссылку на объект, значение которой равно null. Это исключение относится. . .
Русский язык в консоли C++
InfoMaster 08.01.2025
При разработке программ на C++ одной из частых проблем, с которой сталкиваются русскоязычные программисты, является корректное отображение кириллицы в консольных приложениях. Эта проблема особенно. . .
Telegram бот на C#
InfoMaster 08.01.2025
Разработка ботов для Telegram стала неотъемлемой частью современной экосистемы мессенджеров. C# предоставляет мощный и удобный инструментарий для создания разнообразных ботов, от простых. . .
Использование GraphQL в Go (Golang)
InfoMaster 08.01.2025
Go (Golang) является одним из наиболее популярных языков программирования, используемых для создания высокопроизводительных серверных приложений. Его архитектурные особенности и встроенные. . .
Что лучше использовать при создании класса в Java: сеттеры или конструктор?
Alexander-7 08.01.2025
Вопрос подробнее: На вопрос: «Когда одновременно создаются конструктор и сеттеры в классе – это нормально?» куратор уточнил: «Ваш класс может вообще не иметь сеттеров, а только конструктор и геттеры. . .
Как работать с GraphQL на TypeScript
InfoMaster 08.01.2025
Введение в GraphQL и TypeScript В современной разработке веб-приложений GraphQL стал мощным инструментом для создания гибких и эффективных API. В сочетании с TypeScript, эта технология. . .
Счётчик на базе сумматоров + регистров и генератора сигналов согласования.
Hrethgir 07.01.2025
Создан с целью проверки скорости асинхронной логики: ранее описанного сумматора и предополагаемых fast регистров. Регистры созданы на базе ранее описанного, предполагаемого fast триггера. То-есть. . .
Как перейти с Options API на Composition API в Vue.js
BasicMan 06.01.2025
Почему переход на Composition API актуален В мире современной веб-разработки фреймворк Vue. js продолжает эволюционировать, предлагая разработчикам все более совершенные инструменты для создания. . .
Архитектура современных процессоров
inter-admin 06.01.2025
Процессор (центральный процессор, ЦП) является основным вычислительным устройством компьютера, которое выполняет обработку данных и управляет работой всех остальных компонентов системы. Архитектура. . .
История создания реляционной модели баз данных, правила Кодда
Programming 06.01.2025
Предпосылки создания реляционной модели В конце 1960-х годов компьютерная индустрия столкнулась с серьезными проблемами в области управления данными. Существовавшие на тот момент модели данных -. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru