Re[17]: Простой, быстрый, бесплатный грид
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.03.04 18:26
Оценка: :)
Здравствуйте, AndrewVK, Вы писали:

AVK>Фигово. Прикинь что будет если понадобится локализация.


Чего? Внутренней реализации? Может еще и код локализуем?
... << RSDN@Home 1.1.3 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: VirtualGrid - фичи
От: Al-Ko  
Дата: 05.03.04 12:03
Оценка:
Здравствуйте, Al-Ko, Вы писали:

AK>Здравствуйте, VladD2, Вы писали:


AK>Перед проектированием остановимся на основных возможностях VirtualGrid и его элементов:


че-то у нас обсуждение как-то заглохло. Влад, что делаем дальше?
... << RSDN@Home 1.1.3 stable >>
Старый глюк лучше новых двух!
Re[2]: VirtualGrid - фичи
От: SiAVoL Россия  
Дата: 05.03.04 12:13
Оценка:
Здравствуйте, Al-Ko, Вы писали:

AK>че-то у нас обсуждение как-то заглохло.

праздники . Я вот на выходных че-нить попробую осмылить и изложить
AK>Влад, что делаем дальше?
Мне кажется следующим пунктом должно быть выделение основных абстракций с из обязанностями и, возможно, примерным интерфейсом. Главное щас четко разделить обязанности между абстракциями и определить между ними связи
... << RSDN@Home 1.1.3 stable >>
Re[2]: VirtualGrid - фичи
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.03.04 22:22
Оценка:
Здравствуйте, Al-Ko, Вы писали:

AK>че-то у нас обсуждение как-то заглохло. Влад, что делаем дальше?


По-моему давно пора переходить к проектированию интерфейсов и пребным реализациям.
... << RSDN@Home 1.1.3 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: VirtualGrid - фичи
От: SiAVoL Россия  
Дата: 11.03.04 11:24
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>По-моему давно пора переходить к проектированию интерфейсов и пребным реализациям.

угу, согласен. Я вот и собирался к этому перейти на прошлых выходных, но праздники спутали все планы. А сейчас у меня неделя запарочная. Так что я только с понедельника
... << RSDN@Home 1.1.3 stable >>
Re: VirtualGrid - фичи
От: SiAVoL Россия  
Дата: 17.03.04 08:01
Оценка:
Пожалуй пора продолжить . Я тут приведу некие наброски аля первые мысли...
Итак, проведем инвентаризацию, что у нас имеется :
1. абстрактный VirtualGrid — связывает в единый механизм все остальные абстракции. Сам по себе умеет очень мало.
    public abstract class VirtualGrid : Control
    {
        public VirtualGrid() {}

        private bool _RowsHeightConst = true;
        public bool RowsHeightConst
        {
            get { return _RowsHeightConst; }
            set { _RowsHeightConst = value; }
        }

        private bool _ColumnsHeightConst = false;
        public bool ColumnsHeightConst
        {
            get { return _ColumnsHeightConst; }
            set { _ColumnsHeightConst = value; }
        }

        private VGColumnCollection _Columns = new VGColumnCollection();
        public VGColumnCollection Columns
        {
            get { return _Columns; }
            set { _Columns = value; }
        }

        private IVGDataSource _DataSource = null;
        public IVGDataSource DataSource
        {
            get { return _DataSource; }
            set { _DataSource = value; }
        }
    
        private VGHorScroller _HorScroller;
        public HorScroller HorScroller
        {
            get { return _HorScroller; }
            set { _HorScroller = value; }
        }

        private VGVertScroller _VertScroller;
        public VGVertScroller VertScroller
        {
            get { return _VertScroller; }
            set { _VertScroller = value; }
        }
    
    }

2. Интерфейс источника данных IVGDataSource — знает количество строк, предоставляет по запросу данные.
    public interface IVGDataSource
    {
        int RowsCount { get; }
        object GetData(int Row);
        event EventHandler DataChanged;
    }

3. Колонка VGColumn и коллекция колонок VGColumnCollection
    public class VGColumn
    {
        public VGColumn()
        {
        }

        private string _Name;
        public string Name
        {
            get {return _Name; }
            set { _Name = value; }
        }

        private string _Title;
        public string Title
        {
            get { return _Title; }
            set { _Title = value; }
        }
    }
    
    public class VGColumnCollection : CollectionBase
    {
        public VGColumnCollection()
        {
        }

        public VGColumn this[int index]
        {
            get { return (VGColumn)List[index]; }
            set { List[index] = value; }                                        
        }

        public VGColumn this[string Name]
        {
            get { return null; }
            set { }
        }
    }

4. Строка VGRow и коллекция строк VGRowCollection (на сколько я понимаю, наш грид полностью симметричен относительно колонок/строк)
5. Скроллеры. Имеется некий абстрактный класс скроллеров, вертикальный и горизонтальный скроллеры наследуются от него
    public abstract class VGScroller
    {
        public VGScroller()
        {
        }

        protected int _MaxSize;
        public int MaxSize
        {
            get { return _MaxSize; }
            set { _MaxSize = value; }
        }

        protected int _MinSize;
        public int MinSize
        {
            get { return _MinSize; }
            set { _MinSize = value; }
        }

        protected int _Value;
        public int Value
        {
            get { return _Value; }
            set
            {
                _Value = value;
                OnValueChanged();
            }
        }

        public event EventHandler ValueChanged;
        protected void OnValueChanged()
        {
            if (ValueChanged != null)
                ValueChanged(this, new EventArgs());
        }
    }

public class VGGorScroller : VGScroller { /*...*/ }
public class VGVerScroller : VGScroller { /*...*/ }

6. Некая абстракция для управления фокусом и выделением...
... << RSDN@Home 1.1.3 stable >>
Re[2]: VirtualGrid - фичи
От: Al-Ko  
Дата: 19.03.04 13:00
Оценка:
Здравствуйте, SiAVoL, Вы писали:

ok, давай поэтапно.

SAV> public abstract class VirtualGrid : Control

SAV> {
1. От чего насследуется VirtualGrid.
Если мы наследуемся от Control'а, то нам для обеспечения скроллинга нужно будет создавать свои контролы скроллбаров и лепить их к краям контрола.
Преимущества такого подхода: не нужно лезть в WndProc и ловить WM_xSCROLL сообщения для окна, а обрабатывать только события Scroll этих скроллбаров. Недостатки: скроллбары будут находиться в клиентской области окна, поэтому придется каждый раз при вычислениях это учитывать; при одновременном появлении двух скроллбаров нужно лепить в правый нижний угол квадратик-панельку, для того, чтобы там не было дырки .
Если наследоваться от ScrollableControl или его наследников, то таких проблем не будет, но нужно будет работать с сообщениями окна.
Короче, вроде как мы с Владом определились отталкиваться от второго варианта. Только надо вынести Scroller в отдельный класс, который потом можно будет заменить или изменить.

2. Интерфейс IVirtualGrid.

Пока остановимся на этом:

    interface IVirtualGrid
    {
        int RowsCount
        {
            get;
            set;
        }

        int TopRow
        {
            get;
            set;
        }

        bool CacheRowsHeight
        {
            get;
            set;
        }

        int GetBottomRow();

    }


к этому интерфейсу будет обращаться грид-наследник.

Дальше. Это частный случай, если строки и столбцы имеют неизменные размеры, это ОК:

SAV> private bool _RowsHeightConst = true;

SAV> private bool _ColumnsHeightConst = false;

это здесь не нужно:

SAV> private IVGDataSource _DataSource = null;

SAV> public IVGDataSource DataSource
SAV> {
SAV> get { return _DataSource; }
SAV> set { _DataSource = value; }
SAV> }

скроллеры пока убираем:
SAV> private VGHorScroller _HorScroller;
SAV> }


ага, это ты пытался делать нечто вроде интерфейса IVirtualGrid.

SAV>[/c#]

SAV>2. Интерфейс источника данных IVGDataSource — знает количество строк, предоставляет по запросу данные.
SAV>
SAV>    public interface IVGDataSource
SAV>    {
SAV>        int RowsCount { get; }
SAV>        object GetData(int Row);
SAV>        event EventHandler DataChanged;
SAV>    }
SAV>


Это не нужно, с данными работает наследник VirtualGrid.

3. Теперь о столбцах и их коллекции.

Надо решить, делать ли Column компонентом (его наследником), как предложил Михалик (как DataGridColumnStyle), или не делать этого.
После этого нужно двигаться дальше.
... << RSDN@Home 1.1.3 stable >>
Старый глюк лучше новых двух!
Re[3]: VirtualGrid - фичи
От: SiAVoL Россия  
Дата: 19.03.04 13:20
Оценка:
Здравствуйте, Al-Ko, Вы писали:

AK>Если наследоваться от ScrollableControl или его наследников, то таких проблем не будет, но нужно будет работать с сообщениями окна.

AK>Короче, вроде как мы с Владом определились отталкиваться от второго варианта. Только надо вынести Scroller в отдельный класс, который потом можно будет заменить или изменить.
Да я вроде тоже собирался его от ScrollableControl унаследовать, запарил

AK>это здесь не нужно:

возможно...

AK>Это не нужно, с данными работает наследник VirtualGrid.

может быть имеет смысл общие методы работы с данными вынести в VirtualGrid? что бы можно было унифицированно работать с разными гридами

AK>Надо решить, делать ли Column компонентом (его наследником), как предложил Михалик (как DataGridColumnStyle), или не делать этого.

Я большого смысла в этом не вижу

AK>После этого нужно двигаться дальше.

двигаемся дальше
... << RSDN@Home 1.1.3 stable >>
Re[3]: VirtualGrid - фичи
От: orangy Россия
Дата: 19.03.04 13:27
Оценка:
Здравствуйте, Al-Ko, Вы писали:

AK>Если мы наследуемся от Control'а, то нам для обеспечения скроллинга нужно будет создавать свои контролы скроллбаров и лепить их к краям контрола.

Так и придётся делать.

AK>Если наследоваться от ScrollableControl или его наследников, то таких проблем не будет, но нужно будет работать с сообщениями окна.

Так не получится. Как только у тебя появятся хидеры колонок, ты поимеешь кучу проблем с ScrollableControl, не говоря уж о тех проблемах, которые в нём есть от рождения — очень уж плохо управляется там скроллингом... Я пробовал и так и эдак, и через интероп — складывать скроллеры как внутренние контролы всяко удобнее.
... << RSDN@Home 1.1.3 beta 2 >>
"Develop with pleasure!"
Re[3]: VirtualGrid - фичи
От: orangy Россия
Дата: 19.03.04 13:33
Оценка: 5 (1)
Здравствуйте, Al-Ko, Вы писали:

AK>Надо решить, делать ли Column компонентом (его наследником), как предложил Михалик (как DataGridColumnStyle), или не делать этого.

Делать. Если у колонки появятся всякие события, например, HeaderRightClick, Sort или еще чего — тебе будет сложновато подписаться на эти события из дизайнера — придётся писать свой хитрый редактор коллекции с подпиской на сообщения, ну или делать это из кода. Кроме того, всё таки
// удобнее писать 
clmName.ForeColor = Color.Red;
// чем 
grid.Columns["Name"].ForeColor = Color.Red;

Только не забыть поставить [DesignTimeVisible(false)], чтобы в Component Tray они не болтались почём зря.
... << RSDN@Home 1.1.3 beta 2 >>
"Develop with pleasure!"
Re[4]: VirtualGrid - фичи
От: SiAVoL Россия  
Дата: 19.03.04 13:43
Оценка:
Здравствуйте, orangy, Вы писали:

O>Здравствуйте, Al-Ko, Вы писали:


AK>>Надо решить, делать ли Column компонентом (его наследником), как предложил Михалик (как DataGridColumnStyle), или не делать этого.

O>Делать.
А получится ли нормально DataGridColumnStyle воткнуть в наш грид? чет я не думаю. хотя у меня уже щас сображалка плохо втыкает, надо завтра подумать
... << RSDN@Home 1.1.3 stable >>
Re[5]: VirtualGrid - фичи
От: orangy Россия
Дата: 19.03.04 13:47
Оценка:
Здравствуйте, SiAVoL, Вы писали:

AK>>>Надо решить, делать ли Column компонентом (его наследником), как предложил Михалик (как DataGridColumnStyle), или не делать этого.

O>>Делать.
SAV>А получится ли нормально DataGridColumnStyle воткнуть в наш грид? чет я не думаю. хотя у меня уже щас сображалка плохо втыкает, надо завтра подумать
Нет, ну прямо DataGridColumnStyle не надо втыкать, там интерналы есть. Надо свой класс колонки написать. Согласно архитектуре.
... << RSDN@Home 1.1.3 beta 2 >>
"Develop with pleasure!"
Re[5]: VirtualGrid - фичи
От: SiAVoL Россия  
Дата: 19.03.04 13:49
Оценка:
AK>>>Надо решить, делать ли Column компонентом (его наследником)
тьфу, блин. Прочитал неправильно Компонентом надо делать
SAV>щас сображалка плохо втыкает
все, пора уходить в плановый запой — расслабляться (за подробностями сюда
Автор: SiAVoL
Дата: 18.03.04
)
... << RSDN@Home 1.1.3 stable >>
Re[4]: VirtualGrid - ScrollableControl
От: Al-Ko  
Дата: 19.03.04 14:07
Оценка:
Здравствуйте, orangy, Вы писали:

O
O>Так не получится. Как только у тебя появятся хидеры колонок, ты поимеешь кучу проблем с ScrollableControl, не говоря уж о тех проблемах, которые в нём есть от рождения — очень уж плохо управляется там скроллингом... Я пробовал и так и эдак, и через интероп — складывать скроллеры как внутренние контролы всяко удобнее.

ScrollableControl нужен только для того, чтобы обеспечить наличие скроллбаров в клиентской области и также генерирования сообщений скроллинга для окна. После этого весь его ненавязчивый сервис надо попытаться отключить. Технологией с отдельными скроллбарами-контролами я владею, а вот хотелось бы попробовать именно с сабжем. А что, есть печальный опыт, который говорит что это не получится?
... << RSDN@Home 1.1.3 stable >>
Старый глюк лучше новых двух!
Re[4]: VirtualGrid - фичи
От: Al-Ko  
Дата: 19.03.04 14:11
Оценка:
Здравствуйте, orangy, Вы писали:
O>Делать. Если у колонки появятся всякие события, например, HeaderRightClick, Sort или еще чего — тебе будет сложновато подписаться на эти события из дизайнера — придётся писать свой хитрый редактор коллекции с подпиской на сообщения, ну или делать это из кода. Кроме того, всё таки
O>[c#]
O>// удобнее писать
O>clmName.ForeColor = Color.Red;

вот очень лежит душа именно так и сделать
... << RSDN@Home 1.1.3 stable >>
Старый глюк лучше новых двух!
Re[5]: VirtualGrid - ScrollableControl
От: orangy Россия
Дата: 20.03.04 12:52
Оценка:
Здравствуйте, Al-Ko, Вы писали:

AK>ScrollableControl нужен только для того, чтобы обеспечить наличие скроллбаров в клиентской области

Картинка такая на мой взгляд должна быть:
clmHeader1|clmHeader2|clmHeader3...
--------------------------------[^]
--------------------------------[|]
--------------------------------[|]
--------------------------------[|]
--------------------------------[v]
[<----------------------------->...

Т.е. хидеры не должны скроллиться, и скроллер не должен продолжаться на них. Второе еще можно игнорировать, но первое нельзя. А вот ScrollableControl — штука хитрая, он будет "оптимизировать" скроллинг, т.е. двигать битмапу, которую ты нарендерил на область контрола. И сначала скроллить её, а потом просить тебя нарисовать остаток. Не связывайтесь с ним, кривой он.

AK>и также генерирования сообщений скроллинга для окна.

Долго ли подписаться на события от VScrollBar? Там надо-то на ValueChanged подписаться да и всё. Ну и при отрисовке учитывать его размер.
... << RSDN@Home 1.1.3 beta 2 >>
"Develop with pleasure!"
Re[6]: VirtualGrid - ScrollableControl
От: Al-Ko  
Дата: 20.03.04 14:02
Оценка:
Здравствуйте, orangy, Вы писали:

O>Здравствуйте, Al-Ko, Вы писали:


AK>>ScrollableControl нужен только для того, чтобы обеспечить наличие скроллбаров в клиентской области

O>Картинка такая на мой взгляд должна быть:
clmHeader1|clmHeader2|clmHeader3...
--------------------------------[^]
--------------------------------[|]
--------------------------------[|]
--------------------------------[|]
--------------------------------[v]
[<----------------------------->...


да не совсем такая, а такая:

clmHeader1|clmHeader2|clmHeader3[^]
--------------------------------[|]
--------------------------------[|]
--------------------------------[|]
--------------------------------[|]
--------------------------------[v]
[<----------------------------->...




O>Т.е. хидеры не должны скроллиться,

безусловно
O>и скроллер не должен продолжаться на них.
должен — посмотри на любой грид, да хоть бы на тот, что в Хоуме
O>Второе еще можно игнорировать, но первое нельзя. А вот ScrollableControl — штука хитрая, он будет "оптимизировать" скроллинг, т.е. двигать битмапу, которую ты нарендерил на область контрола. И сначала скроллить её, а потом просить тебя нарисовать остаток. Не связывайтесь с ним, кривой он.
а если ему ноги выдрать, обрабатывая WM_xSCROLL, все равно будет скроллить? Не пробовал, если честно, но надо будет заняться.

O>Долго ли подписаться на события от VScrollBar? Там надо-то на ValueChanged подписаться да и всё.

боюсь, что придется подписаться для каждого скроллбара на Scroll event и обрабатывать типы этого события SmallIncrement/Decrement, LargeIncrement/Decrement, ThumbTrack, а также еще события MouseWheel.
O>Ну и при отрисовке учитывать его размер.
Да, в этом случае нужно при ресайзинге контрола, а также при изменениях в строках/столбцах формировать "свой" client rectangle с учетом размеров скроллбаров, и все события мыши, скроллинга и отрисовку контролировать и осуществлять в нем.
Почему-то Влад выступает против этого способа. См.Re[12]: Completely managed TreeViewControl
Автор: Al-Ko
Дата: 30.01.04
(касательно скроллбаров) и ветки ниже.
... << RSDN@Home 1.1.3 stable >>
Старый глюк лучше новых двух!
Re[7]: VirtualGrid - ScrollableControl
От: orangy Россия
Дата: 20.03.04 14:25
Оценка:
Здравствуйте, Al-Ko, Вы писали:

O>>Картинка такая на мой взгляд должна быть:

AK>
AK>clmHeader1|clmHeader2|clmHeader3...
AK>--------------------------------[^]
AK>--------------------------------[|]
AK>--------------------------------[|]
AK>--------------------------------[|]
AK>--------------------------------[v]
AK>[<----------------------------->...
AK>


AK>да не совсем такая, а такая:


AK>
AK>clmHeader1|clmHeader2|clmHeader3[^]
AK>--------------------------------[|]
AK>--------------------------------[|]
AK>--------------------------------[|]
AK>--------------------------------[|]
AK>--------------------------------[v]
AK>[<----------------------------->...
AK>


Это не очень принципиально, я же написал. Но всё-таки мне кажется, что полосы прокрутки должны быть вокруг того, что прокручивается. Возьми, к примеру это окно (окно написания сообщения в янусе). Тут тоже есть Header и Message Body. Я думаю, тебя бы сильно удивило, если бы скроллер был бы от верха хидера до низа тела письма

O>>Второе еще можно игнорировать, но первое нельзя. А вот ScrollableControl — штука хитрая, он будет "оптимизировать" скроллинг, т.е. двигать битмапу, которую ты нарендерил на область контрола. И сначала скроллить её, а потом просить тебя нарисовать остаток. Не связывайтесь с ним, кривой он.

AK>а если ему ноги выдрать, обрабатывая WM_xSCROLL, все равно будет скроллить? Не пробовал, если честно, но надо будет заняться.
А смысл тогда им пользоватся?

O>>Долго ли подписаться на события от VScrollBar? Там надо-то на ValueChanged подписаться да и всё.

AK>боюсь, что придется подписаться для каждого скроллбара на Scroll event и обрабатывать типы этого события SmallIncrement/Decrement, LargeIncrement/Decrement, ThumbTrack, а также еще события MouseWheel.
Не придётся. По-крайней мере, мне не пришлось в моём виртуальном деревянном гриде

O>>Ну и при отрисовке учитывать его размер.

AK>Да, в этом случае нужно при ресайзинге контрола, а также при изменениях в строках/столбцах формировать "свой" client rectangle с учетом размеров скроллбаров, и все события мыши, скроллинга и отрисовку контролировать и осуществлять в нем.
Что-то вы, батенька, усложняете При нормально прописанной структуре контрола это элементарно всё...

AK>Почему-то Влад выступает против этого способа. См.Re[12]: Completely managed TreeViewControl
Автор: Al-Ko
Дата: 30.01.04
(касательно скроллбаров) и ветки ниже.

Почитаю.
... << RSDN@Home 1.1.3 beta 2 >>
"Develop with pleasure!"
Re[8]: VirtualGrid - ScrollableControl
От: Al-Ko  
Дата: 20.03.04 14:55
Оценка:
Здравствуйте, orangy, Вы писали:



O>Это не очень принципиально, я же написал. Но всё-таки мне кажется, что полосы прокрутки должны быть вокруг того, что прокручивается. Возьми, к примеру это окно (окно написания сообщения в янусе). Тут тоже есть Header и Message Body. Я думаю, тебя бы сильно удивило, если бы скроллер был бы от верха хидера до низа тела письма

ну мы же про грид говорим.

O>>>Второе еще можно игнорировать, но первое нельзя. А вот ScrollableControl — штука хитрая, он будет "оптимизировать" скроллинг, т.е. двигать битмапу, которую ты нарендерил на область контрола. И сначала скроллить её, а потом просить тебя нарисовать остаток. Не связывайтесь с ним, кривой он.

AK>>а если ему ноги выдрать, обрабатывая WM_xSCROLL, все равно будет скроллить? Не пробовал, если честно, но надо будет заняться.
O>А смысл тогда им пользоватся?
скроллбары не будут входить в ClientRectangle...
... << RSDN@Home 1.1.3 stable >>
Старый глюк лучше новых двух!
Re[7]: VirtualGrid - ScrollableControl
От: orangy Россия
Дата: 20.03.04 15:08
Оценка:
Здравствуйте, Al-Ko, Вы писали:

AK>Почему-то Влад выступает против этого способа. См.Re[12]: Completely managed TreeViewControl
Автор: Al-Ko
Дата: 30.01.04
(касательно скроллбаров) и ветки ниже.

Почитал ту ветку (честно скажу, по диагонали). Во многом не согласен с Владом, ну да это как обычно Например, я считаю абсолютно неверным рассчёт во время отрисовки. Мало того, что реакция контрола на требование перерисоваться замедляется, так еще и программно с ним работать сложнее становится. Прикинь на досуге реализацию функций:
int GetRowAt(int x, int y); // для хит-тестов разных, например для драг-дропа
int GetRowBottom(int index); // для выпадающего меню, чтобы строку не загораживало
void ScrollRowIntoView(int index); // для программного показа строки, например свежедобавленой

Конечно, это можно реализовать и так, и эдак, но всё-таки мне кажется, что лучше иметь готовый рассчитанный layout. Да, не забудь про резиновые колонки, это очень полезная функция. Я имею ввиду возможность задавать не только фиксированную ширину (в пикселях), но и в процентах или в весах.

Что касается ScrollableControl и иже с ними... Попробуй с этим чудом поработать, сам поймёшь. Слишком много думать за программиста пытается. В этом вопросе с Владом я согласен, лучше делать свой скроллирующий контрол, но такой, какой надо. Насчёт же Авалона — я бы с этим пока не заморачивался, рано еще. Т.е. наследование может быть таким: Control -> ScrollableControlEx (это свой) -> VirtualGridBase -> ну и дальше клиенты.

Еще один момент. Не злоупотребляй интерфейсами. Они заставляют клиента (наследника VG) слишком много имплементировать. Например, если строки переменной высоты можно будет ресайзить, то должен быть предусмотрен какой-то механизм сообщения клиенту об этом для сохранения настроек. А если оно совсем не нужно клиенту? Не хотелось бы иметь VG, ради использования которого надо написать еще кучу кода, причём вида return false; или return null; Вообще не очень пониманию, зачем при общении базового класса с производным нужны какие бы то ни было интерфейсы, и так средств достаточно. Ну да вам виднее, вы уже много про это думали Удачи!
... << RSDN@Home 1.1.3 beta 2 >>
"Develop with pleasure!"
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.