Beispiel #1
0
void
Window::SetEnabled(bool enabled)
{
  AssertThread();

  const bool was_focused = !enabled && HasFocus();

  ::EnableWindow(hWnd, enabled);

  if (was_focused && ::GetFocus() == NULL) {
    /* The window lost its keyboard focus because it got disabled; now
       the focus is in limbo, and can only be recovered by clicking on
       another control, which is impossible for Altair users (no touch
       screen).  This is a major WIN32 API misdesign that is
       documtented here:
       https://blogs.msdn.com/b/oldnewthing/archive/2004/08/04/208005.aspx */

    ContainerWindow *root = GetRootOwner();
    if (root != NULL)
      /* to work around this problem, we pass focus to the main
         window, which will bounce it to the next dialog control; this
         kludge is needed because this Window doesn't know the dialog
         code, and trusts that the main window will do the right
         thing */
      root->SetFocus();
  }
}
Beispiel #2
0
ProgressWindow::ProgressWindow(ContainerWindow &parent)
{
  set(parent,
      InfoBoxLayout::landscape
      ? (LPCTSTR)IDD_PROGRESS_LANDSCAPE
      : (LPCTSTR)IDD_PROGRESS);

  TCHAR Temp[1024];
  _stprintf(Temp, _T("%s %s"), gettext(_T("Version")), XCSoar_Version);
  set_item_text(IDC_VERSION, Temp);

#ifdef WINDOWSPC
  RECT rc = parent.get_client_rect();
  RECT rcp = get_client_rect();

  move(rc.left, rc.top, rcp.right - rcp.left, rcp.bottom - rcp.top);
#else
#ifndef GNAV
  SHFullScreen(hWnd, SHFS_HIDETASKBAR|SHFS_HIDESIPBUTTON|SHFS_HIDESTARTICON);
#endif
#endif

  insert_after(HWND_TOP, true);

  set_range(0, 100);
  set_step(5);

#ifndef ENABLE_SDL
  ::SetForegroundWindow(hWnd);
#endif /* !ENABLE_SDL */
  update();
}
Beispiel #3
0
ProgressWindow::ProgressWindow(ContainerWindow &parent)
  :background_color(COLOR_WHITE),
   background_brush(background_color),
   position(0)
{
  PixelRect rc = parent.GetClientRect();
  WindowStyle style;
  style.Hide();
  Create(parent, rc, style);

  const unsigned width = rc.right - rc.left, height = rc.bottom - rc.top;

  // Load progress bar background
  bitmap_progress_border.Load(IDB_PROGRESSBORDER);

  // Determine text height
#ifndef USE_GDI
  font.Load(FontDescription(Layout::FontScale(10)));
  text_height = font.GetHeight();
#else
  VirtualCanvas canvas({1, 1});
  text_height = canvas.GetFontHeight();
#endif

  // Make progress bar height proportional to window height
  const unsigned progress_height = height / 20;
  const unsigned progress_horizontal_border = progress_height / 2;
  progress_border_height = progress_height * 2;

  // Initialize message text field
  PixelRect message_rc = rc;
  message_rc.bottom -= progress_border_height + height / 48;
  message_rc.top = message_rc.bottom - text_height;
  TextWindowStyle message_style;
  message_style.center();
  message.Create(*this, NULL, message_rc, message_style);

#ifndef USE_GDI
  message.SetFont(font);
#endif

  // Initialize progress bar
  PixelRect pb_rc;
  pb_rc.left = progress_horizontal_border;
  pb_rc.right = pb_rc.left + width - progress_height;
  pb_rc.top = height - progress_border_height + progress_horizontal_border;
  pb_rc.bottom = pb_rc.top + progress_height;
  ProgressBarStyle pb_style;
  progress_bar.Create(*this, pb_rc, pb_style);

  message.InstallWndProc(); // needed for OnChildColor()

  // Set progress bar step size and range
  SetRange(0, 1000);
  SetStep(50);

  // Show dialog
  ShowOnTop();
}
Beispiel #4
0
ProgressWindow::ProgressWindow(ContainerWindow &parent)
  :background_color(COLOR_WHITE),
   background_brush(background_color),
   position(0)
{
  PixelRect rc = parent.get_client_rect();
  WindowStyle style;
  style.hide();
  set(parent, rc.left, rc.top, rc.right, rc.bottom, style);

  unsigned width = rc.right - rc.left, height = rc.bottom - rc.top;

  // Load progress bar background
  bitmap_progress_border.load(IDB_PROGRESSBORDER);

  // Determine text height
#ifdef ENABLE_SDL
  font.set("Droid Sans", 12);
  text_height = font.get_height();
#else
  VirtualCanvas canvas(1, 1);
  text_height = canvas.text_height(_T("W"));
#endif

  // Make progress bar height proportional to window height
  unsigned progress_height = height / 20;
  unsigned progress_horizontal_border = progress_height / 2;
  progress_border_height = progress_height * 2;

  // Initialize message text field
  TextWindowStyle message_style;
  message_style.center();
  message.set(*this, NULL, 0,
              height - progress_border_height - text_height - (height/48),
              width, text_height, message_style);

#ifdef ENABLE_SDL
  message.set_font(font);
#endif

  // Initialize progress bar
  ProgressBarStyle pb_style;
  progress_bar.set(*this, progress_horizontal_border,
                   height - progress_border_height + progress_horizontal_border,
                   width - progress_height,
                   progress_height, pb_style);

  message.install_wndproc(); // needed for on_color()

  // Set progress bar step size and range
  set_range(0, 1000);
  set_step(50);

  // Show dialog
  show_on_top();
  update();
}
Beispiel #5
0
TabBarControl::TabBarControl(ContainerWindow &_parent, const DialogLook &look,
                             PixelRect tab_rc,
                             const WindowStyle style, bool vertical)
  :tab_display(nullptr)
{
  Create(_parent, _parent.GetClientRect(), style);

  tab_display = new TabDisplay(*this, look, *this, tab_rc, vertical);

  pager.Move(MakePagerRect(GetClientRect(), tab_rc, vertical));
}
Beispiel #6
0
Window *
ContainerWindow::FindPreviousControl(Window *reference)
{
  assert(reference != NULL);

  if (reference == this)
    return NULL;

  while (true) {
    ContainerWindow *container = reference->parent;
    assert(container != NULL);

    Window *control = container->FindPreviousChildControl(reference);
    if (control != NULL)
      return control;

    if (container == this)
      return NULL;

    reference = container;
  }
}
Beispiel #7
0
MenuBar::MenuBar(ContainerWindow &parent, const ButtonLook &look)
{
  const PixelRect rc = parent.GetClientRect();

  WindowStyle style;
  style.Hide();
  style.Border();

  for (unsigned i = 0; i < MAX_BUTTONS; ++i) {
    PixelRect button_rc = GetButtonPosition(i, rc);
    buttons[i].Create(parent, look, _T(""), button_rc, style);
  }
}
Beispiel #8
0
Window *
ContainerWindow::find_next_control(Window *reference)
{
  assert(reference != NULL);

  if (reference == this)
    return NULL;

  while (true) {
    ContainerWindow *container = reference->parent;
    assert(container != NULL);

    Window *control = container->find_next_child_control(reference);
    if (control != NULL)
      return control;

    if (container == this)
      return NULL;

    reference = container;
  }
}
Beispiel #9
0
MenuBar::MenuBar(ContainerWindow &parent)
{
  const PixelRect rc = parent.get_client_rect();

  ButtonWindowStyle style;
  style.Hide();
  style.Border();
  style.multiline();

  for (unsigned i = 0; i < MAX_BUTTONS; ++i) {
    PixelRect button_rc = GetButtonPosition(i, rc);
    buttons[i].set(parent, _T(""), button_rc, style);
  }
}
Beispiel #10
0
MenuBar::MenuBar(ContainerWindow &parent)
{
  const RECT rc = parent.get_client_rect();
  int x, y, xsize, ysize;

  ButtonWindowStyle style;
  style.hide();
  style.border();
  style.multiline();

  for (unsigned i = 0; i < MAX_BUTTONS; ++i) {
    GetButtonPosition(i, rc, &x, &y, &xsize, &ysize);
    buttons[i].set(parent, _T(""), i, x, y, xsize, ysize,
                   style);
  }
}
Beispiel #11
0
int
WndForm::ShowModal()
{
  assert_none_locked();

#define OPENCLOSESUPPRESSTIME 500
#ifndef USE_GDI
  ContainerWindow *root = get_root_owner();
  WindowReference old_focus_reference = root->GetFocusedWindowReference();
#else
  HWND oldFocusHwnd;
#endif /* USE_GDI */

  PeriodClock enter_clock;
  if (is_embedded() && !is_altair())
    enter_clock.update();

  show_on_top();

  mModalResult = 0;

#ifdef USE_GDI
  oldFocusHwnd = ::GetFocus();
  if (oldFocusHwnd != NULL)
    ::SendMessage(oldFocusHwnd, WM_CANCELMODE, 0, 0);
#endif /* USE_GDI */
  set_focus();
  focus_first_control();

  bool hastimed = false;
  WndForm::timeAnyOpenClose.update(); // when current dlg opens or child closes

  main_window.add_dialog(this);

#ifndef USE_GDI
  main_window.refresh();
#endif

#ifdef ANDROID
  EventLoop loop(*event_queue, main_window);
  Event event;
#elif defined(ENABLE_SDL)
  EventLoop loop(main_window);
  SDL_Event event;
#else
  DialogEventLoop loop(*this);
  MSG event;
#endif

  while ((mModalResult == 0 || force) && loop.get(event)) {
#if defined(ENABLE_SDL) && !defined(ANDROID)
    if (event.type == SDL_QUIT) {
      mModalResult = mrCancel;
      continue;
    }
#endif

    if (!main_window.FilterEvent(event, this))
      continue;

    // hack to stop exiting immediately
    if (is_embedded() && !is_altair() && !hastimed &&
        is_user_input(event)) {
      if (!enter_clock.check(200))
        /* ignore user input in the first 200ms */
        continue;
      else
        hastimed = true;
    }

    if (is_embedded() && is_mouse_up(event) &&
        !timeAnyOpenClose.check(OPENCLOSESUPPRESSTIME))
      /* prevents child click from being repeat-handled by parent if
         buttons overlap */
      continue;

    if (mOnKeyDownNotify != NULL && is_key_down(event) &&
#ifdef USE_GDI
        identify_descendant(event.hwnd) &&
#endif
        !check_special_key(this, event) &&
        mOnKeyDownNotify(*this, get_key_code(event)))
      continue;

#if defined(ENABLE_SDL) && !defined(ANDROID)
    if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_TAB) {
      /* the Tab key moves the keyboard focus */
      const Uint8 *keystate = ::SDL_GetKeyState(NULL);
      event.key.keysym.sym = keystate[SDLK_LSHIFT] || keystate[SDLK_RSHIFT]
        ? SDLK_UP : SDLK_DOWN;
    }
#endif

    if (is_key_down(event) &&
#ifdef USE_GDI
        identify_descendant(event.hwnd) &&
#endif
        (get_key_code(event) == VK_UP || get_key_code(event) == VK_DOWN)) {
      /* VK_UP and VK_DOWN move the focus only within the current
         control group - but we want it to behave like Shift-Tab and
         Tab */

      if (!check_key(this, event)) {
        /* this window doesn't handle VK_UP/VK_DOWN */
        if (get_key_code(event) == VK_DOWN)
          focus_next_control();
        else
          focus_previous_control();
        continue;
      }
    }

#ifndef USE_GDI
    if (is_key_down(event) && get_key_code(event) == VK_ESCAPE) {
      mModalResult = mrCancel;
      continue;
    }
#endif

    /* map VK_ESCAPE to mrOK on Altair, because the Escape key is expected to 
       be the one that saves and closes a dialog */
    if (is_altair() && is_key_down(event) && get_key_code(event) == VK_ESCAPE) {
      mModalResult = mrOK;
      continue;
    }

    loop.dispatch(event);
  } // End Modal Loop

  main_window.remove_dialog(this);

  // static.  this is current open/close or child open/close
  WndForm::timeAnyOpenClose.update();

#ifdef USE_GDI
  SetFocus(oldFocusHwnd);
#else
  if (old_focus_reference.Defined()) {
    Window *old_focus = old_focus_reference.Get(*root);
    if (old_focus != NULL)
      old_focus->set_focus();
  }
#endif /* !USE_GDI */

  return mModalResult;
}
Beispiel #12
0
int
WndForm::ShowModal()
{
#ifndef USE_WINUSER
  ContainerWindow *root = GetRootOwner();
  WindowReference old_focus_reference = root->GetFocusedWindowReference();
#else
  HWND oldFocusHwnd;
#endif /* USE_WINUSER */

  PeriodClock enter_clock;
  if (IsEmbedded())
    enter_clock.Update();

  ShowOnTop();

  modal_result = 0;

  SingleWindow &main_window = GetMainWindow();
  main_window.CancelMode();

#ifdef USE_WINUSER
  oldFocusHwnd = ::GetFocus();
#endif /* USE_WINUSER */
  SetDefaultFocus();

  bool hastimed = false;

  main_window.AddDialog(this);

#ifndef USE_GDI
  main_window.Refresh();
#endif

#if defined(ANDROID) || defined(USE_POLL_EVENT) || defined(ENABLE_SDL)
  EventLoop loop(*event_queue, main_window);
#else
  DialogEventLoop loop(*event_queue, *this);
#endif
  Event event;

  while ((modal_result == 0 || force) && loop.Get(event)) {
    if (!main_window.FilterEvent(event, this)) {
      if (modeless && event.IsMouseDown())
        break;
      else
        continue;
    }

    // hack to stop exiting immediately
    if (IsEmbedded() && !hastimed &&
        event.IsUserInput()) {
      if (!enter_clock.Check(200))
        /* ignore user input in the first 200ms */
        continue;
      else
        hastimed = true;
    }

    if (event.IsKeyDown()) {
      if (OnAnyKeyDown(event.GetKeyCode()))
        continue;

#ifdef ENABLE_SDL
      if (event.GetKeyCode() == SDLK_TAB) {
        /* the Tab key moves the keyboard focus */
#if SDL_MAJOR_VERSION >= 2
        const Uint8 *keystate = ::SDL_GetKeyboardState(nullptr);
        event.event.key.keysym.sym =
            keystate[SDL_SCANCODE_LSHIFT] || keystate[SDL_SCANCODE_RSHIFT]
          ? SDLK_UP : SDLK_DOWN;
#else
        const Uint8 *keystate = ::SDL_GetKeyState(nullptr);
        event.event.key.keysym.sym =
          keystate[SDLK_LSHIFT] || keystate[SDLK_RSHIFT]
          ? SDLK_UP : SDLK_DOWN;
#endif
      }
#endif

      if (
#ifdef USE_WINUSER
          IdentifyDescendant(event.msg.hwnd) &&
#endif
          (event.GetKeyCode() == KEY_UP || event.GetKeyCode() == KEY_DOWN)) {
        /* KEY_UP and KEY_DOWN move the focus only within the current
           control group - but we want it to behave like Shift-Tab and
           Tab */

        if (!CheckKey(this, event)) {
          /* this window doesn't handle KEY_UP/KEY_DOWN */
          if (event.GetKeyCode() == KEY_DOWN)
            FocusNextControl();
          else
            FocusPreviousControl();
          continue;
        }
      }

#ifndef USE_WINUSER
      if (event.GetKeyCode() == KEY_ESCAPE) {
        modal_result = mrCancel;
        continue;
      }
#endif

#ifdef USE_LINUX_INPUT
      if (event.GetKeyCode() == KEY_POWER) {
        /* the Kobo power button closes the modal dialog */
        modal_result = mrCancel;
        continue;
      }
#endif
    }

    if (character_function && (event.GetCharacterCount() > 0)) {
      bool handled = false;
      for (size_t i = 0; i < event.GetCharacterCount(); ++i)
        handled = character_function(event.GetCharacter(i)) || handled;
      if (handled)
        continue;
    }

    loop.Dispatch(event);
  } // End Modal Loop

  main_window.RemoveDialog(this);

#ifdef USE_WINUSER
  ::SetFocus(oldFocusHwnd);
#else
  if (old_focus_reference.Defined()) {
    Window *old_focus = old_focus_reference.Get(*root);
    if (old_focus != nullptr)
      old_focus->SetFocus();
  }
#endif /* !USE_WINUSER */

  return modal_result;
}
Beispiel #13
0
int
WndForm::ShowModal()
{
  AssertNoneLocked();

#define OPENCLOSESUPPRESSTIME 500
#ifndef USE_GDI
  ContainerWindow *root = GetRootOwner();
  WindowReference old_focus_reference = root->GetFocusedWindowReference();
#else
  HWND oldFocusHwnd;
#endif /* USE_GDI */

  PeriodClock enter_clock;
  if (IsEmbedded() && !IsAltair())
    enter_clock.Update();

  ShowOnTop();

  modal_result = 0;

  SingleWindow &main_window = GetMainWindow();
  main_window.CancelMode();

#ifdef USE_GDI
  oldFocusHwnd = ::GetFocus();
#endif /* USE_GDI */
  SetFocus();
  if (default_focus)
    default_focus->SetFocus();
  else
    client_area.FocusFirstControl();

  bool hastimed = false;

  main_window.AddDialog(this);

#ifndef USE_GDI
  main_window.Refresh();
#endif

#if defined(ANDROID) || defined(USE_EGL)
  EventLoop loop(*event_queue, main_window);
#elif defined(ENABLE_SDL)
  EventLoop loop(main_window);
#else
  DialogEventLoop loop(*this);
#endif
  Event event;

  while ((modal_result == 0 || force) && loop.Get(event)) {
    if (!main_window.FilterEvent(event, this)) {
      if (modeless && event.IsMouseDown())
        break;
      else
        continue;
    }

    // hack to stop exiting immediately
    if (IsEmbedded() && !IsAltair() && !hastimed &&
        event.IsUserInput()) {
      if (!enter_clock.Check(200))
        /* ignore user input in the first 200ms */
        continue;
      else
        hastimed = true;
    }

    if (event.IsKeyDown()) {
      if (key_down_function &&
#ifdef USE_GDI
          IdentifyDescendant(event.msg.hwnd) &&
#endif
          !CheckSpecialKey(this, event) &&
          key_down_function(event.GetKeyCode()))
        continue;

#ifdef ENABLE_SDL
      if (event.GetKeyCode() == SDLK_TAB) {
        /* the Tab key moves the keyboard focus */
        const Uint8 *keystate = ::SDL_GetKeyState(NULL);
        event.event.key.keysym.sym =
          keystate[SDLK_LSHIFT] || keystate[SDLK_RSHIFT]
          ? SDLK_UP : SDLK_DOWN;
      }
#endif

      if (
#ifdef USE_GDI
          IdentifyDescendant(event.msg.hwnd) &&
#endif
          (event.GetKeyCode() == KEY_UP || event.GetKeyCode() == KEY_DOWN)) {
        /* KEY_UP and KEY_DOWN move the focus only within the current
           control group - but we want it to behave like Shift-Tab and
           Tab */

        if (!CheckKey(this, event)) {
          /* this window doesn't handle KEY_UP/KEY_DOWN */
          if (event.GetKeyCode() == KEY_DOWN)
            FocusNextControl();
          else
            FocusPreviousControl();
          continue;
        }
      }

#if !defined USE_GDI || defined _WIN32_WCE
      /* The Windows CE dialog manager does not handle KEY_ESCAPE and
         so we have to do it by ourself */

      // On Altair, the RemoteKey ("E" Button) shall also close the analyse-page
      if (IsAltair()) {
#ifdef GNAV
        if (event.GetKeyCode() == KEY_ESCAPE || event.GetKeyCode() == KEY_F15) {
          modal_result = mrOK;
          continue;
        }
#endif
      } else if (event.GetKeyCode() == KEY_ESCAPE) {
        modal_result = mrCancel;
        continue;
      }
#endif
    }

    if (event.IsCharacter() && character_function &&
        character_function(event.GetCharacter()))
      continue;

    loop.Dispatch(event);
  } // End Modal Loop

  main_window.RemoveDialog(this);

#ifdef USE_GDI
  ::SetFocus(oldFocusHwnd);
#else
  if (old_focus_reference.Defined()) {
    Window *old_focus = old_focus_reference.Get(*root);
    if (old_focus != NULL)
      old_focus->SetFocus();
  }
#endif /* !USE_GDI */

  return modal_result;
}