VCH: пользовательский аналог компонента CheckBox

Автор:Ulan
Дата:02.09.2009
Просмотров:4338
Скачиваний:2180
Оценка:, Оценок - 1
Сохранить в файле

Обсудить в форуме

Описание

Некое подобие стандартного компонента VCH CheckBox-a, но формируется исходя из массива, а не из текстовой строки, есть прокрутка.
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;