From: Holger Schemel Date: Mon, 25 Jan 1999 22:04:28 +0000 (+0100) Subject: rnd-19990126-1 X-Git-Tag: 1.3.0^2~14 X-Git-Url: https://git.artsoft.org/?a=commitdiff_plain;h=e985382cdedf6fbfb89d64e429c0da56754b9e7c;p=rocksndiamonds.git rnd-19990126-1 --- diff --git a/src/buttons.c b/src/buttons.c index 1d29e9a5..9c19a36a 100644 --- a/src/buttons.c +++ b/src/buttons.c @@ -1611,6 +1611,12 @@ int CheckCountButtons(int mx, int my, int button) /* NEW GADGET STUFF -------------------------------------------------------- */ +/* values for DrawGadget() */ +#define DG_UNPRESSED 0 +#define DG_PRESSED 1 +#define DG_BUFFERED 0 +#define DG_DIRECT 1 + static struct GadgetInfo *gadget_list_first_entry = NULL; static struct GadgetInfo *gadget_list_last_entry = NULL; static int next_free_gadget_id = 1; @@ -1677,90 +1683,245 @@ static void default_callback_action(void *ptr) return; } -struct GadgetInfo *CreateGadget(int first_tag, ...) +static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) { - struct GadgetInfo *new_gadget = checked_malloc(sizeof(struct GadgetInfo)); - int tag = first_tag; - va_list ap; + int state = (pressed ? 1 : 0); + struct GadgetDesign *gd = (gi->checked ? + &gi->alt_design[state] : + &gi->design[state]); - va_start(ap, first_tag); + switch (gi->type) + { + case GD_TYPE_NORMAL_BUTTON: + case GD_TYPE_CHECK_BUTTON: + case GD_TYPE_RADIO_BUTTON: + XCopyArea(display, gd->pixmap, drawto, gc, + gd->x, gd->y, gi->width, gi->height, gi->x, gi->y); + if (gi->deco.design.pixmap) + XCopyArea(display, gi->deco.design.pixmap, drawto, gc, + gi->deco.design.x, gi->deco.design.y, + gi->deco.width, gi->deco.height, + gi->x + gi->deco.x + (pressed ? gi->deco.xshift : 0), + gi->y + gi->deco.y + (pressed ? gi->deco.yshift : 0)); + break; - /* always start with reliable default values */ - memset(new_gadget, 0, sizeof(struct GadgetInfo)); /* zero all fields */ - new_gadget->id = getNewGadgetID(); - new_gadget->callback_info = default_callback_info; - new_gadget->callback_action = default_callback_action; + case GD_TYPE_TEXTINPUT_ALPHANUMERIC: + case GD_TYPE_TEXTINPUT_NUMERIC: + { + int i; + char cursor_letter; + char cursor_string[3]; + char text[MAX_GADGET_TEXTSIZE + 1]; + int font_color = FC_YELLOW; + int border = gi->design_border; + strcpy(text, gi->text.value); + strcat(text, " "); + + /* left part of gadget */ + XCopyArea(display, gd->pixmap, drawto, gc, + gd->x, gd->y, border, gi->height, gi->x, gi->y); + + /* middle part of gadget */ + for (i=0; i<=gi->text.size; i++) + XCopyArea(display, gd->pixmap, drawto, gc, + gd->x + border, gd->y, FONT2_XSIZE, gi->height, + gi->x + border + i * FONT2_XSIZE, gi->y); + + /* right part of gadget */ + XCopyArea(display, gd->pixmap, drawto, gc, + gd->x + ED_WIN_COUNT_XSIZE - border, gd->y, + border, gi->height, gi->x + gi->width - border, gi->y); + + /* gadget text value */ + DrawText(gi->x + border, gi->y + border, text, FS_SMALL, font_color); + + cursor_letter = gi->text.value[gi->text.cursor_position]; + cursor_string[0] = '~'; + cursor_string[1] = (cursor_letter != '\0' ? cursor_letter : ' '); + cursor_string[2] = '\0'; + + /* draw cursor, if active */ + if (pressed) + DrawText(gi->x + border + gi->text.cursor_position * FONT2_XSIZE, + gi->y + border, cursor_string, FS_SMALL, font_color); + } + break; + + case GD_TYPE_SCROLLBAR_VERTICAL: + { + int i; + int xpos = gi->x; + int ypos = gi->y + gi->scrollbar.position; + int design_full = gi->width; + int design_body = design_full - 2 * gi->design_border; + int size_full = gi->scrollbar.size; + int size_body = size_full - 2 * gi->design_border; + int num_steps = size_body / design_body; + int step_size_remain = size_body - num_steps * design_body; + + /* clear scrollbar area */ + XFillRectangle(display, backbuffer, gc, + gi->x, gi->y, gi->width, gi->height); + + /* upper part of gadget */ + XCopyArea(display, gd->pixmap, drawto, gc, + gd->x, gd->y, + gi->width, gi->design_border, + xpos, ypos); + + /* middle part of gadget */ + for (i=0; ipixmap, drawto, gc, + gd->x, gd->y + gi->design_border, + gi->width, design_body, + xpos, ypos + gi->design_border + i * design_body); + + /* remaining middle part of gadget */ + if (step_size_remain > 0) + XCopyArea(display, gd->pixmap, drawto, gc, + gd->x, gd->y + gi->design_border, + gi->width, step_size_remain, + xpos, ypos + gi->design_border + num_steps * design_body); + + /* lower part of gadget */ + XCopyArea(display, gd->pixmap, drawto, gc, + gd->x, gd->y + design_full - gi->design_border, + gi->width, gi->design_border, + xpos, ypos + size_full - gi->design_border); + } + break; + + case GD_TYPE_SCROLLBAR_HORIZONTAL: + { + int i; + int xpos = gi->x + gi->scrollbar.position; + int ypos = gi->y; + int design_full = gi->height; + int design_body = design_full - 2 * gi->design_border; + int size_full = gi->scrollbar.size; + int size_body = size_full - 2 * gi->design_border; + int num_steps = size_body / design_body; + int step_size_remain = size_body - num_steps * design_body; + + /* clear scrollbar area */ + XFillRectangle(display, backbuffer, gc, + gi->x, gi->y, gi->width, gi->height); + + /* left part of gadget */ + XCopyArea(display, gd->pixmap, drawto, gc, + gd->x, gd->y, + gi->design_border, gi->height, + xpos, ypos); + + /* middle part of gadget */ + for (i=0; ipixmap, drawto, gc, + gd->x + gi->design_border, gd->y, + design_body, gi->height, + xpos + gi->design_border + i * design_body, ypos); + + /* remaining middle part of gadget */ + if (step_size_remain > 0) + XCopyArea(display, gd->pixmap, drawto, gc, + gd->x + gi->design_border, gd->y, + step_size_remain, gi->height, + xpos + gi->design_border + num_steps * design_body, ypos); + + /* right part of gadget */ + XCopyArea(display, gd->pixmap, drawto, gc, + gd->x + design_full - gi->design_border, gd->y, + gi->design_border, gi->height, + xpos + size_full - gi->design_border, ypos); + } + break; + + default: + return; + } + + if (direct) + XCopyArea(display, drawto, window, gc, + gi->x, gi->y, gi->width, gi->height, gi->x, gi->y); + else + redraw_mask |= (gi->x < SX + SXSIZE ? REDRAW_FIELD : + gi->y < DY + DYSIZE ? REDRAW_DOOR_1 : + gi->y > VY ? REDRAW_DOOR_2 : REDRAW_DOOR_3); +} + +static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) +{ + int tag = first_tag; while (tag != GDI_END) { switch(tag) { case GDI_CUSTOM_ID: - new_gadget->custom_id = va_arg(ap, int); + gi->custom_id = va_arg(ap, int); break; case GDI_INFO_TEXT: { int max_textsize = MAX_INFO_TEXTSIZE; - strncpy(new_gadget->info_text, va_arg(ap, char *), max_textsize); - new_gadget->info_text[max_textsize] = '\0'; + strncpy(gi->info_text, va_arg(ap, char *), max_textsize); + gi->info_text[max_textsize] = '\0'; } break; case GDI_X: - new_gadget->x = va_arg(ap, int); + gi->x = va_arg(ap, int); break; case GDI_Y: - new_gadget->y = va_arg(ap, int); + gi->y = va_arg(ap, int); break; case GDI_WIDTH: - new_gadget->width = va_arg(ap, int); + gi->width = va_arg(ap, int); break; case GDI_HEIGHT: - new_gadget->height = va_arg(ap, int); + gi->height = va_arg(ap, int); break; case GDI_TYPE: - new_gadget->type = va_arg(ap, unsigned long); + gi->type = va_arg(ap, unsigned long); break; case GDI_STATE: - new_gadget->state = va_arg(ap, unsigned long); + gi->state = va_arg(ap, unsigned long); break; case GDI_CHECKED: - new_gadget->checked = va_arg(ap, boolean); + gi->checked = va_arg(ap, boolean); break; case GDI_RADIO_NR: - new_gadget->radio_nr = va_arg(ap, unsigned long); + gi->radio_nr = va_arg(ap, unsigned long); break; case GDI_NUMBER_VALUE: - new_gadget->text.number_value = va_arg(ap, long); - sprintf(new_gadget->text.value, "%d", new_gadget->text.number_value); - new_gadget->text.cursor_position = strlen(new_gadget->text.value); + gi->text.number_value = va_arg(ap, long); + sprintf(gi->text.value, "%d", gi->text.number_value); + gi->text.cursor_position = strlen(gi->text.value); break; case GDI_NUMBER_MIN: - new_gadget->text.number_min = va_arg(ap, long); - if (new_gadget->text.number_value < new_gadget->text.number_min) + gi->text.number_min = va_arg(ap, long); + if (gi->text.number_value < gi->text.number_min) { - new_gadget->text.number_value = new_gadget->text.number_min; - sprintf(new_gadget->text.value, "%d", new_gadget->text.number_value); + gi->text.number_value = gi->text.number_min; + sprintf(gi->text.value, "%d", gi->text.number_value); } break; case GDI_NUMBER_MAX: - new_gadget->text.number_max = va_arg(ap, long); - if (new_gadget->text.number_value > new_gadget->text.number_max) + gi->text.number_max = va_arg(ap, long); + if (gi->text.number_value > gi->text.number_max) { - new_gadget->text.number_value = new_gadget->text.number_max; - sprintf(new_gadget->text.value, "%d", new_gadget->text.number_value); + gi->text.number_value = gi->text.number_max; + sprintf(gi->text.value, "%d", gi->text.number_value); } break; @@ -1768,12 +1929,12 @@ struct GadgetInfo *CreateGadget(int first_tag, ...) { int max_textsize = MAX_GADGET_TEXTSIZE; - if (new_gadget->text.size) - max_textsize = MIN(new_gadget->text.size, MAX_GADGET_TEXTSIZE - 1); + if (gi->text.size) + max_textsize = MIN(gi->text.size, MAX_GADGET_TEXTSIZE - 1); - strncpy(new_gadget->text.value, va_arg(ap, char *), max_textsize); - new_gadget->text.value[max_textsize] = '\0'; - new_gadget->text.cursor_position = strlen(new_gadget->text.value); + strncpy(gi->text.value, va_arg(ap, char *), max_textsize); + gi->text.value[max_textsize] = '\0'; + gi->text.cursor_position = strlen(gi->text.value); } break; @@ -1782,174 +1943,207 @@ struct GadgetInfo *CreateGadget(int first_tag, ...) int tag_value = va_arg(ap, int); int max_textsize = MIN(tag_value, MAX_GADGET_TEXTSIZE - 1); - new_gadget->text.size = max_textsize; - new_gadget->text.value[max_textsize] = '\0'; + gi->text.size = max_textsize; + gi->text.value[max_textsize] = '\0'; - if (new_gadget->width == 0 && new_gadget->height == 0) + if (gi->width == 0 && gi->height == 0) { - new_gadget->width = (new_gadget->text.size + 1) * FONT2_XSIZE + 6; - new_gadget->height = ED_WIN_COUNT_YSIZE; + gi->width = (gi->text.size + 1) * FONT2_XSIZE + 6; + gi->height = ED_WIN_COUNT_YSIZE; } } break; case GDI_DESIGN_UNPRESSED: - new_gadget->design[GD_BUTTON_UNPRESSED].pixmap = va_arg(ap, Pixmap); - new_gadget->design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int); - new_gadget->design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int); + gi->design[GD_BUTTON_UNPRESSED].pixmap = va_arg(ap, Pixmap); + gi->design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int); + gi->design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int); break; case GDI_DESIGN_PRESSED: - new_gadget->design[GD_BUTTON_PRESSED].pixmap = va_arg(ap, Pixmap); - new_gadget->design[GD_BUTTON_PRESSED].x = va_arg(ap, int); - new_gadget->design[GD_BUTTON_PRESSED].y = va_arg(ap, int); + gi->design[GD_BUTTON_PRESSED].pixmap = va_arg(ap, Pixmap); + gi->design[GD_BUTTON_PRESSED].x = va_arg(ap, int); + gi->design[GD_BUTTON_PRESSED].y = va_arg(ap, int); break; case GDI_ALT_DESIGN_UNPRESSED: - new_gadget->alt_design[GD_BUTTON_UNPRESSED].pixmap= va_arg(ap, Pixmap); - new_gadget->alt_design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int); - new_gadget->alt_design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int); + gi->alt_design[GD_BUTTON_UNPRESSED].pixmap= va_arg(ap, Pixmap); + gi->alt_design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int); + gi->alt_design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int); break; case GDI_ALT_DESIGN_PRESSED: - new_gadget->alt_design[GD_BUTTON_PRESSED].pixmap = va_arg(ap, Pixmap); - new_gadget->alt_design[GD_BUTTON_PRESSED].x = va_arg(ap, int); - new_gadget->alt_design[GD_BUTTON_PRESSED].y = va_arg(ap, int); + gi->alt_design[GD_BUTTON_PRESSED].pixmap = va_arg(ap, Pixmap); + gi->alt_design[GD_BUTTON_PRESSED].x = va_arg(ap, int); + gi->alt_design[GD_BUTTON_PRESSED].y = va_arg(ap, int); break; case GDI_DESIGN_BORDER: - new_gadget->design_border = va_arg(ap, int); + gi->design_border = va_arg(ap, int); break; case GDI_DECORATION_DESIGN: - new_gadget->deco.design.pixmap = va_arg(ap, Pixmap); - new_gadget->deco.design.x = va_arg(ap, int); - new_gadget->deco.design.y = va_arg(ap, int); + gi->deco.design.pixmap = va_arg(ap, Pixmap); + gi->deco.design.x = va_arg(ap, int); + gi->deco.design.y = va_arg(ap, int); break; case GDI_DECORATION_POSITION: - new_gadget->deco.x = va_arg(ap, int); - new_gadget->deco.y = va_arg(ap, int); + gi->deco.x = va_arg(ap, int); + gi->deco.y = va_arg(ap, int); break; case GDI_DECORATION_SIZE: - new_gadget->deco.width = va_arg(ap, int); - new_gadget->deco.height = va_arg(ap, int); + gi->deco.width = va_arg(ap, int); + gi->deco.height = va_arg(ap, int); break; case GDI_DECORATION_SHIFTING: - new_gadget->deco.xshift = va_arg(ap, int); - new_gadget->deco.yshift = va_arg(ap, int); + gi->deco.xshift = va_arg(ap, int); + gi->deco.yshift = va_arg(ap, int); break; case GDI_EVENT_MASK: - new_gadget->event_mask = va_arg(ap, unsigned long); + gi->event_mask = va_arg(ap, unsigned long); break; case GDI_AREA_SIZE: - new_gadget->drawing.area_xsize = va_arg(ap, int); - new_gadget->drawing.area_ysize = va_arg(ap, int); + gi->drawing.area_xsize = va_arg(ap, int); + gi->drawing.area_ysize = va_arg(ap, int); /* determine dependent values for drawing area gadget, if needed */ - if (new_gadget->width == 0 && - new_gadget->height == 0 && - new_gadget->drawing.item_xsize !=0 && - new_gadget->drawing.item_ysize !=0) + if (gi->width == 0 && gi->height == 0 && + gi->drawing.item_xsize !=0 && gi->drawing.item_ysize !=0) { - new_gadget->width = - new_gadget->drawing.area_xsize * new_gadget->drawing.item_xsize; - new_gadget->height = - new_gadget->drawing.area_ysize * new_gadget->drawing.item_ysize; + gi->width = gi->drawing.area_xsize * gi->drawing.item_xsize; + gi->height = gi->drawing.area_ysize * gi->drawing.item_ysize; } - else if (new_gadget->drawing.item_xsize == 0 && - new_gadget->drawing.item_ysize == 0 && - new_gadget->width != 0 && - new_gadget->height != 0) + else if (gi->drawing.item_xsize == 0 && gi->drawing.item_ysize == 0 && + gi->width != 0 && gi->height != 0) { - new_gadget->drawing.item_xsize = - new_gadget->width / new_gadget->drawing.area_xsize; - new_gadget->drawing.item_ysize = - new_gadget->height / new_gadget->drawing.area_ysize; + gi->drawing.item_xsize = gi->width / gi->drawing.area_xsize; + gi->drawing.item_ysize = gi->height / gi->drawing.area_ysize; } break; case GDI_ITEM_SIZE: - new_gadget->drawing.item_xsize = va_arg(ap, int); - new_gadget->drawing.item_ysize = va_arg(ap, int); + gi->drawing.item_xsize = va_arg(ap, int); + gi->drawing.item_ysize = va_arg(ap, int); /* determine dependent values for drawing area gadget, if needed */ - if (new_gadget->width == 0 && - new_gadget->height == 0 && - new_gadget->drawing.area_xsize !=0 && - new_gadget->drawing.area_ysize !=0) + if (gi->width == 0 && gi->height == 0 && + gi->drawing.area_xsize !=0 && gi->drawing.area_ysize !=0) { - new_gadget->width = - new_gadget->drawing.area_xsize * new_gadget->drawing.item_xsize; - new_gadget->height = - new_gadget->drawing.area_ysize * new_gadget->drawing.item_ysize; + gi->width = gi->drawing.area_xsize * gi->drawing.item_xsize; + gi->height = gi->drawing.area_ysize * gi->drawing.item_ysize; } - else if (new_gadget->drawing.area_xsize == 0 && - new_gadget->drawing.area_ysize == 0 && - new_gadget->width != 0 && - new_gadget->height != 0) + else if (gi->drawing.area_xsize == 0 && gi->drawing.area_ysize == 0 && + gi->width != 0 && gi->height != 0) { - new_gadget->drawing.area_xsize = - new_gadget->width / new_gadget->drawing.item_xsize; - new_gadget->drawing.area_ysize = - new_gadget->height / new_gadget->drawing.item_ysize; + gi->drawing.area_xsize = gi->width / gi->drawing.item_xsize; + gi->drawing.area_ysize = gi->height / gi->drawing.item_ysize; } break; case GDI_SCROLLBAR_ITEMS_MAX: - new_gadget->scrollbar.items_max = va_arg(ap, int); + gi->scrollbar.items_max = va_arg(ap, int); break; case GDI_SCROLLBAR_ITEMS_VISIBLE: - new_gadget->scrollbar.items_visible = va_arg(ap, int); + gi->scrollbar.items_visible = va_arg(ap, int); break; case GDI_SCROLLBAR_ITEM_POSITION: - new_gadget->scrollbar.item_position = va_arg(ap, int); + gi->scrollbar.item_position = va_arg(ap, int); break; case GDI_CALLBACK_INFO: - new_gadget->callback_info = va_arg(ap, gadget_function); + gi->callback_info = va_arg(ap, gadget_function); break; case GDI_CALLBACK_ACTION: - new_gadget->callback_action = va_arg(ap, gadget_function); + gi->callback_action = va_arg(ap, gadget_function); break; default: - Error(ERR_EXIT, "CreateGadget(): unknown tag %d", tag); + Error(ERR_EXIT, "HandleGadgetTags(): unknown tag %d", tag); } tag = va_arg(ap, int); /* read next tag */ } - va_end(ap); - /* check if gadget complete */ - if (new_gadget->type != GD_TYPE_DRAWING_AREA && - (!new_gadget->design[GD_BUTTON_UNPRESSED].pixmap || - !new_gadget->design[GD_BUTTON_PRESSED].pixmap)) + if (gi->type != GD_TYPE_DRAWING_AREA && + (!gi->design[GD_BUTTON_UNPRESSED].pixmap || + !gi->design[GD_BUTTON_PRESSED].pixmap)) Error(ERR_EXIT, "gadget incomplete (missing Pixmap)"); - if (new_gadget->type & GD_TYPE_SCROLLBAR) + /* adjust gadget values in relation to other gadget values */ + + if (gi->type & GD_TYPE_TEXTINPUT_NUMERIC) { - struct GadgetScrollbar *gs = &new_gadget->scrollbar; + struct GadgetTextInput *text = &gi->text; + int value = text->number_value; + + text->number_value = (value < text->number_min ? text->number_min : + value > text->number_max ? text->number_max : + value); - if (new_gadget->width == 0 || new_gadget->height == 0 || + sprintf(text->value, "%d", text->number_value); + } + + if (gi->type & GD_TYPE_SCROLLBAR) + { + struct GadgetScrollbar *gs = &gi->scrollbar; + + if (gi->width == 0 || gi->height == 0 || gs->items_max == 0 || gs->items_visible == 0) Error(ERR_EXIT, "scrollbar gadget incomplete (missing tags)"); /* calculate internal scrollbar values */ - gs->size_max = (new_gadget->type == GD_TYPE_SCROLLBAR_VERTICAL ? - new_gadget->height : new_gadget->width); + gs->size_max = (gi->type == GD_TYPE_SCROLLBAR_VERTICAL ? + gi->height : gi->width); gs->size = gs->size_max * gs->items_visible / gs->items_max; gs->position = gs->size_max * gs->item_position / gs->items_max; gs->position_max = gs->size_max - gs->size; + + /* finetuning for maximal right/bottom position */ + if (gs->item_position == gs->items_max - gs->items_visible) + gs->position = gs->position_max; } +} + +void ModifyGadget(struct GadgetInfo *gi, int first_tag, ...) +{ + va_list ap; + + va_start(ap, first_tag); + HandleGadgetTags(gi, first_tag, ap); + va_end(ap); + + RedrawGadget(gi); +} + +void RedrawGadget(struct GadgetInfo *gi) +{ + if (gi->mapped) + DrawGadget(gi, gi->state, DG_DIRECT); +} + +struct GadgetInfo *CreateGadget(int first_tag, ...) +{ + struct GadgetInfo *new_gadget = checked_malloc(sizeof(struct GadgetInfo)); + va_list ap; + + /* always start with reliable default values */ + memset(new_gadget, 0, sizeof(struct GadgetInfo)); /* zero all fields */ + new_gadget->id = getNewGadgetID(); + new_gadget->callback_info = default_callback_info; + new_gadget->callback_action = default_callback_action; + + va_start(ap, first_tag); + HandleGadgetTags(new_gadget, first_tag, ap); + va_end(ap); /* insert new gadget into global gadget list */ if (gadget_list_last_entry) @@ -1980,12 +2174,6 @@ void FreeGadget(struct GadgetInfo *gi) free(gi); } -/* values for DrawGadget() */ -#define DG_UNPRESSED 0 -#define DG_PRESSED 1 -#define DG_BUFFERED 0 -#define DG_DIRECT 1 - static void CheckRangeOfNumericInputGadget(struct GadgetInfo *gi) { if (gi->type != GD_TYPE_TEXTINPUT_NUMERIC) @@ -2006,231 +2194,6 @@ static void CheckRangeOfNumericInputGadget(struct GadgetInfo *gi) gi->text.cursor_position = strlen(gi->text.value); } -static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) -{ - int state = (pressed ? 1 : 0); - struct GadgetDesign *gd = (gi->checked ? - &gi->alt_design[state] : - &gi->design[state]); - - switch (gi->type) - { - case GD_TYPE_NORMAL_BUTTON: - case GD_TYPE_CHECK_BUTTON: - case GD_TYPE_RADIO_BUTTON: - XCopyArea(display, gd->pixmap, drawto, gc, - gd->x, gd->y, gi->width, gi->height, gi->x, gi->y); - if (gi->deco.design.pixmap) - XCopyArea(display, gi->deco.design.pixmap, drawto, gc, - gi->deco.design.x, gi->deco.design.y, - gi->deco.width, gi->deco.height, - gi->x + gi->deco.x + (pressed ? gi->deco.xshift : 0), - gi->y + gi->deco.y + (pressed ? gi->deco.yshift : 0)); - break; - - case GD_TYPE_TEXTINPUT_ALPHANUMERIC: - case GD_TYPE_TEXTINPUT_NUMERIC: - { - int i; - char cursor_letter; - char cursor_string[3]; - char text[MAX_GADGET_TEXTSIZE + 1]; - int font_color = FC_YELLOW; - int border = gi->design_border; - strcpy(text, gi->text.value); - strcat(text, " "); - - /* left part of gadget */ - XCopyArea(display, gd->pixmap, drawto, gc, - gd->x, gd->y, border, gi->height, gi->x, gi->y); - - /* middle part of gadget */ - for (i=0; i<=gi->text.size; i++) - XCopyArea(display, gd->pixmap, drawto, gc, - gd->x + border, gd->y, FONT2_XSIZE, gi->height, - gi->x + border + i * FONT2_XSIZE, gi->y); - - /* right part of gadget */ - XCopyArea(display, gd->pixmap, drawto, gc, - gd->x + ED_WIN_COUNT_XSIZE - border, gd->y, - border, gi->height, gi->x + gi->width - border, gi->y); - - /* gadget text value */ - DrawText(gi->x + border, gi->y + border, text, FS_SMALL, font_color); - - cursor_letter = gi->text.value[gi->text.cursor_position]; - cursor_string[0] = '~'; - cursor_string[1] = (cursor_letter != '\0' ? cursor_letter : ' '); - cursor_string[2] = '\0'; - - /* draw cursor, if active */ - if (pressed) - DrawText(gi->x + border + gi->text.cursor_position * FONT2_XSIZE, - gi->y + border, cursor_string, FS_SMALL, font_color); - } - break; - - case GD_TYPE_SCROLLBAR_VERTICAL: - { - int i; - int xpos = gi->x; - int ypos = gi->y + gi->scrollbar.position; - int design_full = gi->width; - int design_body = design_full - 2 * gi->design_border; - int size_full = gi->scrollbar.size; - int size_body = size_full - 2 * gi->design_border; - int num_steps = size_body / design_body; - int step_size_remain = size_body - num_steps * design_body; - - /* clear scrollbar area */ - XFillRectangle(display, backbuffer, gc, - gi->x, gi->y, gi->width, gi->height); - - /* upper part of gadget */ - XCopyArea(display, gd->pixmap, drawto, gc, - gd->x, gd->y, - gi->width, gi->design_border, - xpos, ypos); - - /* middle part of gadget */ - for (i=0; ipixmap, drawto, gc, - gd->x, gd->y + gi->design_border, - gi->width, design_body, - xpos, ypos + gi->design_border + i * design_body); - - /* remaining middle part of gadget */ - if (step_size_remain > 0) - XCopyArea(display, gd->pixmap, drawto, gc, - gd->x, gd->y + gi->design_border, - gi->width, step_size_remain, - xpos, ypos + gi->design_border + num_steps * design_body); - - /* lower part of gadget */ - XCopyArea(display, gd->pixmap, drawto, gc, - gd->x, gd->y + design_full - gi->design_border, - gi->width, gi->design_border, - xpos, ypos + size_full - gi->design_border); - } - break; - - case GD_TYPE_SCROLLBAR_HORIZONTAL: - { - int i; - int xpos = gi->x + gi->scrollbar.position; - int ypos = gi->y; - int design_full = gi->height; - int design_body = design_full - 2 * gi->design_border; - int size_full = gi->scrollbar.size; - int size_body = size_full - 2 * gi->design_border; - int num_steps = size_body / design_body; - int step_size_remain = size_body - num_steps * design_body; - - /* clear scrollbar area */ - XFillRectangle(display, backbuffer, gc, - gi->x, gi->y, gi->width, gi->height); - - /* left part of gadget */ - XCopyArea(display, gd->pixmap, drawto, gc, - gd->x, gd->y, - gi->design_border, gi->height, - xpos, ypos); - - /* middle part of gadget */ - for (i=0; ipixmap, drawto, gc, - gd->x + gi->design_border, gd->y, - design_body, gi->height, - xpos + gi->design_border + i * design_body, ypos); - - /* remaining middle part of gadget */ - if (step_size_remain > 0) - XCopyArea(display, gd->pixmap, drawto, gc, - gd->x + gi->design_border, gd->y, - step_size_remain, gi->height, - xpos + gi->design_border + num_steps * design_body, ypos); - - /* right part of gadget */ - XCopyArea(display, gd->pixmap, drawto, gc, - gd->x + design_full - gi->design_border, gd->y, - gi->design_border, gi->height, - xpos + size_full - gi->design_border, ypos); - } - break; - - default: - return; - } - - if (direct) - XCopyArea(display, drawto, window, gc, - gi->x, gi->y, gi->width, gi->height, gi->x, gi->y); - else - redraw_mask |= REDRAW_ALL; -} - -void ClickOnGadget(struct GadgetInfo *gi) -{ - /* simulate releasing mouse button over last gadget, if still pressed */ - if (button_status) - HandleGadgets(-1, -1, 0); - - /* simulate pressing mouse button over specified gadget */ - HandleGadgets(gi->x, gi->y, 1); - - /* simulate releasing mouse button over specified gadget */ - HandleGadgets(gi->x, gi->y, 0); -} - -void AdjustScrollbar(struct GadgetInfo *gi, int items_max, int item_pos) -{ - struct GadgetScrollbar *gs = &gi->scrollbar; - - gs->items_max = items_max; - gs->item_position = item_pos; - - gs->size = gs->size_max * gs->items_visible / gs->items_max; - gs->position = gs->size_max * gs->item_position / gs->items_max; - gs->position_max = gs->size_max - gs->size; - - /* finetuning for maximal right/bottom position */ - if (gs->item_position == gs->items_max - gs->items_visible) - gs->position = gs->position_max; - - if (gi->mapped) - DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); -} - -void ModifyTextInputTextValue(struct GadgetInfo *gi, char *new_text) -{ - struct GadgetTextInput *text = &gi->text; - int max_textsize = MAX_GADGET_TEXTSIZE; - - if (text->size) - max_textsize = MIN(text->size, MAX_GADGET_TEXTSIZE - 1); - - strncpy(text->value, new_text, max_textsize); - text->value[max_textsize] = '\0'; - text->cursor_position = strlen(text->value); - - if (gi->mapped) - DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); -} - -void ModifyTextInputNumberValue(struct GadgetInfo *gi, int new_value) -{ - struct GadgetTextInput *text = &gi->text; - - text->number_value = (new_value < text->number_min ? text->number_min : - new_value > text->number_max ? text->number_max : - new_value); - - sprintf(text->value, "%d", text->number_value); - - if (gi->mapped) - DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); -} - /* global pointer to gadget actually in use (when mouse button pressed) */ static struct GadgetInfo *last_gi = NULL; @@ -2310,6 +2273,19 @@ void RemapAllGadgets() MultiMapGadgets(MULTIMAP_ALL | MULTIMAP_REMAP); } +void ClickOnGadget(struct GadgetInfo *gi) +{ + /* simulate releasing mouse button over last gadget, if still pressed */ + if (button_status) + HandleGadgets(-1, -1, 0); + + /* simulate pressing mouse button over specified gadget */ + HandleGadgets(gi->x, gi->y, 1); + + /* simulate releasing mouse button over specified gadget */ + HandleGadgets(gi->x, gi->y, 0); +} + void HandleGadgets(int mx, int my, int button) { static struct GadgetInfo *last_info_gi = NULL; @@ -2516,7 +2492,8 @@ void HandleGadgets(int mx, int my, int button) changed_position = TRUE; } - AdjustScrollbar(gi, gs->items_max, gs->item_position); + ModifyGadget(gi, GDI_SCROLLBAR_ITEM_POSITION, gs->item_position, + GDI_END); gi->state = GD_BUTTON_UNPRESSED; gi->event.type = GD_EVENT_MOVING; diff --git a/src/buttons.h b/src/buttons.h index 2df5507d..55499229 100644 --- a/src/buttons.h +++ b/src/buttons.h @@ -427,10 +427,10 @@ struct GadgetInfo struct GadgetInfo *CreateGadget(int, ...); void FreeGadget(struct GadgetInfo *); +void ModifyGadget(struct GadgetInfo *, int, ...); +void RedrawGadget(struct GadgetInfo *); + void ClickOnGadget(struct GadgetInfo *); -void AdjustScrollbar(struct GadgetInfo *, int, int); -void ModifyTextInputTextValue(struct GadgetInfo *, char *); -void ModifyTextInputNumberValue(struct GadgetInfo *, int); void MapGadget(struct GadgetInfo *); void UnmapGadget(struct GadgetInfo *); diff --git a/src/editor.c b/src/editor.c index 2812b01e..1a54f928 100644 --- a/src/editor.c +++ b/src/editor.c @@ -1779,7 +1779,8 @@ void AdjustEditorScrollbar(int id) if (item_position > items_max - items_visible) item_position = items_max - items_visible; - AdjustScrollbar(gi, items_max, item_position); + ModifyGadget(gi, GDI_SCROLLBAR_ITEMS_MAX, items_max, + GDI_SCROLLBAR_ITEM_POSITION, item_position, GDI_END); } void ModifyEditorTextInput(int textinput_id, char *new_text) @@ -1787,7 +1788,7 @@ void ModifyEditorTextInput(int textinput_id, char *new_text) int gadget_id = textinput_info[textinput_id].gadget_id; struct GadgetInfo *gi = level_editor_gadget[gadget_id]; - ModifyTextInputTextValue(gi, new_text); + ModifyGadget(gi, GDI_TEXT_VALUE, new_text, GDI_END); } void ModifyEditorCounter(int counter_id, int new_value) @@ -1796,7 +1797,7 @@ void ModifyEditorCounter(int counter_id, int new_value) int gadget_id = counterbutton_info[counter_id].gadget_id_text; struct GadgetInfo *gi = level_editor_gadget[gadget_id]; - ModifyTextInputNumberValue(gi, new_value); + ModifyGadget(gi, GDI_NUMBER_VALUE, new_value, GDI_END); if (counter_value != NULL) *counter_value = gi->text.number_value; @@ -3419,9 +3420,9 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) { static boolean started_inside_drawing_area = FALSE; int id = gi->custom_id; - boolean inside_drawing_area = !gi->event.off_borders; boolean button_press_event; boolean button_release_event; + boolean inside_drawing_area = !gi->event.off_borders; boolean draw_level = (id == GADGET_ID_DRAWING_LEVEL); int new_element; int button = gi->event.button; @@ -3454,6 +3455,9 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) lx = sx + level_xpos; ly = sy + level_ypos; + if (!IN_LEV_FIELD(lx, ly)) + inside_drawing_area = FALSE; + /* make sure to stay inside level field boundaries */ lx = (lx < min_lx ? min_lx : lx > max_lx ? max_lx : lx); ly = (ly < min_ly ? min_ly : ly > max_ly ? max_ly : ly); @@ -3820,7 +3824,6 @@ static void HandleControlButtons(struct GadgetInfo *gi) { int gadget_id = GADGET_ID_SCROLL_HORIZONTAL; struct GadgetInfo *gi = level_editor_gadget[gadget_id]; - struct GadgetScrollbar *gs = &gi->scrollbar; if (lev_fieldx < ED_FIELDX - 2) break; @@ -3833,7 +3836,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) else DrawMiniLevel(level_xpos, level_ypos); - AdjustScrollbar(gi, gs->items_max, level_xpos + 1); + ModifyGadget(gi, GDI_SCROLLBAR_ITEM_POSITION, level_xpos + 1, GDI_END); } break; @@ -3842,7 +3845,6 @@ static void HandleControlButtons(struct GadgetInfo *gi) { int gadget_id = GADGET_ID_SCROLL_HORIZONTAL; struct GadgetInfo *gi = level_editor_gadget[gadget_id]; - struct GadgetScrollbar *gs = &gi->scrollbar; if (lev_fieldx < ED_FIELDX - 2) break; @@ -3855,7 +3857,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) else DrawMiniLevel(level_xpos, level_ypos); - AdjustScrollbar(gi, gs->items_max, level_xpos + 1); + ModifyGadget(gi, GDI_SCROLLBAR_ITEM_POSITION, level_xpos + 1, GDI_END); } break; @@ -3864,7 +3866,6 @@ static void HandleControlButtons(struct GadgetInfo *gi) { int gadget_id = GADGET_ID_SCROLL_VERTICAL; struct GadgetInfo *gi = level_editor_gadget[gadget_id]; - struct GadgetScrollbar *gs = &gi->scrollbar; if (lev_fieldy < ED_FIELDY - 2) break; @@ -3877,7 +3878,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) else DrawMiniLevel(level_xpos, level_ypos); - AdjustScrollbar(gi, gs->items_max, level_ypos + 1); + ModifyGadget(gi, GDI_SCROLLBAR_ITEM_POSITION, level_ypos + 1, GDI_END); } break; @@ -3886,7 +3887,6 @@ static void HandleControlButtons(struct GadgetInfo *gi) { int gadget_id = GADGET_ID_SCROLL_VERTICAL; struct GadgetInfo *gi = level_editor_gadget[gadget_id]; - struct GadgetScrollbar *gs = &gi->scrollbar; if (lev_fieldy < ED_FIELDY - 2) break; @@ -3899,7 +3899,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) else DrawMiniLevel(level_xpos, level_ypos); - AdjustScrollbar(gi, gs->items_max, level_ypos + 1); + ModifyGadget(gi, GDI_SCROLLBAR_ITEM_POSITION, level_ypos + 1, GDI_END); } break; diff --git a/src/tools.c b/src/tools.c index b1adf481..5bc49709 100644 --- a/src/tools.c +++ b/src/tools.c @@ -126,9 +126,11 @@ void BackToFront() if (redraw_mask & REDRAW_FIELD) { if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER) + { XCopyArea(display,backbuffer,window,gc, REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE, REAL_SX,REAL_SY); + } else { int fx = FX, fy = FY; @@ -1682,8 +1684,6 @@ boolean Request(char *text, unsigned int req_state) text += tl + (tc == 32 ? 1 : 0); } - - #if 0 if (req_state & REQ_ASK) { @@ -1727,8 +1727,6 @@ boolean Request(char *text, unsigned int req_state) #endif - - OpenDoor(DOOR_OPEN_1); ClearEventQueue(); @@ -1756,7 +1754,10 @@ boolean Request(char *text, unsigned int req_state) case ButtonRelease: case MotionNotify: { + +#if 0 int choice; +#endif if (event.type == MotionNotify) { @@ -2087,7 +2088,15 @@ unsigned int MoveDoor(unsigned int door_state) redraw_mask |= REDRAW_DOOR_2; } + + +#if 1 BackToFront(); +#else + XCopyArea(display, drawto, window, gc, DX, DY, DXSIZE, DYSIZE, DX, DY); +#endif + + if (game_status == MAINMENU) DoAnimation();