From 3f3ea56ee7a6b0818aa916a44afd5127d99d4f42 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Fri, 15 Jan 1999 03:44:50 +0100 Subject: [PATCH] rnd-19990115-1 --- src/buttons.c | 126 +++++++++++++++++---- src/buttons.h | 18 +-- src/editor.c | 307 ++++++++++++++++++++++++++++++++++++-------------- src/main.h | 1 + src/screens.c | 3 +- 5 files changed, 338 insertions(+), 117 deletions(-) diff --git a/src/buttons.c b/src/buttons.c index 45967348..228072e0 100644 --- a/src/buttons.c +++ b/src/buttons.c @@ -1619,7 +1619,27 @@ struct GadgetInfo *CreateGadget(int first_tag, ...) break; case GDI_NUMBER_VALUE: - new_gadget->number_value = va_arg(ap, long); + 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); + 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) + { + new_gadget->text.number_value = new_gadget->text.number_min; + sprintf(new_gadget->text.value, "%d", new_gadget->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) + { + new_gadget->text.number_value = new_gadget->text.number_max; + sprintf(new_gadget->text.value, "%d", new_gadget->text.number_value); + } break; case GDI_TEXT_VALUE: @@ -1823,6 +1843,26 @@ void FreeGadget(struct GadgetInfo *gi) #define DG_BUFFERED 0 #define DG_DIRECT 1 +static void CheckRangeOfNumericInputGadget(struct GadgetInfo *gi) +{ + if (gi->type != GD_TYPE_TEXTINPUT_NUMERIC) + return; + + gi->text.number_value = atoi(gi->text.value); + + if (gi->text.number_value < gi->text.number_min) + gi->text.number_value = gi->text.number_min; + if (gi->text.number_value > gi->text.number_max) + gi->text.number_value = gi->text.number_max; + + sprintf(gi->text.value, "%d", gi->text.number_value); + + if (gi->text.cursor_position < 0) + gi->text.cursor_position = 0; + else if (gi->text.cursor_position > strlen(gi->text.value)) + gi->text.cursor_position = strlen(gi->text.value); +} + static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) { int state = (pressed ? 1 : 0); @@ -1838,13 +1878,14 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) gd->x, gd->y, gi->width, gi->height, gi->x, gi->y); break; - case GD_TYPE_TEXTINPUT: + 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 = (pressed ? FC_YELLOW : FC_GREEN); + int font_color = FC_YELLOW; int border = gi->design_border; strcpy(text, gi->text.value); strcat(text, " "); @@ -2010,21 +2051,52 @@ void AdjustScrollbar(struct GadgetInfo *gi, int items_max, int item_pos) 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; void MapGadget(struct GadgetInfo *gi) { - if (gi == NULL) + if (gi == NULL || gi->mapped) return; gi->mapped = TRUE; - DrawGadget(gi, (gi->state == GD_BUTTON_PRESSED), DG_BUFFERED); + DrawGadget(gi, DG_UNPRESSED, DG_BUFFERED); } void UnmapGadget(struct GadgetInfo *gi) { - if (gi == NULL) + if (gi == NULL || !gi->mapped) return; gi->mapped = FALSE; @@ -2071,8 +2143,8 @@ void HandleGadgets(int mx, int my, int button) last_mx = mx; last_my = my; - /* special treatment for text input gadgets */ - if (last_gi && last_gi->type == GD_TYPE_TEXTINPUT && last_gi->mapped && + /* special treatment for text and number input gadgets */ + if (last_gi && last_gi->type & GD_TYPE_TEXTINPUT && last_gi->mapped && button != 0 && !motion_status) { struct GadgetInfo *gi = last_gi; @@ -2092,6 +2164,7 @@ void HandleGadgets(int mx, int my, int button) else { /* if mouse button pressed outside text input gadget, deactivate it */ + CheckRangeOfNumericInputGadget(gi); DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); if (gi->event_mask & GD_EVENT_TEXT_LEAVING) @@ -2127,23 +2200,27 @@ void HandleGadgets(int mx, int my, int button) (gi->type == GD_TYPE_SCROLLBAR_HORIZONTAL ? mx - gi->x : my - gi->y); /* if mouse button released, no gadget needs to be handled anymore */ - if (button == 0 && last_gi && last_gi->type != GD_TYPE_TEXTINPUT) + if (button == 0 && last_gi && !(last_gi->type & GD_TYPE_TEXTINPUT)) last_gi = NULL; - if (new_gi) + /* modify event position values even if no gadget is pressed */ + if (button == 0 && !release_event) + gi = new_gi; + + if (gi) { - int last_x = new_gi->event.x; - int last_y = new_gi->event.y; + int last_x = gi->event.x; + int last_y = gi->event.y; - new_gi->event.x = mx - new_gi->x; - new_gi->event.y = my - new_gi->y; + gi->event.x = mx - gi->x; + gi->event.y = my - gi->y; - if (new_gi->type == GD_TYPE_DRAWING_AREA) + if (gi->type == GD_TYPE_DRAWING_AREA) { - new_gi->event.x /= new_gi->drawing.item_xsize; - new_gi->event.y /= new_gi->drawing.item_ysize; + gi->event.x /= gi->drawing.item_xsize; + gi->event.y /= gi->drawing.item_ysize; - if (last_x != new_gi->event.x || last_y != new_gi->event.y) + if (last_x != gi->event.x || last_y != gi->event.y) changed_position = TRUE; } } @@ -2154,7 +2231,7 @@ void HandleGadgets(int mx, int my, int button) { last_info_gi = new_gi; - if (new_gi != NULL) + if (new_gi != NULL && (button == 0 || new_gi == last_gi)) { new_gi->event.type = 0; new_gi->callback_info(new_gi); @@ -2313,7 +2390,7 @@ void HandleGadgets(int mx, int my, int button) if (gadget_released_inside) { - if (gi->type != GD_TYPE_TEXTINPUT) + if (!(gi->type & GD_TYPE_TEXTINPUT)) DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); gi->state = GD_BUTTON_UNPRESSED; @@ -2343,15 +2420,19 @@ void HandleGadgetsKeyInput(KeySym key) int text_length; int cursor_pos; char letter; + boolean legal_letter; - if (gi == NULL || gi->type != GD_TYPE_TEXTINPUT || !gi->mapped) + if (gi == NULL || !(gi->type & GD_TYPE_TEXTINPUT) || !gi->mapped) return; text_length = strlen(gi->text.value); cursor_pos = gi->text.cursor_position; letter = getCharFromKeySym(key); + legal_letter = (gi->type == GD_TYPE_TEXTINPUT_NUMERIC ? + letter >= '0' && letter <= '9' : + letter != 0); - if (letter && text_length < gi->text.size) + if (legal_letter && text_length < gi->text.size) { strcpy(text, gi->text.value); strcpy(&gi->text.value[cursor_pos + 1], &text[cursor_pos]); @@ -2384,6 +2465,7 @@ void HandleGadgetsKeyInput(KeySym key) } else if (key == XK_Return) { + CheckRangeOfNumericInputGadget(gi); DrawGadget(gi, DG_UNPRESSED, DG_DIRECT); if (gi->event_mask & GD_EVENT_TEXT_RETURN) diff --git a/src/buttons.h b/src/buttons.h index 65d09fcb..f473b877 100644 --- a/src/buttons.h +++ b/src/buttons.h @@ -278,17 +278,17 @@ int CheckCountButtons(int, int, int); #define GD_TYPE_NORMAL_BUTTON (1 << 0) #define GD_TYPE_RADIO_BUTTON (1 << 1) #define GD_TYPE_DRAWING_AREA (1 << 2) -#define GD_TYPE_TEXTINPUT (1 << 3) -#define GD_TYPE_TEXTOUTPUT (1 << 4) -#define GD_TYPE_NUMBERINPUT (1 << 5) -#define GD_TYPE_NUMBEROUTPUT (1 << 6) -#define GD_TYPE_SCROLLBAR_VERTICAL (1 << 7) -#define GD_TYPE_SCROLLBAR_HORIZONTAL (1 << 8) +#define GD_TYPE_TEXTINPUT_ALPHANUMERIC (1 << 3) +#define GD_TYPE_TEXTINPUT_NUMERIC (1 << 4) +#define GD_TYPE_SCROLLBAR_VERTICAL (1 << 5) +#define GD_TYPE_SCROLLBAR_HORIZONTAL (1 << 6) #define GD_TYPE_BUTTON (GD_TYPE_NORMAL_BUTTON | \ GD_TYPE_RADIO_BUTTON) #define GD_TYPE_SCROLLBAR (GD_TYPE_SCROLLBAR_VERTICAL | \ GD_TYPE_SCROLLBAR_HORIZONTAL) +#define GD_TYPE_TEXTINPUT (GD_TYPE_TEXTINPUT_ALPHANUMERIC | \ + GD_TYPE_TEXTINPUT_NUMERIC) /* gadget events */ #define GD_EVENT_PRESSED (1 << 0) @@ -364,6 +364,9 @@ struct GadgetDrawingArea struct GadgetTextInput { char value[MAX_GADGET_TEXTSIZE]; /* text string in input field */ + int number_value; /* integer value, if numeric */ + int number_min; /* minimal allowed numeric value */ + int number_max; /* maximal allowed numeric value */ int size; /* maximal size of input text */ int cursor_position; /* actual cursor position */ }; @@ -392,7 +395,6 @@ struct GadgetInfo int radio_nr; /* number of radio button series */ boolean radio_pressed; /* radio button state */ boolean mapped; /* gadget is active */ - long number_value; struct GadgetDesign design[2]; /* 0: normal; 1: pressed */ struct GadgetDesign alt_design[2]; /* alternative design */ int design_border; /* border size of gadget decoration */ @@ -411,6 +413,8 @@ void FreeGadget(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 faeca9b6..7312964b 100644 --- a/src/editor.c +++ b/src/editor.c @@ -49,7 +49,12 @@ #define RANDOM_USE_PERCENTAGE 0 #define RANDOM_USE_NUM_OBJECTS 1 +/* values for elements with score */ +#define MIN_SCORE 0 +#define MAX_SCORE 255 + /* values for elements with content */ +#define MIN_ELEMCONT 1 #define MAX_ELEMCONT 8 /* values for the control window */ @@ -83,6 +88,10 @@ #define ED_COUNT_ELEMCONT_XPOS ED_PROPERTIES_XPOS #define ED_COUNT_ELEMCONT_YPOS (17 * MINI_TILEY) +/* standard distances */ +#define ED_BORDER_SIZE 3 +#define ED_GADGET_DISTANCE 2 + /* values for element content drawing areas */ #define ED_AREA_ELEMCONT_XPOS (TILEX) #define ED_AREA_ELEMCONT_YPOS (10 * TILEY) @@ -141,32 +150,40 @@ /* counter button identifiers */ #define ED_CTRL_ID_SCORE_DOWN 22 -#define ED_CTRL_ID_SCORE_UP 23 -#define ED_CTRL_ID_ELEMCONT_DOWN 24 -#define ED_CTRL_ID_ELEMCONT_UP 25 +#define ED_CTRL_ID_SCORE_TEXT 23 +#define ED_CTRL_ID_SCORE_UP 24 +#define ED_CTRL_ID_ELEMCONT_DOWN 25 +#define ED_CTRL_ID_ELEMCONT_TEXT 26 +#define ED_CTRL_ID_ELEMCONT_UP 27 /* drawing area identifiers */ -#define ED_CTRL_ID_DRAWING_LEVEL 26 -#define ED_CTRL_ID_ELEMCONT_0 27 -#define ED_CTRL_ID_ELEMCONT_7 34 -#define ED_CTRL_ID_AMOEBA_CONTENT 35 +#define ED_CTRL_ID_DRAWING_LEVEL 28 +#define ED_CTRL_ID_ELEMCONT_0 29 +#define ED_CTRL_ID_ELEMCONT_1 30 +#define ED_CTRL_ID_ELEMCONT_2 31 +#define ED_CTRL_ID_ELEMCONT_3 32 +#define ED_CTRL_ID_ELEMCONT_4 33 +#define ED_CTRL_ID_ELEMCONT_5 34 +#define ED_CTRL_ID_ELEMCONT_6 35 +#define ED_CTRL_ID_ELEMCONT_7 36 +#define ED_CTRL_ID_AMOEBA_CONTENT 37 /* text input identifiers */ -#define ED_CTRL_ID_LEVEL_NAME 36 +#define ED_CTRL_ID_LEVEL_NAME 38 /* gadgets for scrolling of drawing area */ -#define ED_CTRL_ID_SCROLL_UP 37 -#define ED_CTRL_ID_SCROLL_DOWN 38 -#define ED_CTRL_ID_SCROLL_LEFT 39 -#define ED_CTRL_ID_SCROLL_RIGHT 40 -#define ED_CTRL_ID_SCROLL_VERTICAL 41 -#define ED_CTRL_ID_SCROLL_HORIZONTAL 42 +#define ED_CTRL_ID_SCROLL_UP 39 +#define ED_CTRL_ID_SCROLL_DOWN 40 +#define ED_CTRL_ID_SCROLL_LEFT 41 +#define ED_CTRL_ID_SCROLL_RIGHT 42 +#define ED_CTRL_ID_SCROLL_VERTICAL 43 +#define ED_CTRL_ID_SCROLL_HORIZONTAL 44 -#define ED_NUM_GADGETS 43 +#define ED_NUM_GADGETS 45 /* values for counter gadgets */ -#define ED_COUNTER_SCORE 0 -#define ED_COUNTER_ELEMCONT 1 +#define ED_COUNTER_ID_SCORE 0 +#define ED_COUNTER_ID_ELEMCONT 1 #define ED_NUM_COUNTERBUTTONS 2 #define ED_NUM_SCROLLBUTTONS 4 @@ -206,14 +223,29 @@ static struct { 'E', "exit level editor" } }; +/* pointers to counter values */ +static int *gadget_score_value = NULL; +static int *gadget_areas_value = NULL; + static struct { int x, y; - int gadget_id; + int **counter_value; + int min_value, max_value; + int gadget_id_down, gadget_id_up; + int gadget_id_text; } counterbutton_info[ED_NUM_COUNTERBUTTONS] = { - { ED_COUNT_SCORE_XPOS, ED_COUNT_SCORE_YPOS, ED_CTRL_ID_SCORE_DOWN }, - { ED_COUNT_ELEMCONT_XPOS, ED_COUNT_ELEMCONT_YPOS, ED_CTRL_ID_ELEMCONT_DOWN } + { ED_COUNT_SCORE_XPOS, ED_COUNT_SCORE_YPOS, + &gadget_score_value, + MIN_SCORE, MAX_SCORE, + ED_CTRL_ID_SCORE_DOWN, ED_CTRL_ID_SCORE_UP, + ED_CTRL_ID_SCORE_TEXT }, + { ED_COUNT_ELEMCONT_XPOS, ED_COUNT_ELEMCONT_YPOS, + &gadget_areas_value, + MIN_ELEMCONT, MAX_ELEMCONT, + ED_CTRL_ID_ELEMCONT_DOWN, ED_CTRL_ID_ELEMCONT_UP, + ED_CTRL_ID_ELEMCONT_TEXT } }; static struct @@ -306,10 +338,6 @@ static int random_placement_method = RANDOM_USE_PERCENTAGE; static int random_placement_method = RANDOM_USE_NUM_OBJECTS; #endif -/* pointer to score value */ -static int *gadget_score_value; -static int *gadget_areas_value; - static int level_xpos,level_ypos; static int edit_mode; static boolean name_typing; @@ -856,17 +884,23 @@ static void CreateControlButtons() static void CreateCounterButtons() { - int i, j; + int i; for (i=0; iwidth + ED_GADGET_DISTANCE; /* xpos of text count button */ + + if (j == 0) + { + id = counterbutton_info[i].gadget_id_text; + event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; + + gd_x = DOOR_GFX_PAGEX4 + ED_WIN_COUNT_XPOS; + gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT_YPOS; + + gi = CreateGadget(GDI_CUSTOM_ID, id, + GDI_X, xpos, + GDI_Y, ypos, + GDI_TYPE, GD_TYPE_TEXTINPUT_NUMERIC, + GDI_NUMBER_VALUE, 0, + GDI_NUMBER_MIN, counterbutton_info[i].min_value, + GDI_NUMBER_MAX, counterbutton_info[i].max_value, + GDI_TEXT_SIZE, 3, + GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x, gd_y, + GDI_DESIGN_PRESSED, gd_pixmap, gd_x, gd_y, + GDI_DESIGN_BORDER, ED_BORDER_SIZE, + GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_ACTION, HandleCounterButtons, + GDI_END); + + if (gi == NULL) + Error(ERR_EXIT, "cannot create gadget"); + + level_editor_gadget[id] = gi; + xpos += gi->width + ED_GADGET_DISTANCE; /* xpos of up count button */ + } } } } @@ -979,21 +1044,22 @@ static void CreateTextInputGadgets() unsigned long event_mask; int id; + event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; + gd_x = DOOR_GFX_PAGEX4 + ED_WIN_COUNT_XPOS; gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT_YPOS; - event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; /* text input gadget for the level name */ id = ED_CTRL_ID_LEVEL_NAME; gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_X, SX + ED_COUNT_ELEMCONT_XPOS, GDI_Y, SY + ED_AREA_ELEMCONT_YPOS + 3 * TILEX, - GDI_TYPE, GD_TYPE_TEXTINPUT, + GDI_TYPE, GD_TYPE_TEXTINPUT_ALPHANUMERIC, GDI_TEXT_VALUE, level.name, GDI_TEXT_SIZE, 30, GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x, gd_y, GDI_DESIGN_PRESSED, gd_pixmap, gd_x, gd_y, - GDI_DESIGN_BORDER, 3, + GDI_DESIGN_BORDER, ED_BORDER_SIZE, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_ACTION, HandleTextInputGadgets, GDI_END); @@ -1050,7 +1116,7 @@ static void CreateScrollbarGadgets() GDI_STATE, GD_BUTTON_UNPRESSED, GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y1, GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y2, - GDI_DESIGN_BORDER, 3, + GDI_DESIGN_BORDER, ED_BORDER_SIZE, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_ACTION, HandleControlButtons, GDI_END); @@ -1084,12 +1150,11 @@ static void MapControlButtons() MapGadget(level_editor_gadget[i]); } -static void MapCounterButtons(int id) +static void MapCounterButtons(int cnt_id) { - int i; - - for (i=0; i<2; i++) - MapGadget(level_editor_gadget[counterbutton_info[id].gadget_id + i]); + MapGadget(level_editor_gadget[counterbutton_info[cnt_id].gadget_id_down]); + MapGadget(level_editor_gadget[counterbutton_info[cnt_id].gadget_id_text]); + MapGadget(level_editor_gadget[counterbutton_info[cnt_id].gadget_id_up]); } static void MapDrawingArea(int id) @@ -1140,8 +1205,6 @@ void DrawLevelEd() { int i, x, y, graphic; - level_xpos = -1; - level_ypos = -1; edit_mode = ED_MODE_DRAWING; name_typing = FALSE; @@ -1163,6 +1226,8 @@ void DrawLevelEd() } else { + level_xpos = -1; + level_ypos = -1; undo_buffer_position = -1; undo_buffer_steps = -1; CopyLevelToUndoBuffer(UNDO_IMMEDIATE); @@ -1447,18 +1512,19 @@ void AdjustLevelScrollPosition() void AdjustEditorScrollbar(int id) { struct GadgetInfo *gi = level_editor_gadget[id]; - struct GadgetScrollbar *gs = &gi->scrollbar; - int items_max, items_visible, item_position = gs->item_position; + int items_max, items_visible, item_position; if (id == ED_CTRL_ID_SCROLL_HORIZONTAL) { items_max = lev_fieldx + 2; items_visible = ED_FIELDX; + item_position = level_xpos + 1; } else { items_max = lev_fieldy + 2; items_visible = ED_FIELDY; + item_position = level_ypos + 1; } if (item_position > items_max - items_visible) @@ -1467,6 +1533,25 @@ void AdjustEditorScrollbar(int id) AdjustScrollbar(gi, items_max, item_position); } +void ModifyEditorTextInput(int gadget_id, char *new_text) +{ + struct GadgetInfo *gi = level_editor_gadget[gadget_id]; + + ModifyTextInputTextValue(gi, new_text); +} + +void ModifyEditorCounter(int counter_id, int new_value) +{ + int *counter_value = *counterbutton_info[counter_id].counter_value; + int gadget_id = counterbutton_info[counter_id].gadget_id_text; + struct GadgetInfo *gi = level_editor_gadget[gadget_id]; + + ModifyTextInputNumberValue(gi, new_value); + + if (counter_value != NULL) + *counter_value = gi->text.number_value; +} + static void PickDrawingElement(int button, int element) { if (button < 1 || button > 3) @@ -2203,12 +2288,13 @@ static void DrawElementContentAreas() /* display counter to choose number of element content areas */ gadget_areas_value = num_areas; - DrawCounterValueField(ED_COUNTER_ELEMCONT, *gadget_areas_value); - x = counterbutton_info[ED_COUNTER_ELEMCONT].x + DXSIZE; - y = counterbutton_info[ED_COUNTER_ELEMCONT].y; + DrawCounterValueField(ED_COUNTER_ID_ELEMCONT, *gadget_areas_value); + x = counterbutton_info[ED_COUNTER_ID_ELEMCONT].x + DXSIZE; + y = counterbutton_info[ED_COUNTER_ID_ELEMCONT].y; DrawTextF(x + ED_COUNT_VALUE_XOFFSET, y + ED_COUNT_VALUE_YOFFSET, FC_YELLOW, "number of content areas"); - MapCounterButtons(ED_COUNTER_ELEMCONT); + ModifyEditorCounter(ED_COUNTER_ID_ELEMCONT, *gadget_areas_value); + MapCounterButtons(ED_COUNTER_ID_ELEMCONT); /* delete content areas in case of reducing number of them */ XFillRectangle(display, backbuffer, gc, @@ -2387,14 +2473,19 @@ static void DrawPropertiesWindow() { if (elements_with_counter[i].element == properties_element) { - int x = counterbutton_info[ED_COUNTER_SCORE].x + DXSIZE; - int y = counterbutton_info[ED_COUNTER_SCORE].y; + int x = counterbutton_info[ED_COUNTER_ID_SCORE].x + DXSIZE; + int y = counterbutton_info[ED_COUNTER_ID_SCORE].y; gadget_score_value = elements_with_counter[i].counter_value; - DrawCounterValueField(ED_COUNTER_SCORE, *gadget_score_value); + + /* + DrawCounterValueField(ED_COUNTER_ID_SCORE, *gadget_score_value); + */ + DrawTextF(x + ED_COUNT_VALUE_XOFFSET, y + ED_COUNT_VALUE_YOFFSET, FC_YELLOW, elements_with_counter[i].text); - MapCounterButtons(ED_COUNTER_SCORE); + ModifyEditorCounter(ED_COUNTER_ID_SCORE, *gadget_score_value); + MapCounterButtons(ED_COUNTER_ID_SCORE); break; } } @@ -2633,7 +2724,8 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, if (mode != CB_DELETE_OLD_CURSOR && delete_old_brush) CopyBrushExt(0, 0, 0, 0, 0, CB_DELETE_OLD_CURSOR); - if (!IN_LEV_FIELD(cursor_x + level_xpos, cursor_y + level_ypos)) + if (!IN_ED_FIELD(cursor_x, cursor_y) || + !IN_LEV_FIELD(cursor_x + level_xpos, cursor_y + level_ypos)) { delete_old_brush = FALSE; return; @@ -2652,8 +2744,7 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, mode == CB_BRUSH_TO_CURSOR || button == 1 ? brush_buffer[x][y] : new_element); - if (IN_LEV_FIELD(lx, ly) && - sx >=0 && sx < ED_FIELDX && sy >=0 && sy < ED_FIELDY) + if (IN_ED_FIELD(sx, sy) && IN_LEV_FIELD(lx, ly)) { if (sx < border_from_x) border_from_x = sx; @@ -3017,6 +3108,13 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) button == 2 ? new_element2 : button == 3 ? new_element3 : 0); + + + if (button_release_event) + button = 0; + + + if (!draw_level && drawing_function != ED_CTRL_ID_SINGLE_ITEMS) return; @@ -3026,8 +3124,14 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (draw_level) { if (button_release_event) + { CopyLevelToUndoBuffer(UNDO_IMMEDIATE); + if (edit_mode == ED_MODE_DRAWING && draw_with_brush && + !inside_drawing_area) + DeleteBrushFromCursor(); + } + if (!button) break; @@ -3202,24 +3306,21 @@ static void HandleCounterButtons(struct GadgetInfo *gi) { case ED_CTRL_ID_SCORE_DOWN: case ED_CTRL_ID_SCORE_UP: - *gadget_score_value += (id == ED_CTRL_ID_SCORE_DOWN ? -step : step); - if (*gadget_score_value < 0) - *gadget_score_value = 0; - else if (*gadget_score_value > 255) - *gadget_score_value = 255; - - DrawCounterValueField(ED_COUNTER_SCORE, *gadget_score_value); + step *= (id == ED_CTRL_ID_SCORE_DOWN ? -1 : 1); + ModifyEditorCounter(ED_COUNTER_ID_SCORE, *gadget_score_value + step); + break; + case ED_CTRL_ID_SCORE_TEXT: + *gadget_score_value = gi->text.number_value; break; case ED_CTRL_ID_ELEMCONT_DOWN: case ED_CTRL_ID_ELEMCONT_UP: - *gadget_areas_value += (id == ED_CTRL_ID_ELEMCONT_DOWN ? -step : step); - if (*gadget_areas_value < 1) - *gadget_areas_value = 1; - else if (*gadget_areas_value > MAX_ELEMCONT) - *gadget_areas_value = MAX_ELEMCONT; - - DrawCounterValueField(ED_COUNTER_ELEMCONT, *gadget_areas_value); + step *= (id == ED_CTRL_ID_ELEMCONT_DOWN ? -1 : 1); + ModifyEditorCounter(ED_COUNTER_ID_ELEMCONT, *gadget_areas_value + step); + DrawElementContentAreas(); + break; + case ED_CTRL_ID_ELEMCONT_TEXT: + *gadget_areas_value = gi->text.number_value; DrawElementContentAreas(); break; @@ -3228,6 +3329,21 @@ static void HandleCounterButtons(struct GadgetInfo *gi) } } +static void HandleTextInputGadgets(struct GadgetInfo *gi) +{ + int id = gi->custom_id; + + switch (id) + { + case ED_CTRL_ID_LEVEL_NAME: + strcpy(level.name, gi->text.value); + break; + + default: + break; + } +} + static void HandleControlButtons(struct GadgetInfo *gi) { int id = gi->custom_id; @@ -3623,21 +3739,6 @@ void HandleLevelEditorKeyInput(KeySym key) } } -static void HandleTextInputGadgets(struct GadgetInfo *gi) -{ - int id = gi->custom_id; - - switch (id) - { - case ED_CTRL_ID_LEVEL_NAME: - strcpy(level.name, gi->text.value); - break; - - default: - break; - } -} - /* values for ClearEditorGadgetInfoText() and HandleGadgetInfoText() */ #define INFOTEXT_XPOS SX #define INFOTEXT_YPOS (SY + SYSIZE - MINI_TILEX + 2) @@ -3677,7 +3778,9 @@ void HandleEditorGadgetInfoText(void *ptr) if (key) { sprintf(shortcut, " ('%s%c')", - (key >= 'A' && key <= 'Z' ? "Shift-" : ""), key); + (key >= 'A' && key <= 'Z' ? "Shift-" : + gi->custom_id == ED_CTRL_ID_SINGLE_ITEMS ? ".' or '" : ""), + key); if (strlen(infotext) + strlen(shortcut) <= MAX_INFOTEXT_LEN) strcat(infotext, shortcut); @@ -3701,9 +3804,34 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) if (id == ED_CTRL_ID_DRAWING_LEVEL) { - if (IN_LEV_FIELD(lx, ly)) + if (button_status) { - if (gi->state == GD_BUTTON_PRESSED) + int min_sx = 0, min_sy = 0; + int max_sx = gi->drawing.area_xsize - 1; + int max_sy = gi->drawing.area_ysize - 1; + int min_lx = 0, min_ly = 0; + int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1; + + /* make sure to stay inside drawing area boundaries */ + sx = (sx < min_sx ? min_sx : sx > max_sx ? max_sx : sx); + sy = (sy < min_sy ? min_sy : sy > max_sy ? max_sy : sy); + + /* get positions inside level field */ + lx = sx + level_xpos; + ly = sy + level_ypos; + + /* 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); + + /* correct drawing area positions accordingly */ + sx = lx - level_xpos; + sy = ly - level_ypos; + } + + if (IN_ED_FIELD(sx,sy) && IN_LEV_FIELD(lx, ly)) + { + if (button_status) /* if (gi->state == GD_BUTTON_PRESSED) */ { if (gi->event.type == GD_EVENT_PRESSED) { @@ -3757,8 +3885,13 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) } /* misuse this function to draw brush cursor, if needed */ - if (edit_mode == ED_MODE_DRAWING && draw_with_brush) - CopyBrushToCursor(sx, sy); + if (edit_mode == ED_MODE_DRAWING && draw_with_brush && !button_status) + { + if (IN_ED_FIELD(sx,sy) && IN_LEV_FIELD(lx, ly)) + CopyBrushToCursor(sx, sy); + else + DeleteBrushFromCursor(); + } } else if (id == ED_CTRL_ID_AMOEBA_CONTENT) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW, diff --git a/src/main.h b/src/main.h index d7680843..84fa41ea 100644 --- a/src/main.h +++ b/src/main.h @@ -96,6 +96,7 @@ typedef unsigned char byte; #define IN_VIS_FIELD(x,y) ((x)>=0 && (x)=0 &&(y)=BX1 && (x)<=BX2 && (y)>=BY1 &&(y)<=BY2) #define IN_LEV_FIELD(x,y) ((x)>=0 && (x)=0 &&(y)=0 && (x)=0 &&(y)