VCH: пользовательский аналог компонента CheckBox
Сохранить в файлеОбсудить в форуме
Описание
Некое подобие стандартного компонента VCH CheckBox-a, но формируется исходя из массива, а не из текстовой строки, есть прокрутка.
P.S. версия VCH 1.10
P.S. версия VCH 1.10
Текст примера
/* *************************************************************************************** */ /* *************************************************************************************** */ /* Компонет, организующий список CheckBox-ов из элементов массива pArray, с возможностью прокрутки */ class (TComponent) TMultyChoice_FromArray(pArray:TArray, pLeft:integer, pTop:integer, pWidth:integer, pHeight:integer) var cHeight = pHeight - 1; /* количество строк */ var cWidth = pWidth - 1; /* количество символов в строке */ var CurIndex = 0; /* индекс текущего элемента */ var MinIndex = 0; /* минимальный индекс элемента, помещающегося в окне прокрутки */ var MaxIndex = cHeight; /* максимальный индекс элемента, помещающегося в окне прокрутки */ var MainArr; /* Массив описаний */ var SelArr; /* Массив установленных значений */ var ReadOnly = false; /* флаг только чтение */ var MarkColor = BLACK; /* цвет не выделенного крестика */ var SelMarkColor = WHITE; /* цвет выделенного крестика */ var SelMarkBkGrColor = GREEN; /* цвет фона под выделенным крестиком */ /* ---------------------------------------------- */ /* инициализация некоторых значений */ macro Intialize(pArray:TArray) var i = 0; MainArr = pArray; SelArr = TArray(); while (i < MainArr.size) SelArr[i] = false; i = i + 1; end; Color = BLACK; SelBkGrColor = BkGrColor = LIGHTGRAY; SelColor = BLACK; end; /* ---------------------------------------------- */ /* установить элементу с индексом pIndex, значение pVal */ macro SetValue(pIndex:integer, pVal:bool) if ((pIndex >= 0) and (pIndex < MainArr.size)) SelArr[pIndex] = pVal; Draw(); end; end; /* ---------------------------------------------- */ /* устанавливает значения исходя из массива pArr, который должен содержать true или false */ /* используется для установки значений по умолчанию */ macro SetValuesFromArray(pArr:TArray) var lMax = Min(pArr.size, SelArr.size); var i = 0; while (i < lMax) SetValue(i, pArr[i]); i = i + 1; end; end; /* ---------------------------------------------- */ /* установить всем элементам значение pVal */ macro SetAllValues(pVal:bool) var i = 0; while (i < SelArr.size) SelArr[i] = pVal; i = i + 1; end; Draw(); end; /* ---------------------------------------------- */ /* получить значение элемента с индкесом pIndex */ macro GetValue(pIndex:integer) if ((pIndex >= 0) and (pIndex < MainArr.size)) return SelArr[pIndex]; end; return false; end; /* ---------------------------------------------- */ /* встать на первый элемент в списке (массиве) */ macro GoFirst() CurIndex = 0; MinIndex = 0; MaxIndex = cHeight; end; /* -------------------------------------------------------- */ /* встать на последний элемент в списке (массиве) */ macro GoLast() CurIndex = MainArr.size - 1; MaxIndex = Max(cHeight, MainArr.size - 1); MinIndex = MaxIndex - cHeight; end; /* -------------------------------------------------------- */ /* передвинуться на pStep элементов вниз по списку (массиву) */ macro GoNext(pStep:integer) CurIndex = Min(CurIndex + pStep, MainArr.size - 1); if (CurIndex > MaxIndex) MaxIndex = CurIndex; MinIndex = MaxIndex - cHeight; end; end; /* -------------------------------------------------------- */ /* передвинуться на pStep элементов вверх по списку (массиву) */ macro GoPrev(pStep:integer) CurIndex = Max(CurIndex - pStep, 0); if (CurIndex < MinIndex) MinIndex = CurIndex; MaxIndex = MinIndex + cHeight; end; end; /* -------------------------------------------------------- */ /* рисование */ macro Draw var i = MinIndex, lNum = 0; var lStr; while (i <= MaxIndex) if (i < MainArr.size) if (SelArr[i]) lStr = "X"; else lStr = " "; end; if( Selected ) if (CurIndex == i) OwnerPtr.DrawString(cmLeft, cmTop + lNum, "[", SelColor, SelBkGrColor); OwnerPtr.DrawString(cmLeft + 1, cmTop + lNum, lStr, SelMarkColor, SelMarkBkGrColor); OwnerPtr.DrawString(cmLeft + 2, cmTop + lNum, "] " + PADR(MainArr[i], cWidth - 4), SelColor, SelBkGrColor); else OwnerPtr.DrawString(cmLeft, cmTop + lNum, "[", Color, BkGrColor); OwnerPtr.DrawString(cmLeft + 1, cmTop + lNum, lStr, MarkColor, BkGrColor); OwnerPtr.DrawString(cmLeft + 2, cmTop + lNum, "] " + PADR(MainArr[i], cWidth - 4), Color, BkGrColor); end; else OwnerPtr.DrawString(cmLeft, cmTop + lNum, "[", Color, BkGrColor); OwnerPtr.DrawString(cmLeft + 1, cmTop + lNum, lStr, MarkColor, BkGrColor); OwnerPtr.DrawString(cmLeft + 2, cmTop + lNum, "] " + PADR(MainArr[i], cWidth - 4), Color, BkGrColor); end; else OwnerPtr.DrawString(cmLeft, cmTop + lNum, Replicate(" ", cmRight - cmLeft), BkGrColor, BkGrColor); end; lNum = lNum + 1; i = i + 1; end; end; /* ---------------------------------------------- */ /* обработчик событий */ macro HandleEvent(event) HandleEvent(event); if (event.what.keyDown and (event.KeyCode == kbSpace) and Selected and (not ReadOnly)) /* установка/снятие флага */ SetValue(CurIndex, not GetValue(CurIndex)); DrawView; if (ProcessEvent.OnChange) GenRun(OwnerPtr, CompName + "OnChange"); end; elif (event.what.keyDown and (event.KeyCode == kbDown) and Selected) /* перемещение по стрелке вниз */ GoNext(1); DrawView; elif (event.what.keyDown and (event.KeyCode == kbUp) and Selected) /* перемещение по стрелке вверх */ GoPrev(1); DrawView; elif (event.what.keyDown and (event.KeyCode == kbCtrlPgUp) and Selected) /* клавиша Ctrl+PageUp */ GoFirst; DrawView; elif (event.what.keyDown and (event.KeyCode == kbCtrlPgDn) and Selected) /* клавиша Ctrl+PageDown */ GoLast; DrawView; elif (event.what.keyDown and (event.KeyCode == kbPgDn) and Selected) /* клавиша PageDown */ GoNext(cHeight); DrawView; elif (event.what.keyDown and (event.KeyCode == kbPgUp) and Selected) /* клавиша PageUp */ GoPrev(cHeight); DrawView; elif (event.what.keyDown and (event.KeyCode == kbF6) and Selected) /* клавиша F6 (Отметить/Отменить все) */ SetAllValues(not GetValue(0)); end; end; /* ---------------------------------------------- */ initTComponent("", pLeft, pTop, pLeft + cWidth, pTop + cHeight); Intialize(pArray); end; /* *************************************************************************************** */ /* *************************************************************************************** */ /* Класс формы, где применяется наш компонент TMultyChoice_FromArray */ class (TForm) TForm_MultyChoice(pArray, pLeft, pTop, pWidth, pHeight, pCaption) /* --------------------------------------------------- */ initTForm(pLeft, pTop, pLeft + pWidth, pTop + pHeight + 1); if (pCaption != null) Title = pCaption; else Title = "Выбор элементов"; end; FrameColor = TitleColor = BLACK; BkGrColor = LIGHTGRAY; StatLineMsg = " ~ESC~ Выход ~F6~ Отметить все"; CloseBox = false; /* --------------------------------------------------- */ var List = TMultyChoice_FromArray(pArray, 0, 0, pWidth, pHeight); List.SelBkGrColor = List.BkGrColor = BkGrColor; ComponentInsert(List); /* --------------------------------------------------- */ end; /* *************************************************************************************** */ /* *************************************************************************************** */ /* пример использования */ /* формируем наш массив с описаниями */ var MyArray = TArray(); var DefArr = TArray(); var i = 0; while (i < 500) MyArray[i] = " Моё описание для выбора № " + String(i : 4 : o : r); if (i / 3. == Double(i / 3)) /* устанавливаем значения по умолчанию, т.е. по сути устанавливаем каждый третий флажок */ DefArr[i] = true; else DefArr[i] = false; end; i = i + 1; end; /* вызываем форму */ var k = TForm_MultyChoice(MyArray, 5, 3, 70, 10, "Сделай свой выбор"); k.List.SetValuesFromArray(DefArr); /* устанавливаем значения по умолчанию */ k.ShowModal(); /* просматриваем результаты */ i = 0; PrintLn("ПОЛУЧЕННЫЙ РЕЗУЛЬТАТ:"); while (i < k.List.SelArr.size) PrintLn(String((i + 1) : 4 : l), " ", k.List.MainArr[i], " -> ", k.List.SelArr[i]); i = i + 1; end;