/** * Find the dropdown item under the cursor. * @param value [out] Selected item, if function returns \c true. * @return Cursor points to a dropdown item. */ bool GetDropDownItem(int &value) { if (GetWidgetFromPos(this, _cursor.pos.x - this->left, _cursor.pos.y - this->top) < 0) return false; NWidgetBase *nwi = this->GetWidget<NWidgetBase>(DDM_ITEMS); int y = _cursor.pos.y - this->top - nwi->pos_y - 2; int width = nwi->current_x - 4; int pos = this->vscroll->GetPosition(); const DropDownList *list = this->list; for (DropDownList::const_iterator it = list->begin(); it != list->end(); ++it) { /* Skip items that are scrolled up */ if (--pos >= 0) continue; const DropDownListItem *item = *it; int item_height = item->Height(width); if (y < item_height) { if (item->masked || !item->Selectable()) return false; value = item->result; return true; } y -= item_height; } return false; }
/** * Helper function to construct the dropdown. * @param widget the dropdown widget to create the dropdown for */ void ShowDateDropDown(int widget) { int selected; DropDownList *list = new DropDownList(); switch (widget) { default: NOT_REACHED(); case WID_SD_DAY: for (uint i = 0; i < 31; i++) { list->push_back(new DropDownListStringItem(STR_ORDINAL_NUMBER_1ST + i, i + 1, false)); } selected = this->date.day; break; case WID_SD_MONTH: for (uint i = 0; i < 12; i++) { list->push_back(new DropDownListStringItem(STR_MONTH_JAN + i, i, false)); } selected = this->date.month; break; case WID_SD_YEAR: for (Year i = this->min_year; i <= this->max_year; i++) { DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false); item->SetParam(0, i); list->push_back(item); } selected = this->date.year; break; } ShowDropDownList(this, list, selected, widget); }
void linkInputLabels() { GraphicLayer* layer = GraphicLayer::sharedLayer(); CCArray* children = layer->getChildren(); if(children != NULL) { for(int i = 0 ; i < children->count(); i++) { RawObject* child = (RawObject*)children->objectAtIndex(i); //Force actualization of content size and fontSize after everything is loaded because the nodeToWorldTransform is only right after if(isKindOfClass(child, InputLabel)) { InputLabel* input = (InputLabel*)child; child->getNode()->setContentSize(child->getNode()->getContentSize()); if(input->getOriginalInfos() != NULL) { ((ui::EditBox*)child->getNode())->setFontSize(input->getOriginalInfos()->getFontSize()); } } if((isKindOfClass(child, InputLabel)) && child->getEventInfos()->objectForKey("LinkTo") != NULL && isKindOfClass(child->getEventInfos()->objectForKey("LinkTo"), CCString)) { InputLabel* input = (InputLabel*)child; if(input->getLinkTo() == NULL) { CCString* linkTo = (CCString*)child->getEventInfos()->objectForKey("LinkTo"); CCArray* matchs = layer->allObjectsWithName(linkTo); for(long j = 0; j < matchs->count(); j++) { RawObject* match = (RawObject*)matchs->objectAtIndex(j); if(isKindOfClass(match, LabelTTF)) { input->setLinkTo((LabelTTF*)match); j = matchs->count(); } } } } else if((isKindOfClass(child, DropDownList)) && child->getEventInfos()->objectForKey("LinkTo") != NULL && isKindOfClass(child->getEventInfos()->objectForKey("LinkTo"), CCString)) { DropDownList* dropDownList = (DropDownList*)child; if(dropDownList->getLinkTo() == NULL) { CCString* linkTo = (CCString*)child->getEventInfos()->objectForKey("LinkTo"); CCArray* matchs = layer->allObjectsWithName(linkTo); for(long j = 0; j < matchs->count(); j++) { RawObject* match = (RawObject*)matchs->objectAtIndex(j); if(isKindOfClass(match, LabelTTF)) { dropDownList->setLinkTo((LabelTTF*)match); j = matchs->count(); } } } } } } }
/** Build a dropdown list of available airport classes */ static DropDownList *BuildAirportClassDropDown() { DropDownList *list = new DropDownList(); for (uint i = 0; i < AirportClass::GetCount(); i++) { list->push_back(new DropDownListStringItem(AirportClass::GetName((AirportClassID)i), i, false)); } return list; }
/** Build a dropdown list of available airport classes */ static DropDownList *BuildAirportClassDropDown() { DropDownList *list = new DropDownList(); for (uint i = 0; i < AirportClass::GetClassCount(); i++) { *list->Append() = new DropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i, false); } return list; }
/** * Update/redraw the group action dropdown * @param w the window the dropdown belongs to * @param gid the currently selected group in the window */ static void ShowGroupActionDropdown(Window *w, GroupID gid) { DropDownList *list = new DropDownList(); list->push_back(new DropDownListStringItem(STR_VEHICLE_LIST_REPLACE_VEHICLES, GALF_REPLACE, false)); list->push_back(new DropDownListStringItem(STR_VEHICLE_LIST_SEND_FOR_SERVICING, GALF_SERVICE, false)); list->push_back(new DropDownListStringItem(STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT, GALF_DEPOT, false)); if (Group::IsValidID(gid)) { list->push_back(new DropDownListStringItem(STR_GROUP_ADD_SHARED_VEHICLE, GALF_ADD_SHARED, false)); list->push_back(new DropDownListStringItem(STR_GROUP_REMOVE_ALL_VEHICLES, GALF_REMOVE_ALL, false)); } ShowDropDownList(w, list, 0, GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN); }
Pt ModalListPicker::DetermineListHeight(const Pt& _drop_down_size) { auto drop_down_size = _drop_down_size; // Determine the expected height auto border_thick = 2 * GG::Y(ListBox::BORDER_THICK); auto num_rows = std::min<int>(m_num_shown_rows, LB()->NumRows()); auto row_height = (*LB()->FirstRowShown())->Height(); auto expected_height = num_rows * row_height + border_thick; // Shrink the height if too near app edge. auto dist_to_app_edge = GUI::GetGUI()->AppHeight() - m_relative_to_wnd->Bottom(); if (expected_height > dist_to_app_edge && row_height > 0) { auto reduced_num_rows = std::max(GG::Y(1), (dist_to_app_edge - border_thick) / row_height); expected_height = reduced_num_rows * row_height + border_thick; } drop_down_size.y = expected_height; LB()->Resize(drop_down_size); if (!LB()->Selections().empty()) LB()->BringRowIntoView(*(LB()->Selections().begin())); GUI::GetGUI()->PreRenderWindow(LB()); return drop_down_size; }
/** * Create a dropdown menu. * @param parent Parent window. * @param list Dropdown item list. * @param selected Index of the selected item in the list. * @param button Widget of the parent window doing the dropdown. * @param instant_close Close the window when the mouse button is raised. * @param position Topleft position of the dropdown menu window. * @param size Size of the dropdown menu window. * @param wi_colour Colour of the parent widget. * @param scroll Dropdown menu has a scrollbar. * @param widget Widgets of the dropdown menu window. */ DropdownWindow(Window *parent, const DropDownList *list, int selected, int button, bool instant_close, const Point &position, const Dimension &size, Colours wi_colour, bool scroll) : Window(&_dropdown_desc) { assert(list->Length() > 0); this->position = position; this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_DM_SCROLL); uint items_width = size.width - (scroll ? NWidgetScrollbar::GetVerticalDimension().width : 0); NWidgetCore *nwi = this->GetWidget<NWidgetCore>(WID_DM_ITEMS); nwi->SetMinimalSize(items_width, size.height + 4); nwi->colour = wi_colour; nwi = this->GetWidget<NWidgetCore>(WID_DM_SCROLL); nwi->colour = wi_colour; this->GetWidget<NWidgetStacked>(WID_DM_SHOW_SCROLL)->SetDisplayedPlane(scroll ? 0 : SZSP_NONE); this->FinishInitNested(0); CLRBITS(this->flags, WF_WHITE_BORDER); /* Total length of list */ int list_height = 0; for (const DropDownListItem * const *it = list->Begin(); it != list->End(); ++it) { const DropDownListItem *item = *it; list_height += item->Height(items_width); } /* Capacity is the average number of items visible */ this->vscroll->SetCapacity(size.height * (uint16)list->Length() / list_height); this->vscroll->SetCount((uint16)list->Length()); this->parent_wnd_class = parent->window_class; this->parent_wnd_num = parent->window_number; this->parent_button = button; this->list = list; this->selected_index = selected; this->click_delay = 0; this->drag_mode = instant_close; this->instant_close = instant_close; this->left_button_state = _left_button_down; }
/** * Show a dropdown menu window near a widget of the parent window. * The result code of the items is their index in the #strings list. * @param w Parent window that wants the dropdown menu. * @param strings Menu list, end with #INVALID_STRING_ID * @param selected Index of initial selected item. * @param button Button widget number of the parent window #w that wants the dropdown menu. * @param disabled_mask Bitmask for diabled items (items with their bit set are not copied to the dropdown list). * @param hidden_mask Bitmask for hidden items (items with their bit set are displayed, but not selectable in the dropdown list). * @param width Width of the dropdown menu. If \c 0, use the width of parent widget #button. */ void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask, uint width) { DropDownList *list = new DropDownList(); for (uint i = 0; strings[i] != INVALID_STRING_ID; i++) { if (!HasBit(hidden_mask, i)) { list->push_back(new DropDownListStringItem(strings[i], i, HasBit(disabled_mask, i))); } } /* No entries in the list? */ if (list->size() == 0) { DeleteDropDownList(list); return; } ShowDropDownList(w, list, selected, button, width); }
void ModalListPicker::MouseWheel(const Pt& pt, int move, Flags<ModKey> mod_keys) { bool in_anchor_or_dropped_list = (LB()->InWindow(pt) || (m_relative_to_wnd && m_relative_to_wnd->InWindow(pt))); if (!in_anchor_or_dropped_list) return; auto corrected_move = (LB()->InWindow(pt)? move : -move); SignalChanged(Select(MouseWheelCommon(pt, corrected_move, mod_keys))); }
void DropDownList::hide(bool event, bool allow_veto) { // hide? bool keep_open = event && allow_veto && stayOpen(selected_item); if (keep_open) { close_on_mouse_out = true; } else { // hide root DropDownList* root = this; while (root->parent_menu) { root = root->parent_menu; } root->realHide(); } // send event if (event && selected_item != NO_SELECTION && itemEnabled(selected_item)) { select(selected_item); if (IsShown()) Refresh(false); } }
void ModalListPicker::CompleteConstruction() { m_lb_wnd->SelRowsChangedSignal.connect( boost::bind(&ModalListPicker::LBSelChangedSlot, this, _1)); m_lb_wnd->LeftClickedRowSignal.connect( boost::bind(&ModalListPicker::LBLeftClickSlot, this, _1, _2, _3)); GUI::GetGUI()->WindowResizedSignal.connect( boost::bind(&ModalListPicker::WindowResizedSlot, this, _1, _2)); AttachChild(m_lb_wnd); m_lb_wnd->InstallEventFilter(shared_from_this()); if (INSTRUMENT_ALL_SIGNALS) SelChangedSignal.connect(ModalListPickerSelChangedEcho(*this)); if (m_relative_to_wnd) m_lb_wnd->MoveTo(Pt(m_relative_to_wnd->Left(), m_relative_to_wnd->Bottom())); m_lb_wnd->Hide(); }
void ModalListPicker::CorrectListSize() { // reset size of displayed drop list based on number of shown rows set. // assumes that all rows have the same height. // adds some magic padding for now to prevent the scroll bars showing up. if (!m_relative_to_wnd) return; if (LB()->Visible()) return; LB()->MoveTo(Pt(m_relative_to_wnd->Left(), m_relative_to_wnd->Bottom())); Pt drop_down_size(m_relative_to_wnd->DroppedRowWidth(), m_relative_to_wnd->ClientHeight()); if (LB()->Empty()) { LB()->Resize(drop_down_size); } else { LB()->Show(); // The purpose of this code is to produce a drop down list that // will be exactly m_num_shown_rows high and make sure that the // selected row is prerendered in the same way when the drop down // list is open or closed. // The list needs to be resized twice. The first resize with an // estimated row height will add any list box chrome, like scroll // bars to the list and may change the height of the row. The // second resize uses the corrected row height to finalize the drop // down list size. // Note: Placing a tighter constraint on valid DropDownList rows // of always returning the same fixed height regardless of status // (width, prerender etc.) would mean this code could be reduced to // check height and resize list just once. drop_down_size = DetermineListHeight(drop_down_size); DetermineListHeight(drop_down_size); LB()->Hide(); } }
/** * Create a dropdown menu. * @param parent Parent window. * @param list Dropdown item list. * @param selected Index of the selected item in the list. * @param button Widget of the parent window doing the dropdown. * @param instant_close Close the window when the mouse button is raised. * @param position Topleft position of the dropdown menu window. * @param size Size of the dropdown menu window. * @param wi_colour Colour of the parent widget. * @param scroll Dropdown menu has a scrollbar. * @param widget Widgets of the dropdown menu window. */ DropdownWindow(Window *parent, DropDownList *list, int selected, int button, bool instant_close, const Point &position, const Dimension &size, Colours wi_colour, bool scroll) : Window() { this->position = position; this->CreateNestedTree(&_dropdown_desc); this->vscroll = this->GetScrollbar(DDM_SCROLL); uint items_width = size.width - (scroll ? WD_VSCROLLBAR_WIDTH : 0); NWidgetCore *nwi = this->GetWidget<NWidgetCore>(DDM_ITEMS); nwi->SetMinimalSize(items_width, size.height + 4); nwi->colour = wi_colour; nwi = this->GetWidget<NWidgetCore>(DDM_SCROLL); nwi->colour = wi_colour; this->GetWidget<NWidgetStacked>(DDM_SHOW_SCROLL)->SetDisplayedPlane(scroll ? 0 : SZSP_NONE); this->FinishInitNested(&_dropdown_desc, 0); this->flags4 &= ~WF_WHITE_BORDER_MASK; /* Total length of list */ int list_height = 0; for (DropDownList::const_iterator it = list->begin(); it != list->end(); ++it) { DropDownListItem *item = *it; list_height += item->Height(items_width); } /* Capacity is the average number of items visible */ this->vscroll->SetCapacity(size.height * (uint16)list->size() / list_height); this->vscroll->SetCount((uint16)list->size()); this->parent_wnd_class = parent->window_class; this->parent_wnd_num = parent->window_number; this->parent_button = button; this->list = list; this->selected_index = selected; this->click_delay = 0; this->drag_mode = true; this->instant_close = instant_close; }
virtual void OnClick(Point pt, int widget, int click_count) { switch (widget) { case SNGRFS_PRESET_LIST: { DropDownList *list = new DropDownList(); /* Add 'None' option for clearing list */ list->push_back(new DropDownListStringItem(STR_NONE, -1, false)); for (uint i = 0; i < _grf_preset_list.Length(); i++) { if (_grf_preset_list[i] != NULL) { list->push_back(new DropDownListPresetItem(i)); } } ShowDropDownList(this, list, this->preset, SNGRFS_PRESET_LIST); break; } case SNGRFS_PRESET_SAVE: this->query_widget = widget; ShowQueryString(STR_EMPTY, STR_NEWGRF_SETTINGS_PRESET_SAVE_QUERY, 32, 100, this, CS_ALPHANUMERAL, QSF_NONE); break; case SNGRFS_PRESET_DELETE: if (this->preset == -1) return; DeleteGRFPresetFromConfig(_grf_preset_list[this->preset]); GetGRFPresetList(&_grf_preset_list); this->preset = -1; this->InvalidateData(); break; case SNGRFS_ADD: // Add GRF DeleteWindowByClass(WC_SAVELOAD); new NewGRFAddWindow(&_newgrf_add_dlg_desc, this, &this->list); break; case SNGRFS_REMOVE: { // Remove GRF GRFConfig **pc, *c, *newsel; /* Choose the next GRF file to be the selected file */ newsel = this->sel->next; for (pc = &this->list; (c = *pc) != NULL; pc = &c->next) { /* If the new selection is empty (i.e. we're deleting the last item * in the list, pick the file just before the selected file */ if (newsel == NULL && c->next == this->sel) newsel = c; if (c == this->sel) { *pc = c->next; free(c); break; } } this->sel = newsel; this->preset = -1; this->InvalidateData(3); this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window break; } case SNGRFS_MOVE_UP: { // Move GRF up GRFConfig **pc, *c; if (this->sel == NULL) break; int pos = 0; for (pc = &this->list; (c = *pc) != NULL; pc = &c->next, pos++) { if (c->next == this->sel) { c->next = this->sel->next; this->sel->next = c; *pc = this->sel; break; } } this->vscroll.ScrollTowards(pos); this->preset = -1; this->InvalidateData(); break; } case SNGRFS_MOVE_DOWN: { // Move GRF down GRFConfig **pc, *c; if (this->sel == NULL) break; int pos = 1; // Start at 1 as we swap the selected newgrf with the next one for (pc = &this->list; (c = *pc) != NULL; pc = &c->next, pos++) { if (c == this->sel) { *pc = c->next; c->next = c->next->next; (*pc)->next = c; break; } } this->vscroll.ScrollTowards(pos); this->preset = -1; this->InvalidateData(); break; } case SNGRFS_FILE_LIST: { // Select a GRF GRFConfig *c; uint i = (pt.y - this->GetWidget<NWidgetBase>(SNGRFS_FILE_LIST)->pos_y) / this->resize.step_height + this->vscroll.GetPosition(); for (c = this->list; c != NULL && i > 0; c = c->next, i--) {} if (this->sel != c) this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window this->sel = c; this->InvalidateData(); if (click_count > 1) this->OnClick(pt, SNGRFS_SET_PARAMETERS, 1); break; } case SNGRFS_APPLY_CHANGES: // Apply changes made to GRF list if (this->execute) { ShowQuery( STR_NEWGRF_POPUP_CAUTION_CAPTION, STR_NEWGRF_CONFIRMATION_TEXT, this, NewGRFConfirmationCallback ); } else { CopyGRFConfigList(this->orig_list, this->list, true); ResetGRFConfig(false); ReloadNewGRFData(); } break; case SNGRFS_SET_PARAMETERS: { // Edit parameters if (this->sel == NULL) break; this->query_widget = widget; static char buff[512]; GRFBuildParamList(buff, this->sel, lastof(buff)); SetDParamStr(0, buff); ShowQueryString(STR_JUST_RAW_STRING, STR_NEWGRF_SETTINGS_PARAMETER_QUERY, 63, 250, this, CS_NUMERAL_SPACE, QSF_NONE); break; } case SNGRFS_TOGGLE_PALETTE: if (this->sel != NULL) { this->sel->windows_paletted ^= true; this->SetDirty(); } break; case SNGRFS_CONTENT_DOWNLOAD: if (!_network_available) { ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, 0, 0); } else { #if defined(ENABLE_NETWORK) /* Only show the things in the current list, or everything when nothing's selected */ ContentVector cv; for (const GRFConfig *c = this->list; c != NULL; c = c->next) { if (c->status != GCS_NOT_FOUND && !HasBit(c->flags, GCF_COMPATIBLE)) continue; ContentInfo *ci = new ContentInfo(); ci->type = CONTENT_TYPE_NEWGRF; ci->state = ContentInfo::DOES_NOT_EXIST; ttd_strlcpy(ci->name, c->name != NULL ? c->name : c->filename, lengthof(ci->name)); ci->unique_id = BSWAP32(c->grfid); memcpy(ci->md5sum, c->md5sum, sizeof(ci->md5sum)); if (HasBit(c->flags, GCF_COMPATIBLE)) GamelogGetOriginalGRFMD5Checksum(c->grfid, ci->md5sum); *cv.Append() = ci; } ShowNetworkContentListWindow(cv.Length() == 0 ? NULL : &cv, CONTENT_TYPE_NEWGRF); #endif } break; } }