Книга: Программирование мобильных устройств на платформе .NET Compact Framework
Листинг 13.1. Использование конечного автомата для экспериментов с двумя различными вариантами компоновки пользовательского интерфейса
Листинг 13.1. Использование конечного автомата для экспериментов с двумя различными вариантами компоновки пользовательского интерфейса
//--------------------------------------------------------------------------
//Конечный автомат, который управляет отображением кнопок, закрываемых рукой
//--------------------------------------------------------------------------
private enum GameUIState {
startScreen = 1,
waitForNextQuestion = 2,
waitForUserToStateKnowledge = 4,
waitForUserToAnswerMultipleChoice = 8
}
//Текущее состояние игры
private GameUIState m_GameUIState;
//==========================================================================
//Конечный автомат, используемый для управления пользовательским интерфейсом
//==========================================================================
private void StateChangeForGameUI(GameUIState newGameUIState) {
m_GameUIState = newGameUIState;
switch (newGameUIState) {
case GameUIState.startScreen:
buttonAskQuestion.Visible = true;
buttonAskQuestion.Text = "Start";
//Скрыть текстовое окно
textBoxAskQuestion.Visible = false;
SetAnswerButtonVisibility(false);
SetDifficultyButtonVisibility(false);
break;
case GameUIState.waitForNextQuestion:
setQuestionText("List answer details here... rn" +
"Lots of space to write...rn" +
"Waiting for user to select next question...");
textBoxAskQuestion.Visible = true;
buttonAskQuestion.Text = "Next";
buttonAskQuestion.Visible = true;
//Убедиться в том, что кнопка отображается на переднем плане
buttonAskQuestion.BringToFront();
SetAnswerButtonVisibility(false);
SetDifficultyButtonVisibility(false);
#if PLAYFIELD ON_BOTTOM //ПОЛЕ ИГРЫ располагается под пользовательскими
//элементами управления
textBoxAskQuestion.Height = pictureBoxGameBoard.Top - 2;
#else //ПОЛЕ ИГРЫ располагается над пользовательскими
//элементами управления
textBoxAskQuestion.Top = pictureBoxGameBoard.Top + pictureBoxGameBoard.Height + 2;
textBoxAskQuestion.Height = this.Height - textBoxAskQuestion.Top;
#endif
break;
case GameUIState.waitForUserToStateKnowledge:
SetTextForVocabularyQuestion();
textBoxAskQuestion.Visible = true;
buttonAskQuestion.Visible = false;
SetAnswerButtonVisibility(false);
SetDifficultyButtonVisibility(true);
#if PLAYFIELD_ON_BOTTOM //ПОЛЕ ИГРЫ располагается под пользовательскими
//элементами управления
textBoxAskQuestion.Height = buttonShowAnswers_AdvancedVersion.Top - 2;
#else //ПОЛЕ ИГРЫ располагается над пользовательскими
//элементами управления
textBoxAskQuestion.Top = buttonShowAnswers_AdvancedVersion.Top + buttonShowAnswers_AdvancedVersion.Height + 2;
textBoxAskQuestion.Height = this.Height - textBoxAskQuestion.Top;
#endif
break;
case GameUIState.waitForUserToAnswerMultipleChoice:
buttonAskQuestion.Visible = false;
SetDifficultyButtonVisibility(false);
//Сделать кнопки доступными, чтобы пользователь мог щелкать на них
SetAnswerButtonEnabled(true);
SetAnswerButtonVisibility(true);
#if PLAYFIELD_ON_BOTTOM //ПОЛЕ ИГРЫ располагается под пользовательскими
//элементами управления
textBoxAskQuestion.Height = buttonAnswer0.Top - 2;
#else //ПОЛЕ ИГРЫ располагается над пользовательскими
//элементами управления.
//Разместить текстовое окно таким образом, чтобы экран использовался
//эффективно
textBoxAskQuestion.Top = buttonAnswer5.Top + buttonAnswer5.Height + 2;
textBoxAskQuestion.Height =this.Height - textBoxAskQuestion.Top;
#endif
break;
//======================================================================
//Задать статическую компоновку нашего пользовательского интерфейса.
//Сюда входят все элементы, позиции которых остаются фиксированными.
//Изменения в остальные свойства внесет конечный автомат
//пользовательского интерфейса
//======================================================================
private void SetStartControlPositionAndState() {
pictureBoxGameBoard.Width = 240;
pictureBoxGameBoard.Height = 176;
//Установить размеры кнопок множественного выбора вариантов ответов
const int answerButtons_dx = 117;
const int answerButtons_dy = 18;
buttonAnswer0.Width = answerButtons_dx;
buttonAnswer0.Height = answerButtons_dy;
buttonAnswer1.Size = buttonAnswer0.Size;
buttonAnswer2.Size = buttonAnswer0.Size;
buttonAnswer3.Size = buttonAnswer0.Size;
buttonAnswer4.Size = buttonAnswer0.Size;
buttonAnswer5.Size = buttonAnswer0.Size;
buttonShowAnswers_AdvancedVersion.Width = answerButtons_dx;
buttonShowAnswers_AdvancedVersion.Height = 24;
buttonShowAnswers_SimpleVersion.Size = buttonShowAnswers_AdvancedVersion.Size;
//Расстояние (в пикселях) между соседними кнопками
const int dx_betweenButtons = 3;
const int dy_betweenButtons = 2;
const int answerbuttons_beginX = 3;
//Создать задний план для нашего изображения, чтобы мы видели
//его в процессе тестирования
System.Drawing.Bitmap gameBoard;
gameBoard = new System.Drawing.Bitmap(pictureBoxGameBoard.Width, pictureBoxGameBoard.Height);
System.Drawing.Graphics gameboard_gfx;
gameboard_gfx = System.Drawing.Graphics.FromImage(gameBoard);
gameboard_gfx.Clear(System.Drawing.Color.Yellow);
System.Drawing.Pen myPen = new System.Drawing.Pen(System.Drawing.Color.Blue);
gameboard_gfx.DrawRectangle(myPen, 2, 2, gameBoard.Width-4, gameBoard.Height-6);
myPen.Dispose();
gameboard_gfx.Dispose();
pictureBoxGameBoard.Image = gameBoard;
//Разместить текстовое окно, в котором содержатся задаваемые вопросы,
//a также подробные ответы для пользователей
textBoxAskQuestion.Left = 0;
textBoxAskQuestion.Width = 240;
buttonAskQuestion.Width = 64;
buttonAskQuestion.Height = 20;
#if PLAYFIELD_ON_BOTTOM //ПОЛЕ ИГРЫ располагается под пользовательскими
//элементами управления
const int answerbuttons_beginY = 42;
const int showanswers_beginY = 77;
//--------------------------------------------------------
//Задать кнопки выбора вариантов Easy или Hard режима игры
//--------------------------------------------------------
buttonShowAnswers_AdvancedVersion.Top = showanswers_beginY;
buttonShowAnswers_SimpleVersion.Top = showanswers_beginY;
//------------------------------
//Задать набор вариантов ответов
//------------------------------
//Задать элемент управления, по которому будут выравниваться
//все остальные элементы управления
buttonAnswer0.Top = answerbuttons_beginY;
//Поместить PictureBox под элементами управления
pictureBoxGameBoard.Top = (answerButtons_dy + dy_betweenButtons) * 3 + answerbuttons beginY;
buttonAskQuestion.Top = 0;
buttonAskQuestion.Left = 174;
textBoxAskQuestion.Top = 0;
#else //ПОЛЕ ИГРЫ располагается над пользовательскими
//элементами управления
const int answerbuttons_beginY = 174;
//--------------------------------------------------------
//Задать кнопки выбора вариантов Easy или Hard режима игры
//--------------------------------------------------------
buttonShowAnswers_AdvancedVersion.Top = answerbuttons_beginY;
buttonShowAnswers_SimpleVersion.Top = answerbuttons_beginY;
//-----------------------------
//Задать набор вариантов ответа
//-----------------------------
//Задать элемент управления, по которому будут выравниваться
//все остальные элементы управления
buttonAnswer0.Top = answerbuttons_beginY;
pictureBoxGameBoard.Top = 0;
buttonAskQuestion.Top = answerbuttons_beginY;
buttonAskQuestion.Left = 174;
#endif
buttonShowAnswers_AdvancedVersion.Left = answerbuttons_beginX;
buttonShowAnswers_SimpleVersion.Left = buttonShowAnswers_AdvancedVersion.Left + answerButtons_dx + dx betweenButtons;
pictureBoxGameBoard.Left = 0;
pictureBoxGameBoard.Width = 240;
pictureBoxGameBoard.Height = 172;
buttonAnswer0.Left = answerbuttons_beginX;
buttonAnswer1.Left = buttonAnswer0.Left + answerButtons_dx + dx_betweenButtons;
buttonAnswer1.Top = buttonAnswer0.Top;
//следующий ряд
buttonAnswer2.Left = buttonAnswer0.Left;
buttonAnswer2.Top = buttonAnswer0.Top + answerButtons_dy + dy_betweenButtons;
buttonAnswer3.Left = buttonAnswer2.Left + answerButtons_dx + dx_betweenButtons;
buttonAnswer3.Top = buttonAnswer2.Top;
//следующий ряд
buttonAnswer4.Left = buttonAnswer2.Left;
buttonAnswer4.Top = buttonAnswer2.Top + answerButtons_dy + dy_betweenButtons;
buttonAnswer5.Left = buttonAnswer4.Left + answerButtons_dx + dx_betweenButtons;
buttonAnswer5.Top = buttonAnswer4.Top;
}
//-------------------------------------------------------------
//Вспомогательная функция, которая позволяет задавать состояние
//видимости кнопок, отображающих ответы из словаря
//-------------------------------------------------------------
private void SetAnswerButtonVisibility(bool visibleState) {
buttonAnswer0.Visible = visibleState;
buttonAnswer1.Visible = visibleState;
buttonAnswer2.Visible = visibleState;
buttonAnswer3.Visible = visibleState;
buttonAnswer4.Visible = visibleState;
buttonAnswer5.Visible = visibleState;
}
//-----------------------------------------------------------------
//Вспомогательная функция, вызываемая для задания свойств видимости
//некоторых элементов управления
//-----------------------------------------------------------------
private void SetDifficultyButtonVisibility(bool visibleState) {
buttonShowAnswers_AdvancedVersion.Visible = visibleState;
buttonShowAnswers_SimpleVersion.Visible = visibleState;
}
//-------------------------------------------------------------
//Вспомогательная функция, которая позволяет задавать состояние
//видимости кнопок, отображающих ответы из словаря
//-------------------------------------------------------------
private void SetAnswerButtonEnabled(bool enabledState) {
buttonAnswer0.Enabled = enabledState;
buttonAnswer1.Enabled = enabledState;
buttonAnswer2.Enabled = enabledState;
buttonAnswer3.Enabled = enabledState;
buttonAnswer4.Enabled = enabledState;
buttonAnswer5.Enabled = enabledState;
}
//-----------------------------------------------------------------
//Задает текст в текстовом окне и кнопках,
//необходимых для формулирования вопросов.
//
//B случае практической реализации эта функция должна просматривать
//вопросы динамически
//-----------------------------------------------------------------
private void SetTextForVocabularyQuestion() {
setQuestionText("What is the English word for 'der Mensch'?");
buttonAnswer0.Text = "Four";
buttonAnswer1.Text = "Person";
buttonAnswer2.Text = "Three";
buttonAnswer3.Text = "To Jump";
buttonAnswer4.Text = "Newspaper";
buttonAnswer5.Text = "Brother";
}
//Вызывается для оценки варианта ответа, выбранного пользователем
private void evaluateMultipleChoiceAnswer(Button buttonClicked, int selection) {
//Примечание: в практической реализации правильный номер ответа
//определяется динамически и не всегда соответствует "кнопке № 1"
//Если выбранный пользователем вариант ответа не является правильным,
//отменить доступ к нажатой кнопке
if (selection ! = 1) {
//Выбранный вариант ответа является неправильным
buttonClicked.Enabled = false;
} else {
//Пользователь выбрал правильный ответ, продолжить игру
StateChangeForGameUI(GameUIState.waitForNextQuestion);
}
}
//Абстракция, задающая текст вопросов
void setQuestionText(string textIn) {
textBoxAskQuestion.Text = textIn;
}
//----------------------------------------------------------------
//ОБРАБОТЧИК СОБЫТИЙ: Пользователь желает увидеть следующий вопрос
//----------------------------------------------------------------
private void buttonAskQuestion_Click(object sender, System.EventArgs e) {
SetTextForVocabularyQuestion();
StateChangeForGameUI(GameUIState.waitForUserToStateKnowledge);
}
//---------------------------------------------------------------------
//ОБРАБОТЧИК СОБЫТИЙ:
//Пользователь желает ответить на отображенный вопрос и сообщить, какой
//наиболее сложный уровень является для него приемлемым
//---------------------------------------------------------------------
private void buttonShowAnswers_AdvancedVersion_Click(object sender, System.EventArgs e) {
//Установить состояние игры для отображения вариантов выбора
StateChangeForGameUI(GameUIState.waitForUserToAnswerMultipleChoice);
}
//---------------------------------------------------------------------
//ОБРАБОТЧИК СОБЫТИЙ:
//Пользователь желает ответить на отображенный вопрос и сообщить, какой
//наиболее легкий уровень является для него приемлемым
//---------------------------------------------------------------------
private void buttonShowAnswers_SimpleVersion_Click(object sender, System.EventArgs e) {
//Установить состояние игры для отображения вариантов выбора
StateChangeForGameUI(GameUIState.waitForUserToAnswerMultipleChoice);
}
//ОБРАБОТЧИК СОБЫТИЙ: Был выполнен щелчок на кнопке выбора варианта ответа
private void buttonAnswer0_Click(object sender, System.EventArgs e) {
evaluateMultipleChoiceAnswer(buttonAnswer0, 0);
}
//ОБРАБОТЧИК СОБЫТИЙ: Был выполнен щелчок на кнопке выбора варианта ответа
private void buttonAnswer1_Click(object sender, System.EventArgs e) {
evaluateMultipleChoiceAnswer(buttonAnswer1, 1);
}
//ОБРАБОТЧИК СОБЫТИЙ: Был выполнен щелчок на кнопке выбора варианта ответа
private void buttonAnswer2_Click(object sender, System.EventArgs e) {
evaluateMultipleChoiceAnswer(buttonAnswer2, 2);
}
//ОБРАБОТЧИК СОБЫТИЙ: Был выполнен щелчок на кнопке выбора варианта ответа
private void buttonAnswer3_Click(object sender, System.EventArgs e) {
evaluateMultipleChoiceAnswer(buttonAnswer3, 3);
}
//ОБРАБОТЧИК СОБЫТИЙ: Был выполнен щелчок на кнопке выбора варианта ответа
private void buttonAnswer4_Click(object sender, System.EventArgs e) {
evaluateMultipleChoiceAnswer(buttonAnswer4, 4);
}
//ОБРАБОТЧИК СОБЫТИЙ: Был выполнен щелчок на кнопке выбора варианта ответа
private void buttonAnswer5_Click(object sender, System.EventArgs e) {
evaluateMultipleChoiceAnswer(buttonAnswer5, 5);
}
//-------------------------------------------------
//ОБРАБОТЧИК СОБЫТИЙ: Вызывается при загрузке формы
//-------------------------------------------------
private void Form1_Load(object sender, System.EventArgs e) {
//Задать статические свойства нашего визуального интерфейса
SetStartControlPositionAndState();
//Задать динамические свойства, исходя из того, в какое состояние
//игры мы входим
StateChangeForGameUI(GameUIState.startScreen);
}
- Примеры к главе 13 (проектирование пользовательского интерфейса)
- Листинг 10.1. (simpleid.c) Отображение идентификаторов пользователя и группы
- Восстановление с использованием инструмента gbak
- Миграция между различными версиями InterBase
- Типы страниц и их использование
- Использование констант
- Использование переменной окружения ISC_PATH
- Использование сервера Yaffil внутри процесса
- Использование CAST() с типами дата
- Определение пользовательского формата числовых данных
- Использование типов содержимого и столбцов
- Вызов хранимых процедур InterBase с использованием стандартного синтаксиса ODBC