/* * LookListSetContents: Set contents & highlight of list box in Look dialog. */ void LookListSetContents(HWND hwndListBox, list_type contents, int flags) { list_type l; object_node *obj; WindowBeginUpdate(hwndListBox); ListBox_ResetContent(hwndListBox); /* Fill in list box with stuff from passed-in list */ for (l = contents; l != NULL; l = l->next) { /* We need to make a copy of this object, because the original object might be freed by the game before this dialog ends */ obj = ObjectCopy((object_node *) (l->data)); ItemListAddItem(hwndListBox, obj, -1, !(flags & LD_AMOUNTS)); /* Add to end */ } WindowEndUpdate(hwndListBox); /* In single selection box, make 1st item default. In multiple selection, * only highlight 1st item if there is just 1 item AND item doesn't need an amount */ if ((flags & LD_MULTIPLESEL) && contents->next == NULL) { obj = (object_node *) contents->data; if (!(info->flags & LD_AMOUNTS) || !IsNumberObj(obj->id)) { ListBox_SetSel(hwndListBox, TRUE, 0); info->selected[0] = True; } } else ListBox_SetCurSel(hwndListBox, 0); }
/* * GetAmount: If appropriate, display amount dialog to get amount * of given object at (x, y) on hwnd. * hParent is parent of dialog. * Return True if item isn't a number item, or user entered valid amount. */ Bool GetAmount(HWND hParent, HWND hwnd, object_node *obj, int x, int y) { int value; if (!IsNumberObj(obj->id)) return True; if (!InputNumber(hParent,hwnd,x,y,&value,(int)obj->amount,1,(int)obj->amount)) { return False; } if (value == 0) return False; obj->temp_amount = value; return True; #if 0 RECT r; AmountDialogStruct dlg_info; if (!IsNumberObj(obj->id)) return True; GetWindowRect(hwnd, &r); dlg_info.x = r.left + x; dlg_info.y = r.top + y; dlg_info.amount = obj->amount; if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_AMOUNT), hParent, AmountDialogProc, (LPARAM) &dlg_info) == IDCANCEL) return False; /* Don't select item */ obj->temp_amount = dlg_info.amount; if (dlg_info.amount == 0) return False; return True; #endif }
/* * GetAmountListBox: If appropriate, display amount dialog to get amount * of object at given index in given list box. * Return True iff item should be selected (i.e. user entered valid #) */ Bool GetAmountListBox(HWND hList, int index) { object_node *obj; MEASUREITEMSTRUCT m; /* See if item requires an amount */ obj = (object_node *) ListBox_GetItemData(hList, index); if (obj == NULL || !IsNumberObj(obj->id)) return True; /* Place amount dialog just beneath selected item */ ItemListMeasureItem(hList, &m); return GetAmount(GetParent(hList), hList, obj, 0, (index - ListBox_GetTopIndex(hList) + 1) * (m.itemHeight - 1)); }
/* * DisplayLookList: Display a list of items in a popup dialog box. * Returns a list of the objects the user selected, or NULL if he hit * cancel. These object are actually copies of those in the given list, so the * caller should free the list. * hParent is the parent for the dialog box. * title is the title for the dialog box. * flags affects behavior of dialog box: * If LD_MULTIPLESEL is set, the user may select more than one object from * the list of items; otherwise he may select at most one. * If LD_AMOUNTS is set, ask user for amount of object if appropriate. amount field * will be set in object in the returned list. * If LD_SINGLEAUTO is set and l contains only one object, the dialog won't be * displayed and the object will be automatically selected. * Note: The returned list is created by the dialog procedure, and so should * be freed by the caller. */ list_type DisplayLookList(HWND hParent, char *title, list_type l, int flags) { LookDialogStruct dlg_info; Bool valid; /* Do nothing if list is empty, or if dialog is already up */ if (l == NULL || hwndLookDialog != NULL) return NULL; /* Even if there's just 1 object, need to copy it to be consistent with general case */ if ((flags & LD_SINGLEAUTO) && l->next == NULL) { // Ask for amount for single number items object_node *obj = (object_node *) (l->data); if (!((flags & LD_AMOUNTS) && IsNumberObj(obj->id))) return list_add_item(NULL, ObjectCopy((object_node *) (l->data))); } ZeroMemory(&dlg_info,sizeof(dlg_info)); dlg_info.title = title; dlg_info.contents = l; dlg_info.flags = flags; /* If multiple selections allowed, make list box multiple select */ if (flags & LD_MULTIPLESEL) valid = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ITEMLISTMULTIPLE), hParent, LookDialogProc, (LPARAM) &dlg_info); else if (flags & LD_SORT) valid = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ITEMLISTSORTED), hParent, LookDialogProc, (LPARAM) &dlg_info); else valid = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ITEMLISTSINGLE), hParent, LookDialogProc, (LPARAM) &dlg_info); if( info != NULL ) { SafeFree(info->selected); } /* In Windows, DialogBox returns an int, which can't fit a pointer. So * we must put the return value in a global variable. Death to Windows!! */ if (valid == IDOK) return LookDialogRetval; else return NULL; }
/* * InventoryDrawSingleItem: Draw given inventory item, at given row and col * in relative coordinates. */ void InventoryDrawSingleItem(InvItem *item, int row, int col) { HDC hdc; AREA area, obj_area; char temp[MAXAMOUNT + 1]; Bool draw_cursor; area.x = col * INVENTORY_BOX_WIDTH; area.y = row * INVENTORY_BOX_HEIGHT; area.cx = INVENTORY_BOX_WIDTH; area.cy = INVENTORY_BOX_HEIGHT; obj_area.x = area.x + INVENTORY_OBJECT_BORDER; obj_area.y = area.y + INVENTORY_OBJECT_BORDER; obj_area.cx = INVENTORY_OBJECT_WIDTH - 1; obj_area.cy = INVENTORY_OBJECT_HEIGHT - 1; hdc = GetDC(hwndInv); // See if we should draw cursor here draw_cursor = (GetFocus() == hwndInv && row == cursor_row - top_row && col == cursor_col); if (draw_cursor) OffscreenBitBlt(hdc, 0, 0, INVENTORY_BOX_WIDTH, INVENTORY_BOX_HEIGHT, cursor_bits, 0, 0, INVENTORY_BOX_WIDTH, OBB_FLIP); else OffscreenWindowBackground(&inventory_bkgnd, inventory_area.x + area.x, inventory_area.y + area.y, INVENTORY_BOX_WIDTH, INVENTORY_BOX_HEIGHT); if (item->is_using) OffscreenBitBlt(hdc, INVENTORY_OBJECT_BORDER, INVENTORY_OBJECT_BORDER, INVENTORY_OBJECT_WIDTH, INVENTORY_OBJECT_HEIGHT, inuse_bits, 0, 0, INVENTORY_OBJECT_WIDTH, OBB_FLIP | OBB_TRANSPARENT); DrawObject(hdc, item->obj, item->obj->animate->group, True, &obj_area, NULL, INVENTORY_OBJECT_BORDER, INVENTORY_OBJECT_BORDER, 0, False); OffscreenCopy(hdc, area.x, area.y, INVENTORY_BOX_WIDTH, INVENTORY_BOX_HEIGHT, 0, 0); // Draw numbers for number items if (IsNumberObj(item->obj->id) && cinfo->config->inventory_num) { sprintf(temp, "%d", item->obj->amount); SetBkMode(hdc, TRANSPARENT); SelectObject(hdc, GetFont(FONT_STATNUM)); SetTextColor(hdc, GetColor(COLOR_INVNUMBGD)); TextOut(hdc, obj_area.x + 1, obj_area.y + 1, temp, strlen(temp)); SetTextColor(hdc, GetColor(COLOR_INVNUMFGD)); TextOut(hdc, obj_area.x, obj_area.y, temp, strlen(temp)); } // Draw border around area to clear previous cursor (if any) if (!draw_cursor) { DrawWindowBackgroundBorder(&inventory_bkgnd, hdc, &obj_area, INVENTORY_OBJECT_BORDER, inventory_area.x + obj_area.x, inventory_area.y + obj_area.y, -1, NULL); } ReleaseDC(hwndInv, hdc); }
/* * LookCommand: Handle WM_COMMAND messages. */ void LookCommand(HWND hDlg, int ctrl_id, HWND hwndCtl, UINT codeNotify) { int index, num_entries, i, amount, currentAmount; list_type selection; object_node *obj; char buf[MAXNAME + 1], temp[16]; switch(ctrl_id) { case IDC_ITEMFIND: if (codeNotify == EN_UPDATE) { /* Go to object in list that user has named */ Edit_GetText(info->hwndFind, buf, MAXNAME); index = ListBox_FindString(info->hwndListBox, -1, buf); if (index != LB_ERR) if (info->flags & LD_MULTIPLESEL) ListBox_SetCaretIndex(info->hwndListBox, index); else ListBox_SetCurSel(info->hwndListBox, index); } break; case IDC_ALL: /* In multiple selection box only, select all objects. If we require that * user give amounts, don't select amount objects */ num_entries = ListBox_GetCount(info->hwndListBox); ListBox_SetSel(info->hwndListBox, TRUE, -1); WindowBeginUpdate(info->hwndQuanList); // Select all for number items for (i=0; i < num_entries; i++) { info->selected[i] = True; obj = (object_node *) ListBox_GetItemData(info->hwndListBox, i); if (IsNumberObj(obj->id)) amount = obj->amount; else amount = 1; obj->temp_amount = amount; ListBox_DeleteString(info->hwndQuanList,i); sprintf(temp, "%d", amount); ListBox_InsertString(info->hwndQuanList,i,temp); ListBox_SetItemData(info->hwndQuanList,i,amount); } WindowEndUpdate(info->hwndQuanList); break; case IDC_ITEMLIST: switch (codeNotify) { case LBN_DBLCLK: /* Look at item */ index = ListBox_GetCaretIndex(info->hwndListBox); if (index != LB_ERR) { obj = (object_node *) ListBox_GetItemData(info->hwndListBox, index); RequestLook(obj->id); SetDescParams(hDlg, DESC_NONE); ListBox_SetSel(info->hwndListBox, FALSE, index); info->selected[index] = False; } break; case LBN_SELCHANGE: #if 0 LookSelChange(hwndCtl); #else index = ListBox_GetCurSel(info->hwndListBox); obj = (object_node *) ListBox_GetItemData(info->hwndListBox, index); WindowBeginUpdate(info->hwndQuanList); ListBox_DeleteString(info->hwndQuanList,index); if (ListBox_GetSel(info->hwndListBox,index)) { if (IsNumberObj(obj->id)) amount = obj->amount; else amount = 1; sprintf(temp, "%d", amount); } else { amount = 0; strcpy(temp," "); } ListBox_InsertString(info->hwndQuanList,index,temp); ListBox_SetItemData(info->hwndQuanList,index,amount); ListBox_SetSel(info->hwndListBox,amount > 0,index); info->selected[index] = (amount > 0); obj->temp_amount = amount; ListBox_SetSel(info->hwndQuanList,FALSE,index); WindowEndUpdate(info->hwndQuanList); #endif break; } break; case IDC_QUANLIST: if (codeNotify == LBN_SELCHANGE) { char temp[16]; index = (int)ListBox_GetCurSel(info->hwndQuanList); obj = (object_node *) ListBox_GetItemData(info->hwndListBox, index); currentAmount = (int)ListBox_GetItemData(info->hwndQuanList, index); amount = currentAmount; if (ListBox_GetItemData(info->hwndQuanList, index) > 0) { if (IsNumberObj(obj->id)) { MEASUREITEMSTRUCT m; int startAmount = currentAmount; if (currentAmount == 0) startAmount = obj->amount; /* Place amount dialog just beneath selected item */ ItemListMeasureItem(info->hwndQuanList, &m); // Force highlight on (we are editing it) ListBox_SetSel(info->hwndListBox,TRUE,index); if(InputNumber(hDlg,info->hwndQuanList, 0,(index - ListBox_GetTopIndex(info->hwndQuanList) + 1) * (m.itemHeight - 1), &amount,startAmount,1,obj->amount)) { ListBox_DeleteString(info->hwndQuanList,index); if (amount > 0) { sprintf(temp, "%d", amount); ListBox_InsertString(info->hwndQuanList, index, temp); } else { ListBox_InsertString(info->hwndQuanList,index," "); } ListBox_SetItemData(info->hwndQuanList, index, amount); } else amount = currentAmount; // reset highlight based on quantity - off if zero, on otherwise ListBox_SetSel(info->hwndListBox, (ListBox_GetItemData(info->hwndQuanList,index) > 0), index); } else { ListBox_DeleteString(info->hwndQuanList,index); if (currentAmount == 0) { amount = 1; strcpy(temp,"1"); } else { amount = 0; strcpy(temp," "); } ListBox_InsertString(info->hwndQuanList,index,temp); ListBox_SetItemData(info->hwndQuanList,index,amount); } } ListBox_SetSel(info->hwndListBox,amount > 0,index); info->selected[index] = (amount > 0); obj->temp_amount = amount; ListBox_SetCurSel(info->hwndQuanList,-1); } break; case IDOK: /* Get user's selection(s) */ num_entries = ListBox_GetCount(info->hwndListBox); selection = NULL; for (i = 0; i < num_entries; i++) { /* If item is selected, add to selection list, else free */ obj = (object_node *) ListBox_GetItemData(info->hwndListBox, i); if (ListBox_GetSel(info->hwndListBox, i) > 0) selection = list_add_item(selection, obj); else ObjectDestroyAndFree(obj); } LookDialogRetval = selection; EndDialog(hDlg, IDOK); break; case IDCANCEL: LookListFreeContents(info->hwndListBox); LookDialogRetval = NULL; EndDialog(hDlg, IDCANCEL); break; } }