// // Button - OnDraw event. // int EZ_button_OnDraw(ez_control_t *self, void *ext_event_info) { ez_button_t *button = (ez_button_t *)self; int x, y; EZ_control_GetDrawingPosition(self, &x, &y); // Run the super class's implementation first. EZ_control_OnDraw(self, NULL); if (self->int_flags & control_focused) { if (button->ext_flags & button_use_images) { } else { Draw_AlphaRectangleRGB(x, y, self->width, self->height, 1, false, RGBAVECT_TO_COLOR(button->color_focused)); } } // Draw control specifics. CONTROL_EVENT_HANDLER_CALL(NULL, self, ez_control_t, OnDraw, NULL); return 0; }
// We need a seperate function, since our messages are in colour... and transparent void VXSCR_DrawTrackerString (void) { byte rgba[4]; char *start, image[256], fullpath[MAX_PATH]; int l; int j; int x, y; int i, printable_chars; float alpha = 1; float scale = bound(0.1, amf_tracker_scale.value, 10); float im_scale = bound(0.1, amf_tracker_images_scale.value, 10); StringToRGB(amf_tracker_frame_color.string); if (!active_track) return; memset(rgba, 255, sizeof(byte) * 4); y = vid.height * 0.2 / scale + amf_tracker_y.value; // Draw the max allowed trackers allowed at the same time // the latest ones are always shown. for (i = 0; i < max_active_tracks; i++) { // Time expired for this tracker, don't draw it. if (trackermsg[i].die < r_refdef2.time) continue; // Get the start of the tracker message. start = trackermsg[i].msg; // Fade the text as it gets older. alpha = min(1, (trackermsg[i].die - r_refdef2.time) / 2); // Loop through the tracker message and parse it. while (start[0]) { l = printable_chars = 0; // Find the number of printable characters for the next line. while (start[l] && start[l] != '\n') { // Look for any escape codes for images and color codes. // Image escape. if (start[l] == '\\') { // We found opening slash, get image name now. int from, to; from = to = ++l; for( ; start[l]; l++) { if (start[l] == '\n') break; // Something bad, we didn't find a closing slash. if (start[l] == '\\') break; // Found a closing slash. to = l + 1; } if (to > from) printable_chars += 2; // We got potential image name, treat image as two printable characters. if (start[l] == '\\') l++; // Advance. continue; } // Get rid of color codes. if (start[l] == '&') { if (start[l + 1] == 'r') { l += 2; continue; } else if (start[l + 1] == 'c' && start[l + 2] && start[l + 3] && start[l + 4]) { l += 5; continue; } } printable_chars++; // Increment count of printable chars. l++; // Increment count of any chars in string untill end or new line. } // Place the tracker. x = scale * (amf_tracker_align_right.value ? (vid.width / scale - printable_chars * 8) - 8 : 8); x += amf_tracker_x.value; // Draw the string. for (j = 0; j < l;) { if (start[j] == '\\') { // We found opening slash, get image name now int from, to; from = to = ++j; for( ; start[j]; j++) { if (start[j] == '\n') break; // Something bad, we does't found closing slash. if (start[j] == '\\') break; // Found closing slash. to = j + 1; } if (to > from) { // We got potential image name, treat image as two printable characters. mpic_t *pic; int size = to - from; size = min(size, (int)sizeof(image) - 1); memcpy(image, (start + from), size); // Copy image name to temp buffer. image[size] = 0; if (image[0]) { snprintf(fullpath, sizeof(fullpath), "textures/tracker/%s", image); if ((pic = Draw_CachePicSafe(fullpath, false, true))) { Draw_FitPic( (float)x - 0.5 * 8 * 2 * (im_scale - 1) * scale, (float)y - 0.5 * 8 * (im_scale - 1) * scale, im_scale * 8 * 2 * scale, im_scale * 8 * scale, pic); } } x += 8 * 2 * scale; } if (start[j] == '\\') j++; // Advance. continue; } if (start[j] == '&') { if (start[j + 1] == 'r') { memset(rgba, 255, sizeof(byte) * 4); j += 2; continue; } else if (start[j + 1] == 'c' && start[j + 2] && start[j + 3] && start[j + 4]) { rgba[0] = (byte)(255 * ((float)(start[j + 2] - '0') / 9)); rgba[1] = (byte)(255 * ((float)(start[j + 3] - '0') / 9)); rgba[2] = (byte)(255 * ((float)(start[j + 4] - '0') / 9)); j += 5; continue; } } rgba[3] = 255 * alpha; Draw_SColoredCharacterW (x, y, char2wc(start[j]), RGBAVECT_TO_COLOR(rgba), scale); j++; x += 8 * scale; } y += 8 * scale; // Next line. start += l; if (*start == '\n') start++; // Skip the \n } } }
// // FileList drawing func // void FL_Draw(filelist_t *fl, int x, int y, int w, int h) { int i; int listsize, pos, interline, inter_up, inter_dn, rowh; char line[1024]; char sname[MAX_PATH] = {0}, ssize[COL_SIZE+1] = {0}, sdate[COL_DATE+1] = {0}, stime[COL_TIME+1] = {0}; // Check if it's time for us to reset the search. // (FL_SEARCH_TIMEOUT seconds after the user entered the last char in the search term) if (Sys_DoubleTime() - last_search_enter_time >= FL_SEARCH_TIMEOUT) { fl->search_valid = false; fl->search_string[0] = 0; } if (fl->mode == FL_MODE_DELETE) { UI_Print_Center(x, y + 8, w, "Are you sure you want to delete this file?", true); UI_Print_Center(x, y + 24, w, FL_GetCurrentDisplay(fl), false); UI_Print_Center(x, y + 40, w, "(Y/N)", true); return; } #ifdef WITH_ZIP else if (fl->mode == FL_MODE_COMPRESS) { UI_Print_Center(x, y + 8, w, "Are you sure you want to compress this file?", true); UI_Print_Center(x, y + 24, w, FL_GetCurrentDisplay(fl), false); UI_Print_Center(x, y + 40, w, "(Y/N)", true); return; } else if (fl->mode == FL_MODE_DECOMPRESS) { UI_Print_Center(x, y + 8, w, "Are you sure you want to decompress this file?", true); UI_Print_Center(x, y + 24, w, FL_GetCurrentDisplay(fl), false); UI_Print_Center(x, y + 40, w, "(Y/N)", true); return; } #endif // WITH_ZIP fl->last_page_size = 0; w -= fl->scrollbar->width; // Calculate interline (The space between each row) interline = file_browser_interline.value; interline = max(interline, 0); interline = min(interline, 6); inter_up = interline / 2; inter_dn = interline - inter_up; rowh = 8 + inter_up + inter_dn; listsize = h / rowh; // Check screen boundaries and mimnimum size if (w < 160 || h < 80) return; if (x < 0 || y < 0 || x + w > vid.width || y + h > vid.height) return; if (fl->need_refresh) { #ifdef WITH_ZIP if (fl->in_archive) { FL_ReadArchive (fl); } else #endif // WITH_ZIP { FL_ReadDir(fl); } } if (fl->need_resort) { FL_SortDir(fl); } if (fl->search_dirty) { FL_Search(fl); } // Print the current path. { char *curr_path = NULL; #ifdef WITH_ZIP if (fl->in_archive) { curr_path = fl->current_archive; } else #endif // WITH_ZIP { curr_path = fl->current_dir; } // Make the path fit on screen "c:\quake\bla\bla\bla" => "c:\quake...la\bla". COM_FitPath (line, sizeof(line), curr_path, w/8); } line[w/8] = 0; UI_Print(x, y + inter_up, line, true); listsize--; // Draw column titles. pos = w/8; memset(line, ' ', pos); line[pos] = 0; if (file_browser_show_time.value) Add_Column(line, &pos, "time", COL_TIME); if (file_browser_show_date.value) Add_Column(line, &pos, "date", COL_DATE); if (file_browser_show_size.value) Add_Column(line, &pos, " kb", COL_SIZE); memcpy(line, "name", min(pos, 4)); line[w/8] = 0; UI_Print_Center(x, y + rowh + inter_dn, w, line, true); listsize--; // Nothing to show. if (fl->num_entries <= 0) { UI_Print_Center(x, y + 2 * rowh + inter_dn + 4, w, "directory empty", false); return; } // Something went wrong when processing the directory. if (fl->error) { UI_Print_Center(x, y + 2 * rowh + inter_dn + 4, w, "error reading directory", false); return; } // If we're showing the status bar we have less room for the file list. if (file_browser_show_status.value) { listsize -= 3; } fl->list_width = w; fl->list_height = listsize*rowh; fl->list_y_offset = 2 * rowh; fl->last_page_size = listsize; // Remember for PGUP/PGDN fl->displayed_entries_count = listsize; FL_CheckPosition(fl); if (fl->displayed_entries_count < fl->num_entries) { ScrollBar_Draw(fl->scrollbar, x + fl->list_width, y + fl->list_y_offset, fl->list_height); } for (i = 0; i < listsize; i++) { filedesc_t *entry; DWORD dwsize; char size[COL_SIZE+1], date[COL_DATE+1], time[COL_TIME+1]; char name[MAX_PATH]; int filenum = fl->display_entry + i; clrinfo_t clr[2]; // here we use _one_ color, at begining of the string static char last_name[sizeof(name)] = {0}; // this is for scroll, can't put it inside scroll code clr[0].c = COLOR_WHITE; clr[0].i = 0; // begin of the string if (filenum >= fl->num_entries) break; entry = &fl->entries[filenum]; // Extract date & time. snprintf(date, sizeof(date), "%02d-%02d-%02d", entry->time.wYear % 100, entry->time.wMonth, entry->time.wDay); snprintf(time, sizeof(time), "%2d:%02d", entry->time.wHour, entry->time.wMinute); // Extract size. if (entry->is_directory) { strlcpy(size, "<-->", sizeof(size)); if (filenum == fl->current_entry) strlcpy(ssize, "dir", sizeof(ssize)); } else { dwsize = entry->size / 1024; if (dwsize > 9999) { dwsize /= 1024; dwsize = min(dwsize, 999); snprintf(size, sizeof(size), "%3dm", dwsize); if (filenum == fl->current_entry) snprintf(ssize, sizeof(ssize), "%d mb", dwsize); } else { snprintf(size, sizeof(size), "%4d", dwsize); if (filenum == fl->current_entry) snprintf(ssize, sizeof(ssize), "%d kb", dwsize); } } // Add the columns to the current row (starting from the right). pos = w/8; // Clear the line. memset(line, ' ', pos); line[pos] = 0; // Add columns. if (file_browser_show_time.value) Add_Column(line, &pos, time, COL_TIME); if (file_browser_show_date.value) Add_Column(line, &pos, date, COL_DATE); if (file_browser_show_size.value) Add_Column(line, &pos, size, COL_SIZE); // End of name, switch to white. clr[1].c = COLOR_WHITE; clr[1].i = pos; // Set the name. // (Add a space infront so that the cursor for the currently // selected file can fit infront) snprintf (name, sizeof(name) - 1, " %s", entry->display); // // Copy the display name of the entry into the space that's left on the row. // if (filenum == fl->current_entry && file_browser_scrollnames.value && strlen(name) > pos) { // We need to scroll the text since it doesn't fit. #define SCROLL_RIGHT 1 #define SCROLL_LEFT 0 double t = 0; static double t_last_scroll = 0; static qbool wait = false; static int scroll_position = 0; static int scroll_direction = SCROLL_RIGHT; static int last_text_length = 0; int text_length = strlen(name); float scroll_delay = 0.1; // If the text has changed since last time we scrolled // the scroll data will be invalid so reset it. if (last_text_length != text_length || !last_name[0] || strncmp(name, last_name, sizeof(last_name))) { strlcpy(last_name, name, sizeof(last_name)); scroll_position = 0; scroll_direction = SCROLL_RIGHT; last_text_length = text_length; // Wait a second before start scroll plz. wait = true; t_last_scroll = Sys_DoubleTime(); } // Get the current time. t = Sys_DoubleTime(); // Time to scroll. if (!wait && (t - t_last_scroll) > scroll_delay) { // Save the current time as the last time we scrolled // and change the scroll position depending on what direction we're scrolling. t_last_scroll = t; scroll_position = (scroll_direction == SCROLL_RIGHT) ? scroll_position + 1 : scroll_position - 1; } // Set the scroll direction. if (text_length - scroll_position == pos) { // We've reached the end, go back. scroll_direction = SCROLL_LEFT; wait = true; } else if (scroll_position == 0) { // At the beginning, start over. scroll_direction = SCROLL_RIGHT; wait = true; } // Wait a second when changing direction. if (wait && (t - t_last_scroll) > 1.0) { wait = false; } memcpy(line, name + scroll_position, min(pos, text_length + scroll_position)); } else { // // Fits in the name column, no need to scroll (or the user doesn't want us to scroll :~<) // // Did we just select a new entry? In that case reset the scrolling. if (filenum == fl->current_entry) { last_name[0] = 0; } // If it's not the selected directory/zip color it so that it stands out. if (filenum != fl->current_entry) { if (entry->is_directory) { // Set directory color. clr[0].c = RGBAVECT_TO_COLOR(file_browser_dir_color.color); } #ifdef WITH_ZIP else if (entry->is_archive) { // Set zip color. clr[0].c = RGBAVECT_TO_COLOR(file_browser_archive_color.color); } #endif // WITH_ZIP else { clr[0].c = RGBAVECT_TO_COLOR(file_browser_file_color.color); } } memcpy(line, name, min(pos, strlen(name))); } // Draw a cursor character at the start of the line. if (filenum == fl->current_entry) { line[0] = 141; UI_DrawGrayBox(x, y + rowh * (i + 2) + inter_dn, w, rowh); } // Max amount of characters that fits on a line. line[w/8] = 0; // Color the selected entry. if (filenum == fl->current_entry) { clr[0].c = RGBAVECT_TO_COLOR(file_browser_selected_color.color); clr[0].i = 1; // Don't color the cursor (index 0). } // Print the line for the directory entry. UI_Print_Center3(x, y + rowh * (i + 2) + inter_dn, w, line, clr, 2, 0); // Remember the currently selected file for dispalying in the status bar if (filenum == fl->current_entry) { strlcpy (sname, line + 1, min(pos, sizeof(sname))); strlcpy (stime, time, sizeof(stime)); snprintf (sdate, sizeof(sdate), "%02d-%02d-%02d", entry->time.wYear % 100, entry->time.wMonth, entry->time.wDay); } } // Show a statusbar displaying the currently selected entry. if (file_browser_show_status.value) { // Print a line to part the status bar from the file list. memset(line, '\x1E', w/8); line[0] = '\x1D'; line[w/8 - 1] = '\x1F'; line[w/8] = 0; UI_Print(x, y + h - 3 * rowh - inter_up, line, false); // Print the name. UI_Print_Center(x, y + h - 2 * rowh - inter_up, w, sname, false); if (fl->search_valid) { // Some weird but nice-looking string in Quake font perhaps strlcpy(line, "search for: ", sizeof(line)); // seach for: if (fl->search_error) { strlcat(line, "not found", sizeof(line)); UI_Print_Center(x, y + h - rowh - inter_up, w, line, false); } else { strlcat(line, fl->search_string, sizeof(line)); UI_Print_Center(x, y + h - rowh - inter_up, w, line, true); } } else { snprintf(line, sizeof(line), "%s \x8f modified: %s %s", ssize, sdate, stime); UI_Print_Center(x, y + h - rowh - inter_up, w, line, false); } } }