Пример #1
0
  void Create(const DialogLook &look, PixelSize size) {
    SingleWindow::Create(_T("RunRenderOZ"), size);

    const PixelRect rc = GetClientRect();

    WindowStyle with_border;
    with_border.Border();

    PixelRect oz_rc = rc;
    oz_rc.left = oz_rc.right / 2;
    oz.Create(*this, oz_rc, with_border);

    const PixelRect list_rc(0, 0, rc.right / 2, rc.bottom - 30);

    type_list = new ListControl(*this, look, list_rc,
                                with_border, 25);

    type_list->SetItemRenderer(this);
    type_list->SetCursorHandler(this);
    type_list->SetLength(NUM_OZ_TYPES);

    PixelRect button_rc = rc;
    button_rc.right = (rc.left + rc.right) / 2;
    button_rc.top = button_rc.bottom - 30;
    close_button.Create(*this, *button_look, _T("Close"), button_rc,
                        WindowStyle(),
                        *this, CLOSE);

    oz.set_shape(ObservationZone::Shape::LINE);

    type_list->SetFocus();
  }
Пример #2
0
  void Create(const DialogLook &look, PixelSize size) {
    SingleWindow::Create(_T("RunChartRenderer"), size);

    const PixelRect rc = GetClientRect();

    WindowStyle with_border;
    with_border.Border();

    const PixelRect list_rc(0, 0, 250, rc.bottom - 30);

    type_list = new ListControl(*this, look, list_rc,
                                with_border, 25);

    type_list->SetItemRenderer(this);
    type_list->SetCursorHandler(this);
    type_list->SetLength(ARRAY_SIZE(chart_names));

    PixelRect chart_rc = rc;
    chart_rc.left = list_rc.right;
    chart.Create(*this, chart_rc, with_border);

    PixelRect button_rc = rc;
    button_rc.right = list_rc.right;
    button_rc.top = button_rc.bottom - 30;
    close_button.Create(*this, *button_look, _T("Close"), button_rc,
                        WindowStyle(),
                        *this, CLOSE);

    type_list->SetFocus();
  }
 GaugeThermalAssistantWindow(ContainerWindow &parent,
                             PixelRect rc,
                             const ThermalAssistantLook &look,
                             WindowStyle style=WindowStyle())
   :ThermalAssistantWindow(look, 5, true)
 {
   set(parent, rc, style);
 }
Пример #4
0
 GaugeThermalAssistantWindow(ContainerWindow &parent,
                             PixelRect rc,
                             const ThermalAssistantLook &look,
                             WindowStyle style=WindowStyle())
   :ThermalAssistantWindow(look, 5, true, true),
    dragging(false), pressed(false)
 {
   Create(parent, rc, style);
 }
Пример #5
0
  /* virtual methods from class Window */
  void OnCreate() override {
    SingleWindow::OnCreate();

#ifdef ENABLE_CLOSE_BUTTON
    close_button.Create(*this, *button_look, _T("Close"),
                        GetCloseButtonRect(GetClientRect()),
                        WindowStyle(),
                        *this, CLOSE);
#endif
  }
Пример #6
0
void
TaskPointWidget::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  const Layout layout(rc, look);

  WindowStyle panel_style;
  panel_style.Hide();
  panel_style.Border();
  panel_style.ControlParent();

  ButtonWindowStyle button_style;
  button_style.TabStop();

  CheckBoxStyle check_box_style;
  check_box_style.TabStop();

  WindowStyle dock_style;
  dock_style.ControlParent();

  waypoint_panel.Create(parent, look, layout.waypoint_panel, panel_style);
  waypoint_name.Create(waypoint_panel, layout.waypoint_name);
  waypoint_details.Create(waypoint_panel, look.button, _("Details"),
                          layout.waypoint_details,
                          button_style, *this, DETAILS);
  waypoint_remove.Create(waypoint_panel, look.button, _("Remove"),
                         layout.waypoint_remove,
                         button_style, *this, REMOVE);
  waypoint_relocate.Create(waypoint_panel, look.button, _("Relocate"),
                           layout.waypoint_relocate,
                           button_style, *this, RELOCATE);

  tp_panel.Create(parent, look, layout.tp_panel, panel_style);

  type_label.Create(tp_panel, layout.type_label);
  change_type.Create(tp_panel, look.button, _("Change Type"),
                     layout.change_type,
                     button_style, *this, CHANGE_TYPE);
  map.Create(tp_panel, layout.map, WindowStyle(),
             [this](Canvas &canvas, const PixelRect &rc){
               PaintMap(canvas, rc);
             });
  properties_dock.Create(tp_panel, layout.properties, dock_style);
  optional_starts.Create(tp_panel, look.button, _("Enable Alternate Starts"),
                         layout.optional_starts, button_style,
                         *this, OPTIONAL_STARTS);
  score_exit.Create(tp_panel, look, _("Score exit"),
                    layout.score_exit, check_box_style,
                    *this, SCORE_EXIT);

  RefreshView();
}
Пример #7
0
bool CDialog::RunModeless(CWnd& rParent)
{
	// Initalise members.
	m_bModal     = false;
	m_pParentWnd = &rParent;

	ASSERT(rParent.Handle());
	ASSERT(CModule::This().Handle());
	ASSERT(m_iRscID);

	// Create it.
	HWND hWnd = CreateDialogParam(CModule::This().Handle(), MAKEINTRESOURCE(m_iRscID),
									rParent.Handle(), DlgProc, reinterpret_cast<LPARAM>(this));

	ASSERT(hWnd != NULL);

	// If a child dialog, turn off size grip.
	if (WindowStyle() & WS_CHILD)
		m_bNoSizeGrip = true;

	// Okay?
	return (hWnd != NULL);
}
 GlueGaugeVario(const FullBlackboard &blackboard,
                ContainerWindow &parent, const VarioLook &look,
                int left, int top, unsigned width, unsigned height,
                const WindowStyle style=WindowStyle())
   :GaugeVario(blackboard, parent, look, left, top, width, height, style),
    blackboard_valid(false) {}
Пример #9
0
  /** cover screen, stretch controls horizontally */
  dsFullWidth = 0,
  /** stretch only frame to maintain aspect ratio */
  dsScaled,
  /** like eDialogScaled but center dialog in screen */
  dsScaledCentered,
  /** don't adjust at all (same as !Layout::ScaleSupported()) */
  dsFixed,
  /** stretch horizontal and place to bottom */
  dsScaledBottom
};

extern DialogStyle dialog_style_setting;

/**
 * Sets the global dialog look for loading XML dialogs.
 */
void
SetXMLDialogLook(const DialogLook &dialog_look);

Window *
LoadWindow(const CallBackTableEntry *LookUpTable, SubForm *form,
           ContainerWindow &parent, const TCHAR *resource,
           WindowStyle style=WindowStyle());

WndForm *
LoadDialog(const CallBackTableEntry *LookUpTable, SingleWindow &Parent,
               const TCHAR *resource, const PixelRect *targetRect = NULL);

#endif
Пример #10
0
 void set(ContainerWindow &parent,
          int left, int top, unsigned width, unsigned height,
          const WindowStyle style=WindowStyle()) {
   set(parent, _T("PaintWindow"), left, top, width, height, style);
 }
Пример #11
0
 * Scales based on the DialogStyle of the last XML form loaded by XCSoar.
 * The Window is destroyed by its Form's destructor
 *
 * @param LookUpTable The CallBackTable
 * @param form The WndForm into which the Window is added
 * @param parent The parent window of the control being created
 *    set parent to "form-GetClientRect()" to make top level control
 *    or to a PanelControl to add it to a tab window
 * @param rc the rectangle within the parent for relative coordinates
 * @param FileName The XML filename
 * @return the pointer to the Window added to the form
 */
Window *
LoadWindow(const CallBackTableEntry *LookUpTable, SubForm *form,
           ContainerWindow &parent, const PixelRect &rc,
           const TCHAR *resource, WindowStyle style=WindowStyle());

/**
 * This function returns a WndForm created either from the ressources or
 * from the XML file in XCSoarData(if found)
 * @param LookUpTable The CallBackTable
 * @param FileName The XML filename to search for in XCSoarData
 * @param Parent The parent window (e.g. XCSoarInterface::main_window)
 * @param resource The resource to look for
 * @param targetRect The area where to move the dialog if not parent
 * @return The WndForm object
 */
WndForm *
LoadDialog(const CallBackTableEntry *LookUpTable, SingleWindow &Parent,
               const TCHAR *resource, const PixelRect *targetRect = NULL);
Пример #12
0
 void set(ContainerWindow *parent, const TCHAR *cls, const TCHAR *text,
          const PixelRect rc, const WindowStyle window_style=WindowStyle()) {
   set(parent, cls, text, rc.left, rc.top,
       rc.right - rc.left, rc.bottom - rc.top,
       window_style);
 }
Пример #13
0
struct DialogLook;

class WndFrame : public PaintWindow {
  const DialogLook &look;

  Color caption_color;

  unsigned mCaptionStyle;

  StaticString<300> text;

public:
  WndFrame(ContainerWindow &parent, const DialogLook &look,
           PixelRect rc,
           const WindowStyle style=WindowStyle());

  void SetAlignCenter();
  void SetVAlignCenter();

  void SetText(const TCHAR *_text);

  const TCHAR *GetCaption() const {
    return text.c_str();
  }

  void SetCaption(const TCHAR *_text) {
    SetText(_text);
  }

  void SetCaptionColor(const Color &color) {
Пример #14
0
 void Create(ContainerWindow &parent, PixelRect rc,
          WindowStyle window_style=WindowStyle()) {
   window_style.EnableDoubleClicks();
   ThermalAssistantWindow::Create(parent, rc, window_style);
 }
Пример #15
0
// Called in the PM thread.
void nsFrameWindow::RealDoCreate( HWND hwndP, nsWindow *aParent,
                                  const nsIntRect &aRect,
                                  EVENT_CALLBACK aHandleEventFunction,
                                  nsIDeviceContext *aContext,
                                  nsIAppShell *aAppShell,
                                  nsWidgetInitData *aInitData, HWND hwndO)
{
   nsIntRect rect = aRect;
   if( aParent)  // Offset rect by position of owner
   {
      nsIntRect clientRect;
      aParent->GetBounds(rect);
      aParent->GetClientBounds(clientRect);
      rect.x += aRect.x + clientRect.x;
      rect.y += aRect.y + clientRect.y;
      rect.width = aRect.width;
      rect.height = aRect.height;
      hwndP = aParent->GetMainWindow();
      rect.y = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - (rect.y + rect.height);
   }
   else          // Use original rect, no owner window
   {
      rect = aRect;
      rect.y = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - (aRect.y + aRect.height);
   }

#if DEBUG_sobotka
   printf("\nIn nsFrameWindow::RealDoCreate:\n");
   printf("   hwndP = %lu\n", hwndP);
   printf("   aParent = 0x%lx\n", &aParent);
   printf("   aRect = %ld, %ld, %ld, %ld\n", aRect.x, aRect.y, aRect.height, aRect.width);
#endif

   ULONG fcfFlags = GetFCFlags();

   ULONG style = WindowStyle();
   if( aInitData)
   {
      if( aInitData->clipChildren)
         style |= WS_CLIPCHILDREN;
#if 0
      //
      // Windows has a slightly different idea of what the implications are
      // of a window having or not having the CLIPSIBLINGS style.
      // All 'canvas' components we create must have clipsiblings, or
      // strange things happen & performance actually degrades.
      //
      else
        style &= ~WS_CLIPCHILDREN;
#endif

      if( aInitData->clipSiblings)
         style |= WS_CLIPSIBLINGS;
      else
         style &= ~WS_CLIPSIBLINGS;
   }

#ifdef DEBUG_FOCUS
   mWindowIdentifier = currentWindowIdentifier;
   currentWindowIdentifier++;
   if (aInitData && (aInitData->mWindowType == eWindowType_toplevel))
     DEBUGFOCUS(Create Frame Window);
   else
     DEBUGFOCUS(Create Window);
#endif

   mFrameWnd = WinCreateStdWindow( HWND_DESKTOP,
                                   0,
                                   &fcfFlags,
                                   WindowClass(),
                                   "Title",
                                   style,
                                   NULLHANDLE,
                                   0,
                                   &mWnd);

  
   /* Because WinCreateStdWindow doesn't take an owner, we have to set it */
   if (hwndP)
     WinSetOwner(mFrameWnd, hwndP);


   /* Set some HWNDs and style into properties for fullscreen mode */
   HWND hwndTitleBar = WinWindowFromID(mFrameWnd, FID_TITLEBAR);
   WinSetProperty(mFrameWnd, "hwndTitleBar", (PVOID)hwndTitleBar, 0);
   HWND hwndSysMenu = WinWindowFromID(mFrameWnd, FID_SYSMENU);
   WinSetProperty(mFrameWnd, "hwndSysMenu", (PVOID)hwndSysMenu, 0);
   HWND hwndMinMax = WinWindowFromID(mFrameWnd, FID_MINMAX);
   WinSetProperty(mFrameWnd, "hwndMinMax", (PVOID)hwndMinMax, 0);


   SetWindowListVisibility( PR_FALSE);  // Hide from Window List until shown

   NS_ASSERTION( mFrameWnd, "Couldn't create frame");

   // Frames have a minimum height based on the pieces they are created with,
   // such as titlebar, menubar, frame borders, etc.  We need this minimum
   // height so we can correctly set the frame position (coordinate flipping).
   nsIntRect frameRect = rect;
   long minheight; 

   if ( fcfFlags & FCF_SIZEBORDER) {
      minheight = 2 * WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER);
   }
   else if ( fcfFlags & FCF_DLGBORDER) {
      minheight = 2 * WinQuerySysValue( HWND_DESKTOP, SV_CYDLGFRAME);
   }
   else {
      minheight = 2 * WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER);
   }
   if ( fcfFlags & FCF_TITLEBAR) {
      minheight += WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR);
   }
   if ( frameRect.height < minheight) {
      frameRect.height = minheight;
   }

   // Set up parent data - don't addref to avoid circularity
   mParent = nsnull;

   // Make sure we have a device context from somewhere
   if( aContext)
   {
      mContext = aContext;
      NS_ADDREF(mContext);
   }
   else
   {
      nsresult rc;
      static NS_DEFINE_IID(kDeviceContextCID, NS_DEVICE_CONTEXT_CID);

      rc = CallCreateInstance(kDeviceContextCID, &mContext);
      if( NS_SUCCEEDED(rc))
         mContext->Init(this);
#ifdef DEBUG
      else
         printf( "Couldn't find DC instance for nsWindow\n");
#endif
   }

   // Record bounds.  This is XP, the rect of the entire main window in
   // parent space.  Returned by GetBounds().
   // NB: We haven't subclassed yet, so callbacks to change mBounds won't
   //     have happened!
   mBounds = frameRect;
   mBounds.height = frameRect.height;

   // Record passed in things
   mEventCallback = aHandleEventFunction;

   if( mParent)
      mParent->AddChild( this);

   // call the event callback to notify about creation

   DispatchStandardEvent( NS_CREATE );
   SubclassWindow(TRUE);
   PostCreateWidget();

   // Subclass frame
   fnwpDefFrame = WinSubclassWindow( mFrameWnd, fnwpFrame);
   WinSetWindowPtr( mFrameWnd, QWL_USER, this);


   WinSetWindowPos(mFrameWnd, 0, frameRect.x, frameRect.y, frameRect.width, frameRect.height, SWP_SIZE | SWP_MOVE);
}
Пример #16
0
 void Create(ContainerWindow &parent, PixelRect rc, Color _color,
             const WindowStyle style=WindowStyle()) {
   background_color = _color;
   ContainerWindow::Create(parent, rc, style);
 }
Пример #17
0
void
WaypointDetailsWidget::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  for (const auto &i : waypoint.files_embed) {
    if (images.full())
      break;

    try {
      if (!images.append().LoadFile(LocalPath(i.c_str())))
        images.shrink(images.size() - 1);
    } catch (const std::exception &e) {
      LogFormat("Failed to load %s: %s",
                (const char *)NarrowPathName(Path(i.c_str())),
                e.what());
      images.shrink(images.size() - 1);
    }
  }

  const Layout layout(rc, waypoint);

  WindowStyle dock_style;
  dock_style.Hide();
  dock_style.ControlParent();

  WindowStyle button_style;
  button_style.Hide();
  button_style.TabStop();

  if (allow_navigation)
    goto_button.Create(parent, look.button, _("GoTo"), layout.goto_button,
                       button_style, *this, GOTO);

  if (!images.empty()) {
    magnify_button.Create(parent, layout.magnify_button, button_style,
                          new SymbolButtonRenderer(look.button, _T("+")),
                          *this, MAGNIFY);
    shrink_button.Create(parent, layout.shrink_button, button_style,
                         new SymbolButtonRenderer(look.button, _T("-")),
                         *this, SHRINK);
  }

  if (allow_navigation) {
    previous_button.Create(parent, layout.previous_button, button_style,
                           new SymbolButtonRenderer(look.button, _T("<")),
                           *this, PREVIOUS);
    next_button.Create(parent, layout.next_button, button_style,
                       new SymbolButtonRenderer(look.button, _T(">")),
                       *this, NEXT);
  }

  close_button.Create(parent, look.button, _("Close"), layout.close_button,
                      button_style, dialog, mrOK);

  info_dock.Create(parent, layout.main, dock_style);
  info_dock.SetWidget(&info_widget);

  details_panel.Create(parent, look, layout.main, dock_style);
  details_text.Create(details_panel, layout.details_text);
  details_text.SetFont(look.text_font);
  details_text.SetText(waypoint.details.c_str());

#ifdef HAVE_RUN_FILE
  const unsigned num_files = std::distance(waypoint.files_external.begin(),
                                           waypoint.files_external.end());
  if (num_files > 0) {
    file_list.Create(details_panel, layout.file_list,
                     WindowStyle(), layout.file_list_item_height);
    file_list.SetItemRenderer(&file_list_handler);
    file_list.SetCursorHandler(&file_list_handler);
    file_list.SetLength(num_files);
  }
#endif

  commands_dock.Create(parent, layout.main, dock_style);
  commands_dock.SetWidget(&commands_widget);

  if (!images.empty())
    image_window.Create(parent, layout.main, dock_style,
                        [this](Canvas &canvas, const PixelRect &rc){
                          OnImagePaint(canvas, rc);
                        });

  last_page = 2 + images.size();
}
Пример #18
0
bool
dlgTextEntryKeyboardShowModal(TCHAR *text, size_t width,
                              const TCHAR* caption,
                              AllowedCharacters accb)
{
  if (width == 0)
    width = MAX_TEXTENTRY;

  max_width = std::min(MAX_TEXTENTRY, width);

  const DialogLook &look = UIGlobals::GetDialogLook();
  WndForm form(look);
  form.Create(UIGlobals::GetMainWindow(), caption);
  form.SetKeyDownFunction(FormKeyDown);
  form.SetCharacterFunction(FormCharacter);

  ContainerWindow &client_area = form.GetClientAreaWindow();
  const PixelRect rc = client_area.GetClientRect();

  const PixelScalar client_height = rc.bottom - rc.top;

  const PixelScalar padding = Layout::Scale(2);
  const PixelScalar backspace_width = Layout::Scale(36);
  const PixelScalar backspace_left = rc.right - padding - backspace_width;
  const PixelScalar editor_height = Layout::Scale(22);
  const PixelScalar editor_bottom = padding + editor_height;
  const PixelScalar button_height = Layout::Scale(40);
  constexpr unsigned keyboard_rows = 5;
  const PixelScalar keyboard_top = editor_bottom + padding;
  const PixelScalar keyboard_height = keyboard_rows * button_height;
  const PixelScalar keyboard_bottom = keyboard_top + keyboard_height;

  const bool vertical = client_height >= keyboard_bottom + button_height;

  const PixelScalar button_top = vertical
    ? rc.bottom - button_height
    : keyboard_bottom - button_height;
  const PixelScalar button_bottom = vertical
    ? rc.bottom
    : keyboard_bottom;

  const PixelScalar ok_left = vertical ? 0 : padding;
  const PixelScalar ok_right = vertical
    ? rc.right / 3
    : ok_left + Layout::Scale(80);

  const PixelScalar cancel_left = vertical
    ? ok_right
    : Layout::Scale(175);
  const PixelScalar cancel_right = vertical
    ? rc.right * 2 / 3
    : cancel_left + Layout::Scale(60);

  const PixelScalar clear_left = vertical
    ? cancel_right
    : Layout::Scale(235);
  const PixelScalar clear_right = vertical
    ? rc.right
    : clear_left + Layout::Scale(50);

  WndProperty _editor(client_area, look, _T(""),
                      { 0, padding, backspace_left - padding, editor_bottom },
                      0, WindowStyle());
  _editor.SetReadOnly();
  editor = &_editor;

  ButtonWindowStyle button_style;
  button_style.TabStop();

  WndButton backspace_button(client_area, look, _T("<-"),
                             { backspace_left, padding, rc.right - padding,
                                 editor_bottom },
                             button_style, OnBackspace);

  WndButton ok_button(client_area, look, _("OK"),
                      { ok_left, button_top, ok_right, button_bottom },
                      button_style, form, mrOK);

  WndButton cancel_button(client_area, look, _("Cancel"),
                          { cancel_left, button_top,
                              cancel_right, button_bottom },
                          button_style, form, mrCancel);

  WndButton clear_button(client_area, look, _("Clear"),
                         { clear_left, button_top,
                             clear_right, button_bottom },
                         button_style, ClearText);

  KeyboardControl keyboard(client_area, look,
                           { padding, keyboard_top,
                              rc.right - padding,
                              keyboard_bottom },
                           OnCharacter);
  kb = &keyboard;

  AllowedCharactersCallback = accb;

  cursor = 0;
  ClearText();

  if (!StringIsEmpty(text)) {
    CopyString(edittext, text, width);
    cursor = _tcslen(text);
  }

  UpdateTextboxProp();
  bool result = form.ShowModal() == mrOK;

  if (result) {
    CopyString(text, edittext, width);
  }

  return result;
}
Пример #19
0
 void set(ContainerWindow &parent, const TCHAR *cls,
          int left, int top, unsigned width, unsigned height,
          const WindowStyle style=WindowStyle()) {
   set(&parent, cls, left, top, width, height, style);
 }
Пример #20
0
bool
TouchTextEntry(TCHAR *text, size_t width,
               const TCHAR *caption,
               AllowedCharacters accb,
               bool default_shift_state)
{
  if (width == 0)
    width = MAX_TEXTENTRY;

  max_width = std::min(MAX_TEXTENTRY, width);

  const DialogLook &look = UIGlobals::GetDialogLook();
  WndForm form(look);
  form.Create(UIGlobals::GetMainWindow(), caption);
  form.SetKeyDownFunction(FormKeyDown);
  form.SetCharacterFunction(FormCharacter);

  ContainerWindow &client_area = form.GetClientAreaWindow();
  const PixelRect rc = client_area.GetClientRect();

  const int client_height = rc.GetHeight();

  const int padding = Layout::Scale(2);
  const int backspace_width = Layout::Scale(36);
  const int backspace_left = rc.right - padding - backspace_width;
  const int editor_height = Layout::Scale(22);
  const int editor_bottom = padding + editor_height;
  const int button_height = Layout::Scale(40);
  constexpr unsigned keyboard_rows = 5;
  const int keyboard_top = editor_bottom + padding;
  const int keyboard_height = keyboard_rows * button_height;
  const int keyboard_bottom = keyboard_top + keyboard_height;

  const bool vertical = client_height >= keyboard_bottom + button_height;

  const int button_top = vertical
    ? rc.bottom - button_height
    : keyboard_bottom - button_height;
  const int button_bottom = vertical
    ? rc.bottom
    : keyboard_bottom;

  const int ok_left = vertical ? 0 : padding;
  const int ok_right = vertical
    ? rc.right / 3
    : ok_left + Layout::Scale(80);

  const int cancel_left = vertical
    ? ok_right
    : Layout::Scale(175);
  const int cancel_right = vertical
    ? rc.right * 2 / 3
    : cancel_left + Layout::Scale(60);

  const int clear_left = vertical
    ? cancel_right
    : Layout::Scale(235);
  const int clear_right = vertical
    ? rc.right
    : clear_left + Layout::Scale(50);

  WndProperty _editor(client_area, look, _T(""),
                      { 0, padding, backspace_left - padding, editor_bottom },
                      0, WindowStyle());
  _editor.SetReadOnly();
  editor = &_editor;

  WindowStyle button_style;
  button_style.TabStop();

  Button ok_button(client_area, look.button, _("OK"),
                   { ok_left, button_top, ok_right, button_bottom },
                   button_style, form, mrOK);

  Button cancel_button(client_area, look.button, _("Cancel"),
                       { cancel_left, button_top,
                           cancel_right, button_bottom },
                       button_style, form, mrCancel);

  auto clear_listener = MakeLambdaActionListener([](unsigned id){
      ClearText();
    });
  Button clear_button(client_area, look.button, _("Clear"),
                      { clear_left, button_top,
                          clear_right, button_bottom },
                      button_style, clear_listener, 0);

  KeyboardWidget keyboard(look.button, FormCharacter, !accb,
                          default_shift_state);

  const PixelRect keyboard_rc = {
    padding, keyboard_top,
    rc.right - padding, keyboard_bottom
  };

  keyboard.Initialise(client_area, keyboard_rc);
  keyboard.Prepare(client_area, keyboard_rc);
  keyboard.Show(keyboard_rc);

  kb = &keyboard;

  auto backspace_listener = MakeLambdaActionListener([](unsigned id){
      OnBackspace();
    });
  Button backspace_button(client_area, look.button, _T("<-"),
                          { backspace_left, padding, rc.right - padding,
                              editor_bottom },
                          button_style, backspace_listener, 0);

  AllowedCharactersCallback = accb;

  cursor = 0;
  ClearText();

  if (!StringIsEmpty(text)) {
    CopyTruncateString(edittext, width, text);
    cursor = _tcslen(text);
  }

  UpdateTextboxProp();
  bool result = form.ShowModal() == mrOK;

  keyboard.Hide();
  keyboard.Unprepare();

  if (result) {
    CopyTruncateString(text, width, edittext);
  }

  return result;
}