|
Елементи керування
Поле вводу - InpLine (модуль Ctl)
Поле вводу дозволяє юзеру ввести (або відредагувати) текстовий рядок. Ну, а нам, програмерам - узнати, що він там ввів чи наредагував :). Внутрішньо це досить складний елемент керування: якщо Check.inc та Radio.inc займали 4-5 кілобайт, то InpLine.inc тягне на 24 кіло. Воно і не дивно - поле вводу дозволяє вводити, редагувати текст, прокручувати його, виділяти фрагменти та виконувати дії над ними, і все це можна робити як з клавіатури, так і мишкою. На щастя, використання поля вводу не складніше за уже розглянуті елементи керування і схоже на них. Втім, зараз побачите самі.
Політівські поля вводу дещо відрізняються від Windows'них. По-перше, якщо текст у полі надто довгий, по краях поля з'являються стрілочки; з їх допомогою юзер може прокручувати текст у полі мишкою. По-друге, при виділенні текста мишкою координата Y курсора фіксується (тобто мишка не може вискочити за межі поля, поки не буде відпущена її кнопка). Так само, як у Windows, правою кнопкою мишки на полі відкривається його контекстне меню з аналогічними командами - "Вирізати", "Зкопіювати", "Вставити", "Виділити все". Причому якщо Політ був запущений з-під Windows, ці команди працюватимуть із Windows'ним clipboard'ом.
Створення поля вводу
Function InpLine_Create(Prog:PProg; VText:String;
VIcon:Pointer): PControl;
- VText - текст, що буде з самого початку показаний у полі вводу. Тут може бути порожній рядок '', але часто буває зручно вказувати якісь значення за умовчанням (або збережені десь в Ini-файлі). Перший метод використовується у Майстрі програм, а другий - у грі Танки (в її вікні нової гри).
- VIcon - поле вводу може містити іконку (вона буде показана зліва перед текстом). Іноді це буває зручно, щоб указати юзеру на природу тексту в цьому полі вводу. Скажімо, діалог збереження файлів має поле вводу для імені файла: в ньому показана стандартна іконка файла. Звичайно, тут можна вказати Nil, і ніякої іконки в полі вводу не буде.
Встановити обробник зміни тексту в полі вводу
Procedure InpLine_SetOnChangeFunc(Me:PControl;
VOnChange:TInpLineChangeFunc);
Призначити функцію, що буде викликатися при зміні тексту в полі вводу (точніше, при вводі якогось символу). Зверніть увагу, тип цього обробника - не TCtlHandler, як було всюди до цього, а TInpLineChangeFunc. Він описується так:
TInpLineChangeFunc=Function(Me:PProg;
Control:PControl; Ch:String): String;
Це зроблено для того, щоб наш обробник міг проаналізувати, що за символ введено, і якщо треба замінити його на якийсь рядок, який і буде в результаті вставлено в поле вводу.
Ch - введений символ
Результат функції - текст, що буде вставлений в поле. Ясно, що за умовчанням текст цього обробника простий:
InpLineChangeDummy:=Ch
Тобто вставити той символ, який і натиснув юзер. Але можна робити і цікавіші речі. Наприклад, елемент керування SpinEdit (який ми розглянемо пізніше) базується на InpLine, зокрема заміняє його обробник OnChange. Цей обробник SpinEdit'а пропускає лише цифри ('0'..'9'), а для всіх інших символів повертає '' - не вставляти в поле нічого.
Як звичайно, майже завжди ця процедура викликається відразу після InpLine_Create - установити обробник раз і назавжди :).
Намалювати поле вводу
Procedure InpLine_Paint(Me:PControl;
VX1, VY1, VX2:Integer);
Висота поля вводу фіксована і дорівнює 20 пікселям.
Встановити текст у полі вводу
Procedure InpLine_SetText(Me:PControl; VText:String);
VText - новий текст
Отримати текст у полі вводу
Function InpLine_GetText(Me:PControl): String;
Основний прийом роботи з полями вводу.
Програмка-приклад на цей раз хай буде така. У ній буде два поля вводу і кнопка. Коли юзер натисне кнопку, програма створить файл, використавши як його ім'я текст у першому полі вводу, та запише в нього текст із другого поля вводу. Створюємо заготовку TestInp і поїхали:
InpFName, InpContent, BtnWrite: PControl;
Створюємо:
InpFName:=Ctl.InpLine_Create(Me, 'file.txt', Nil);
InpContent:=Ctl.InpLine_Create(Me, '(кілька слів)', Nil);
BtnWrite:=Ctl.Button_Create(Me, 'Записати', Nil, ppLeft,
OnWriteClick);
Пишемо обробник OnWriteClick:
Procedure OnWriteClick(Me:PProg; Control:PControl);
Var
F: Text;
Begin
With Me^, TTestInpData(Data^) Do
Begin
Assign(F, Ctl.InpLine_GetText(InpFName));
Rewrite(F);
Write(F, Ctl.InpLine_GetText(InpContent));
Close(F);
Kernel.ShowHint('Файл записано')
End
End;
На ShowHint не звертайте уваги, це я так, для краси, про хінти ми будемо говорити пізніше. Малюємо все це:
Ctl.InpLine_Paint(InpFName, 10, 10, X2-X1-10);
Ctl.InpLine_Paint(InpContent, 10, 40, X2-X1-10);
Ctl.Button_Paint(BtnWrite, 10, 70, X2-X1-10);
Зверніть увагу - координати X2 у всіх елементів керування дорівнюють X2-X1-10, тобто "на 10 пікселів лівіше правого краю вікна".
Все, програмка має запускатись і працювати. Тепер пропоную зробити трохи цікавішу річ. Хай перше поле вводу (ім'я файла) при вводі літер кирилиці робить їх транслітерацію латинськими. Наприклад, друкуємо "Україна", а в полі з'являється "Ukrayina". Для цього можна скористатися обробником зміни тексту в полі вводу. Логіка його буде не дуже складна: якщо введений символ - літера кирилиці (in ['а'..'я', 'А'..'Я']), тоді замінити його на транслітерований, інакше повернути його ж. Транслітерацію можна було б робити так:
If Ch='а' Then TempStr:='a';
If Ch='б' Then TempStr:='b';
...
If Ch='я' Then TempStr:='ya';
If Ch='А' Then TempStr:='A';
...
OnInpLineChange:=TempStr;
На щастя, у політівському модулі D уже є така функція - TranslitLine (зробити транслітерацію рядка). Ось нею ми і скористаємося. Отже, пишемо обробник:
Function OnFNameChange(Me:PProg; Control:PControl;
Ch:String): String;
Begin
If Ch[1] in ['а'..'я', 'А'..'Я']
Then OnFNameChange:=D.TranslitLine(Ch)
Else OnFNameChange:=Ch
End;
Ах да, і призначаємо цей обробник полю ввода відразу після його створення:
Ctl.InpLine_SetOnChangeFunc(InpFName, OnFNameChange);
Все, можна запускати програмку і гратися :).
| |