Form Pencereleri

Form penceresi mantığı menü pencerelerinkine oldukça benzemektedir. Her bir form bir ana pencere ve alt pencere ile ilişiklendirilir. Ana pencere başlık, etiket, çerçeve veya kullanıcı her ne istiyorsa gösterir. Alt pencere ise tüm alanları içerir ve onları konumlarına göre gösterir. Bu durum hoş görüntüler üzerinde esnek şekilde değişiklik yapma imkanı verir.

Menü pencerelerine çok benzediğinden oldukça açıklamalı bir örnek sunuyorum. İşlevler aynıdır ve aynı şekilde çalışır.

Örnek 5.33. Form Pencereleri Örneği

#include <form.h>

void print_in_middle(WINDOW *win, int starty, int startx, int width,
     char *string, chtype color);

int main()
{
  FIELD *field[3];
  FORM  *my_form;
  WINDOW *my_form_win;
  int ch, rows, cols;

  /* Curses kipi ilklendir */
  initscr();
  start_color();
  cbreak();
  noecho();
  keypad(stdscr, TRUE);

  /* Renk çiftlerini ilklendir */
  init_pair(1, COLOR_RED, COLOR_BLACK);

  /* Alanları ilklendir */
  field[0] = new_field(1, 10, 6, 1, 0, 0);
  field[1] = new_field(1, 10, 8, 1, 0, 0);
  field[2] = NULL;

  /* alan seçeneklerini ayarla */
  set_field_back(field[0], A_UNDERLINE);
  field_opts_off(field[0], O_AUTOSKIP); /* Bu alan dolduğunda */
                                        /* sonraki alana geçme */
  set_field_back(field[1], A_UNDERLINE);
  field_opts_off(field[1], O_AUTOSKIP);

  /* Formu oluştur ve ekrana yaz */
  my_form = new_form(field);

  /* Form için gerekli alanı hesapla */
  scale_form(my_form, &rows, &cols);

  /* Form ile ilişiklendirilecek pencereyi oluştur */
  my_form_win = newwin(rows + 4, cols + 4, 4, 4);
  keypad(my_form_win, TRUE);

  /* Ana pencereyi ve alt pencereyi ata */
  set_form_win(my_form, my_form_win);
  set_form_sub(my_form, derwin(my_form_win, rows, cols, 2, 2));

  /* Ana pencere etrafında bir çerçeve çiz ve başlık yaz */
  box(my_form_win, 0, 0);
  print_in_middle(my_form_win, 1, 0, cols + 4,
    "Benim Formum", COLOR_PAIR(1));

  post_form(my_form);
  wrefresh(my_form_win);

  mvprintw(LINES - 2, 0,
    "YUKARI ve AŞAĞI ok tuşlarıyla alanlar arasında geçiş yapın");
  refresh();

  /* Kullanıcı istekleri için döngü */
  while((ch = wgetch(my_form_win)) != KEY_F(1))
  { switch(ch)
    { case KEY_DOWN:
        /* sonraki alana git */
        form_driver(my_form, REQ_NEXT_FIELD);
        /* O anki önbelleğin sonuna git */
        /* Son karakterde döngüden çık */
        form_driver(my_form, REQ_END_LINE);
        break;
      case KEY_UP:
        /* Önceki alana git */
        form_driver(my_form, REQ_PREV_FIELD);
        form_driver(my_form, REQ_END_LINE);
        break;
      default:
        /* Eğer bu normak bir karakterse */
        /* Ekrana yazılır                                */
        form_driver(my_form, ch);
        break;
    }
  }

  /* Ekrandan sil ve ayrılan bellek alanını geri ver */
  unpost_form(my_form);
  free_form(my_form);
  free_field(field[0]);
  free_field(field[1]);

  endwin();
  return 0;
}

void print_in_middle(WINDOW *win, int starty, int startx, int width,
     char *string, chtype color)
{ int length, x, y;
  float temp;

  if(win == NULL)
    win = stdscr;
  getyx(win, y, x);
  if(startx != 0)
    x = startx;
  if(starty != 0)
    y = starty;
  if(width == 0)
    width = 80;

  length = strlen(string);
  temp = (width - length)/ 2;
  x = startx + (int)temp;
  wattron(win, color);
  mvwprintw(win, y, x, "%s", string);
  wattroff(win, color);
  refresh();
}