static void clear_all_buttons(GPtrArray *buttons) { gint i; for (i = 0; i < (gint)buttons->len; i++) { struct index_button *idxbutton; idxbutton = g_ptr_array_index(buttons, i); if (idxbutton && idxbutton->cand_index_in_page != -1) { clear_button(idxbutton, i); } } }
static GtkEventBox* assign_cellbutton(UIMCandWinHorizontalGtk *horizontal_cwin, gint cand_index, gint display_limit) { struct index_button *idxbutton; int len; GPtrArray *buttons; buttons = horizontal_cwin->buttons; len = buttons->len; if (len <= cand_index) { GtkWidget *button; GtkWidget *label; button = gtk_event_box_new(); gtk_event_box_set_above_child(GTK_EVENT_BOX(button), TRUE); label = gtk_label_new(""); gtk_container_add(GTK_CONTAINER(button), label); scale_label(GTK_EVENT_BOX(button), PANGO_SCALE_LARGE); g_signal_connect(button, "button-press-event", G_CALLBACK(button_clicked), horizontal_cwin); #if GTK_CHECK_VERSION(2, 90, 0) g_signal_connect_after(label, "draw", G_CALLBACK(label_draw), horizontal_cwin); #else g_signal_connect_after(label, "expose-event", G_CALLBACK(label_exposed), horizontal_cwin); #endif #if GTK_CHECK_VERSION(3, 4, 0) gtk_widget_set_hexpand(button, TRUE); gtk_widget_set_vexpand(button, TRUE); gtk_grid_attach(GTK_GRID(UIM_CAND_WIN_GTK(horizontal_cwin)->view), button, cand_index, 0, 1, 1); #else gtk_table_attach_defaults(GTK_TABLE(UIM_CAND_WIN_GTK(horizontal_cwin)->view), button, cand_index, cand_index + 1, 0, 1); #endif idxbutton = g_malloc(sizeof(struct index_button)); if (idxbutton) { idxbutton->button = GTK_EVENT_BOX(button); clear_button(idxbutton, cand_index); idxbutton->cand_index_in_page = cand_index; } g_ptr_array_add(horizontal_cwin->buttons, idxbutton); } else { idxbutton = g_ptr_array_index(buttons, cand_index); idxbutton->cand_index_in_page = cand_index; } return idxbutton->button; }
void manage_meter_graph(void) { sc[SC_UPDATE_METER_GRAPH]=sd[SC_UPDATE_METER_GRAPH]; if(cg.meter_graph_on == 1) { if(mg_flag==0) { mg_clear_flag=TRUE; init_meter_graph(); make_meter_graph(FALSE); } } else { if(mg_flag==1) { mg_flag=0; lir_fillbox(mg.xleft,mg.ytop,mg.xright-mg.xleft+1,mg.ybottom-mg.ytop+1,0); clear_button(mgbutt, MAX_MGBUTT); } } }
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; }
static void uim_cand_win_horizontal_gtk_init (UIMCandWinHorizontalGtk *horizontal_cwin) { gint col; GtkWidget *viewport; UIMCandWinGtk *cwin; cwin = UIM_CAND_WIN_GTK(horizontal_cwin); horizontal_cwin->buttons = g_ptr_array_new(); horizontal_cwin->selected = NULL; #if GTK_CHECK_VERSION(3, 4, 0) cwin->view = gtk_grid_new(); gtk_grid_set_column_spacing(GTK_GRID(cwin->view), 10); #else cwin->view = gtk_table_new(1, DEFAULT_NR_CELLS, FALSE); gtk_table_set_col_spacings(GTK_TABLE(cwin->view), 10); #endif viewport = gtk_viewport_new(NULL, NULL); gtk_container_add(GTK_CONTAINER(viewport), cwin->view); gtk_container_add(GTK_CONTAINER(cwin->scrolled_window), viewport); gtk_container_set_resize_mode(GTK_CONTAINER(viewport), GTK_RESIZE_PARENT); for (col = 0; col < DEFAULT_NR_CELLS; col++) { GtkWidget *button; GtkWidget *label; struct index_button *idxbutton; button = gtk_event_box_new(); gtk_event_box_set_above_child(GTK_EVENT_BOX(button), TRUE); label = gtk_label_new(""); gtk_container_add(GTK_CONTAINER(button), label); scale_label(GTK_EVENT_BOX(button), PANGO_SCALE_LARGE); g_signal_connect(button, "button-press-event", G_CALLBACK(button_clicked), horizontal_cwin); #if GTK_CHECK_VERSION(2, 90, 0) g_signal_connect_after(label, "draw", G_CALLBACK(label_draw), horizontal_cwin); #else g_signal_connect_after(label, "expose-event", G_CALLBACK(label_exposed), horizontal_cwin); #endif #if GTK_CHECK_VERSION(3, 4, 0) gtk_widget_set_hexpand(button, TRUE); gtk_widget_set_vexpand(button, TRUE); gtk_grid_attach(GTK_GRID(cwin->view), button, col, 0, 1, 1); #else gtk_table_attach_defaults(GTK_TABLE(cwin->view), button, col, col + 1, 0, 1); #endif idxbutton = g_malloc(sizeof(struct index_button)); if (idxbutton) { idxbutton->button = GTK_EVENT_BOX(button); clear_button(idxbutton, col); } g_ptr_array_add(horizontal_cwin->buttons, idxbutton); } gtk_widget_show_all(cwin->view); gtk_widget_show(viewport); gtk_widget_set_size_request(cwin->num_label, DEFAULT_MIN_WINDOW_WIDTH, -1); gtk_window_set_default_size(GTK_WINDOW(cwin), DEFAULT_MIN_WINDOW_WIDTH, -1); gtk_window_set_resizable(GTK_WINDOW(cwin), FALSE); }
void show_hotkeys_dialog (display & disp, config *save_config) { log_scope ("show_hotkeys_dialog"); const events::event_context dialog_events_context; const int centerx = disp.w()/2; const int centery = disp.h()/2; const int width = 700; const int height = disp.video().gety() < 600 ? 380 : 500; const int xpos = centerx - width/2; const int ypos = centery - height/2; gui::button close_button (disp.video(), _("Close")); std::vector<gui::button*> buttons; buttons.push_back(&close_button); gui::dialog_frame f(disp.video(),_("Hotkey Settings"),gui::dialog_frame::default_style,true,&buttons); f.layout(xpos,ypos,width,height); f.draw(); SDL_Rect clip_rect = create_rect(0, 0, disp.w (), disp.h ()); SDL_Rect text_size = font::draw_text(NULL, clip_rect, font::SIZE_LARGE, font::NORMAL_COLOR,_("Press desired hotkey (Esc cancels)"), 0, 0); std::vector<std::string> menu_items; std::vector<hotkey::hotkey_item>& hotkeys = hotkey::get_hotkeys(); for(std::vector<hotkey::hotkey_item>::iterator i = hotkeys.begin(); i != hotkeys.end(); ++i) { if(i->hidden() || !i->is_in_active_scope()) continue; std::stringstream str,name; name << i->get_description(); str << name.str(); str << COLUMN_SEPARATOR; // This trick allows to display chars identical to markup characters str << font::NULL_MARKUP << i->get_name(); menu_items.push_back(str.str()); } std::ostringstream heading; heading << HEADING_PREFIX << _("Action") << COLUMN_SEPARATOR << _("Binding"); menu_items.push_back(heading.str()); gui::menu::basic_sorter sorter; sorter.set_alpha_sort(0).set_alpha_sort(1); gui::menu menu_(disp.video(), menu_items, false, height - font::relative_size(10), -1, &sorter, &gui::menu::bluebg_style); menu_.sort_by(0); menu_.reset_selection(); menu_.set_width(font::relative_size(500)); menu_.set_location(xpos + font::relative_size(10), ypos + font::relative_size(10)); gui::button change_button (disp.video(), _("Change Hotkey")); change_button.set_location(xpos + width - change_button.width () - font::relative_size(30),ypos + font::relative_size(30)); gui::button clear_button (disp.video(), _("Clear Hotkey")); clear_button.set_location(xpos + width - clear_button.width () - font::relative_size(30),ypos + font::relative_size(80)); // gui::button save_button (disp.video(), _("Save Hotkeys")); // save_button.set_location(xpos + width - save_button.width () - font::relative_size(30),ypos + font::relative_size(130)); escape_handler esc_hand; for(;;) { if (close_button.pressed() || esc_hand.escape_pressed()) { if (save_config == NULL) { save_hotkeys(); } else { hotkey::save_hotkeys(*save_config); } break; } if (change_button.pressed () || menu_.double_clicked()) { // Lets change this hotkey...... SDL_Rect dlgr = create_rect(centerx - text_size.w / 2 - 30 , centery - text_size.h / 2 - 16 , text_size.w + 60 , text_size.h + 32); surface_restorer restorer(&disp.video(),dlgr); gui::dialog_frame mini_frame(disp.video()); mini_frame.layout(centerx-text_size.w/2 - 20, centery-text_size.h/2 - 6, text_size.w+40, text_size.h+12); mini_frame.draw_background(); mini_frame.draw_border(); font::draw_text (&disp.video(), clip_rect, font::SIZE_LARGE,font::NORMAL_COLOR, _("Press desired hotkey (Esc cancels)"),centerx-text_size.w/2, centery-text_size.h/2); disp.update_display(); SDL_Event event; event.type = 0; int character = 0, keycode = 0, mod = 0; // Just to avoid warning int joystick = 0, button = 0, hat = 0, value = 0; const int any_mod = KMOD_CTRL | KMOD_ALT | KMOD_LMETA; while (event.type!=SDL_KEYDOWN && event.type!=SDL_JOYBUTTONDOWN && event.type!= SDL_JOYHATMOTION) SDL_PollEvent(&event); do { if (event.type==SDL_KEYDOWN) { keycode=event.key.keysym.sym; character=event.key.keysym.unicode; mod=event.key.keysym.mod; }; if (event.type==SDL_JOYBUTTONDOWN) { joystick = event.jbutton.which; button = event.jbutton.button; } if (event.type==SDL_JOYHATMOTION) { joystick = event.jhat.which; hat = event.jhat.hat; value = event.jhat.value; } SDL_PollEvent(&event); disp.flip(); disp.delay(10); } while (event.type!=SDL_KEYUP && event.type!=SDL_JOYBUTTONUP && event.type!=SDL_JOYHATMOTION); restorer.restore(); disp.update_display(); if (keycode == SDLK_ESCAPE && (mod & any_mod) == 0) { //cancel -- no action } else { const hotkey::hotkey_item& oldhk = hotkey::get_hotkey(character, keycode, (mod & KMOD_SHIFT) != 0, (mod & KMOD_CTRL) != 0, (mod & KMOD_ALT) != 0, (mod & KMOD_LMETA) != 0); hotkey::hotkey_item& newhk = hotkey::get_visible_hotkey(menu_.selection()); if(oldhk.get_id() != newhk.get_id() && !oldhk.null()) { std::stringstream msg; msg << " " << oldhk.get_description() << " : " << oldhk.get_name(); gui2::show_transient_message(disp.video(),_("This hotkey is already in use."),msg.str()); } else { if (event.type == SDL_JOYHATMOTION) { const hotkey::hotkey_item& oldhkhat = hotkey::get_hotkey(joystick, hat, value); if(oldhkhat.get_id() != newhk.get_id() && !oldhkhat.null()) { std::stringstream msg; msg << " " << oldhkhat.get_description() << " : " << oldhkhat.get_name(); gui2::show_transient_message(disp.video(),_("This hotkey is already in use."),msg.str()); } else { newhk.set_hat(joystick, hat, value); menu_.change_item(menu_.selection(), 1, font::NULL_MARKUP + newhk.get_name()); } } else if (event.type == SDL_JOYBUTTONUP) { const hotkey::hotkey_item& oldhkbtn = hotkey::get_hotkey(button, joystick); if(oldhkbtn.get_id() != newhk.get_id() && !oldhkbtn.null()) { std::stringstream msg; msg << " " << oldhkbtn.get_description() << " : " << oldhkbtn.get_name(); gui2::show_transient_message(disp.video(),_("This hotkey is already in use."),msg.str()); } else { newhk.set_button(button, joystick); menu_.change_item(menu_.selection(), 1, font::NULL_MARKUP + newhk.get_name()); } } else { newhk.set_key(character, keycode, (mod & KMOD_SHIFT) != 0, (mod & KMOD_CTRL) != 0, (mod & KMOD_ALT) != 0, (mod & KMOD_LMETA) != 0); menu_.change_item(menu_.selection(), 1, font::NULL_MARKUP + newhk.get_name()); if ((newhk.get_id() == hotkey::HOTKEY_SCREENSHOT || newhk.get_id() == hotkey::HOTKEY_MAP_SCREENSHOT) && (mod & any_mod) == 0) { gui2::show_transient_message(disp.video(), _("Warning"), _("Screenshot hotkeys should be combined with the Control, Alt or Meta modifiers to avoid problems.")); } } } } } // if (save_button.pressed()) { // if (save_config == NULL) { // save_hotkeys(); // } else { // hotkey::save_hotkeys(*save_config); // } // } if (clear_button.pressed()) { // clear hotkey hotkey::hotkey_item& newhk = hotkey::get_visible_hotkey(menu_.selection()); newhk.clear_hotkey(); menu_.change_item(menu_.selection(), 1, font::NULL_MARKUP + newhk.get_name()); } menu_.process(); events::pump(); events::raise_process_event(); events::raise_draw_event(); disp.update_display(); disp.delay(10); } }
void make_meter_graph(int clear_old) { int i, ypix, sunit_flag; double t1, t2; if(clear_old) { pause_thread(THREAD_SCREEN); hide_mouse(mg_old_x1,mg_old_x2,mg_old_y1,mg_old_y2); lir_fillbox(mg_old_x1,mg_old_y1,mg_old_x2-mg_old_x1+1, mg_old_y2-mg_old_y1+1,0); } current_graph_minh=MG_MIN_HEIGHT; current_graph_minw=MG_MIN_WIDTH; check_graph_placement((void*)(&mg)); clear_button(mgbutt, MAX_MGBUTT); scro[meter_graph_scro].no=METER_GRAPH; scro[meter_graph_scro].x1=mg.xleft; scro[meter_graph_scro].x2=mg.xright; scro[meter_graph_scro].y1=mg.ytop; scro[meter_graph_scro].y2=mg.ybottom; // Each border line is treated as a button. // That is for the mouse to get hold of them so the window can be moved. mgbutt[MG_LEFT].x1=mg.xleft; mgbutt[MG_LEFT].x2=mg.xleft+2; mgbutt[MG_LEFT].y1=mg.ytop; mgbutt[MG_LEFT].y2=mg.ybottom; mgbutt[MG_RIGHT].x1=mg.xright-2; mgbutt[MG_RIGHT].x2=mg.xright; mgbutt[MG_RIGHT].y1=mg.ytop; mgbutt[MG_RIGHT].y2=mg.ybottom; mgbutt[MG_TOP].x1=mg.xleft; mgbutt[MG_TOP].x2=mg.xright; mgbutt[MG_TOP].y1=mg.ytop; mgbutt[MG_TOP].y2=mg.ytop+2; mgbutt[MG_BOTTOM].x1=mg.xleft; mgbutt[MG_BOTTOM].x2=mg.xright; mgbutt[MG_BOTTOM].y1=mg.ybottom-2; mgbutt[MG_BOTTOM].y2=mg.ybottom; if(mg.xright-mg.xleft < 12.5*text_width) { mg_bar=TRUE; for(i=4; i<MAX_MGBUTT; i++) { mgbutt[i].x1=screen_width+1; mgbutt[i].x2=screen_width+1; } } else { mg_bar=FALSE; make_button(mg.xright-3*text_width,mg.ybottom-text_height/2-2, mgbutt,MG_INCREASE_AVGN,27); make_button(mg.xright-5*text_width,mg.ybottom-text_height/2-2, mgbutt,MG_DECREASE_AVGN,26); make_button(mg.xleft+text_width,mg.ytop+text_height/2+2, mgbutt,MG_INCREASE_GAIN,24); make_button(mg.xleft+text_width,mg.ybottom-text_height/2-2, mgbutt,MG_DECREASE_GAIN,25); make_button(mg.xright-text_width,mg.ybottom-text_height/2-2, mgbutt,MG_INCREASE_YREF,25); make_button(mg.xright-text_width,mg.ytop+text_height/2+2, mgbutt,MG_DECREASE_YREF,24); make_button(mg.xright-3*text_width,mg.ytop+text_height/2+2, mgbutt,MG_CHANGE_TRACKS,' '); if(mg.scale_type != MG_SCALE_DB) { mgbutt[MG_CHANGE_CAL].x1=mg.xleft+2*text_width; mgbutt[MG_CHANGE_CAL].x2=mg.xleft+8.5*text_width; mgbutt[MG_CHANGE_CAL].y1=mg.ytop+1; mgbutt[MG_CHANGE_CAL].y2=mg.ytop+text_height+2; } else { mgbutt[MG_CHANGE_CAL].x1=screen_width+1; mgbutt[MG_CHANGE_CAL].x2=screen_width+1; } mgbutt[MG_CHANGE_TYPE].x1=mg.xleft+2*text_width; mgbutt[MG_CHANGE_TYPE].y1=mg.ybottom-3-text_height; mgbutt[MG_CHANGE_TYPE].y2=mg.ybottom-2; switch (mg.scale_type) { case MG_SCALE_DB: mgbutt[MG_CHANGE_TYPE].x2=mg.xleft+4.5*text_width; break; case MG_SCALE_DBM: mgbutt[MG_CHANGE_TYPE].x2=mg.xleft+5.5*text_width; break; case MG_SCALE_SUNITS: mgbutt[MG_CHANGE_TYPE].x2=mg.xleft+3.5*text_width; break; } } mg_first_xpixel=mg.xleft+7*text_width; mg_last_xpixel=mg.xright-1; // ************************************************ // Make an Y-scale in dB, dBm or S-units. // ************************************************ // The separation between scale lines, has to be at least // MG_MIN_SCALESEP*text_height. In dB this corresponds to mg_dbstep. mg_dbstep=10*MG_MIN_SCALESEP*text_height/mg.ygain; if(mg.scale_type == MG_SCALE_SUNITS) { i=1+mg_dbstep/6; mg_dbstep=6*i; } else { adjust_scale(&mg_dbstep); } // Make mg_dbscale_start the dB value for the first pixel in the graph (mg_rms_meter[]=0) // Then make it a multiple of mg_dbstep and make sure we have enough // space to write text. mg_scale_offset=0; if(mg.scale_type == MG_SCALE_DBM)mg_scale_offset=106+fg.gain+mg.cal_dbm; if(mg.scale_type == MG_SCALE_SUNITS)mg_scale_offset=6+fg.gain+mg.cal_s_units; mg_dbscale_start=-10*mg.yzero/mg.ygain-mg_scale_offset; mg_dbscale_start/=mg_dbstep; mg_dbscale_start=(int)mg_dbscale_start; mg_dbscale_start*=mg_dbstep; for(i=0; i<screen_height; i++)mg_behind_meter[i]=0; mg_ymin=mg.ybottom-5-text_height; mg_ymax=mg.ytop+3+text_height; ypix=mg.yzero+0.1*mg.ygain*(mg_dbscale_start+mg_scale_offset); mg_midscale=mg_dbscale_start; t1=mg_dbscale_start; t2=mg_dbstep; sunit_flag=0; mg_bar_x1=mg.xleft+2*text_width; mg_bar_x2=mg_bar_x1+3*text_width; mg_y0=mg.ybottom-1; while(mg_ymin-ypix > mg_ymax) { if(ypix >=0) { if(mg.scale_type == MG_SCALE_SUNITS) { if(t1 > 54.111 && sunit_flag == 0) { sunit_flag=1; i=1+mg_dbstep/5; t2=5*i; t1=54+t2; ypix=mg.yzero+0.1*mg.ygain*(t1+mg_scale_offset); } } if(mg_ymin-ypix > mg_ymax) { mg_behind_meter[mg_ymin-ypix]=57; } } t1+=t2; ypix=mg.yzero+0.1*mg.ygain*(t1+mg_scale_offset); } mg_midscale=0.1*(mg_scale_offset+(mg_midscale+t1-t2)*0.5); make_modepar_file(GRAPHTYPE_MG); for(i=0; i<ui.rx_rf_channels*mg_size; i++) { mg_peak_ypix[i]=mg_ymin; mg_rms_ypix[i]=mg_ymin; } sc[SC_MG_REDRAW]++; if(clear_old) resume_thread(THREAD_SCREEN); }
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; }