192 lines
6.7 KiB
C
192 lines
6.7 KiB
C
/*
|
|
* mtsedit/search.c
|
|
*
|
|
* Copyright (C) 2019 bzt (bztsrc@gitlab)
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person
|
|
* obtaining a copy of this software and associated documentation
|
|
* files (the "Software"), to deal in the Software without
|
|
* restriction, including without limitation the rights to use, copy,
|
|
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
* of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be
|
|
* included in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* @brief Search Block window
|
|
*
|
|
*/
|
|
|
|
#include "main.h"
|
|
|
|
int numresults, *results = NULL, line, overblk = -1, searchscr = 0;
|
|
int searchlen = 0, searchpos = 0;
|
|
char search[256] = { 0 }, cur[2] = {0, 0};
|
|
|
|
/**
|
|
* Redraw the Search Block window
|
|
*/
|
|
void search_redraw()
|
|
{
|
|
int i;
|
|
SDL_Rect rect;
|
|
|
|
rect.x = 36; rect.y = 0; rect.w = screen->w - 36; rect.h = screen->h - font->height;
|
|
SDL_FillRect(screen, &rect, theme[THEME_BG]);
|
|
|
|
strmaxw = screen->w - 5;
|
|
sdlprint((screen->w - 47 - strlen(lang[ADDBLOCKS]) * (font->width+1)) / 2 + 47, 4, THEME_INPUT, THEME_BG, lang[ADDBLOCKS]);
|
|
rect.y = 12 + font->height;
|
|
sdlprint(42, rect.y, THEME_FG, THEME_BG, lang[SEARCH]);
|
|
rect.x = 160; rect.w = screen->w - 165; rect.h = font->height + 2;
|
|
SDL_FillRect(screen, &rect, theme[THEME_INPBG]);
|
|
strmaxw = screen->w - 5;
|
|
sdlprint(161,rect.y + 1, THEME_INPUT, THEME_INPBG, search);
|
|
cur[0] = search[searchpos] ? search[searchpos] : ' ';
|
|
sdlprint(161 + searchpos * (font->width+1), rect.y + 1, THEME_INPBG, THEME_INPUT, cur);
|
|
rect.x = 42; rect.y = 20 + 2*font->height; rect.w = rect.h = 32;
|
|
if(line != (screen->w - 47) / 32) {
|
|
line = (screen->w - 47) / 32;
|
|
searchscr = 0;
|
|
}
|
|
for(i = searchscr * line; i < numresults && rect.y + 32 < (int)(screen->h - font->height); i++, rect.x += 32) {
|
|
if(rect.x + 32 > screen->w - 5) { rect.x = 42; rect.y += 32; }
|
|
if(rect.y + 32 > (int)(screen->h - font->height)) rect.h = screen->h - font->height - rect.y;
|
|
blk->pixels = results[i] > 0 && results[i] < numblocks && blocks[results[i]].img ? blocks[results[i]].img :
|
|
(uint8_t*)icons->pixels + 32 * icons->pitch;
|
|
SDL_FillRect(screen, &rect, theme[i == overblk ? THEME_INACT : THEME_BG]);
|
|
SDL_BlitSurface(blk, NULL, screen, &rect);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Search Block window scrolling event handler
|
|
*/
|
|
void search_scroll(SDL_Event *event)
|
|
{
|
|
int i = numresults / line;
|
|
searchscr -= event->wheel.y;
|
|
if(searchscr < 0) searchscr = 0;
|
|
if(searchscr + 1 >= i) searchscr = i - 1;
|
|
}
|
|
|
|
/**
|
|
* Add a block to the palette
|
|
*/
|
|
void search_addblock(int blk)
|
|
{
|
|
int i, j, b;
|
|
|
|
if(blk != -1 && blk < numresults) {
|
|
b = results[blk];
|
|
if(!b) return;
|
|
for(j = 1; j < 15 && palette[j] != b; j++);
|
|
for(i = j; i > 1; i--) palette[i] = palette[i - 1];
|
|
palette[1] = b;
|
|
activeblock = 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Search Block window mouse down event handler
|
|
*/
|
|
void search_mousedown(_unused SDL_Event *event)
|
|
{
|
|
if(overblk != -1 && overblk < numresults) {
|
|
search_addblock(overblk);
|
|
status = overblk < 0 || overblk >= numresults || results[overblk] < 0 || results[overblk] >= numblocks ? NULL :
|
|
blocks[results[overblk]].name;
|
|
sdlredraw();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Search Block mouse over event handler
|
|
*/
|
|
void search_mouseover(SDL_Event *event)
|
|
{
|
|
int i, j = -1;
|
|
|
|
if(event->motion.x >= 42 && event->motion.x < screen->w - 5) {
|
|
if(event->motion.y >= (int)(20 + 2*font->height) && event->motion.y < (int)(screen->h - font->height)) {
|
|
i = ((event->motion.x - 42) / 32);
|
|
j = (((event->motion.y - (20 + 2*font->height)) / 32 + searchscr) * line) + (i < line ? i : line);
|
|
if(j >= numresults || !results[j]) j = -1;
|
|
}
|
|
}
|
|
if(j != overblk) {
|
|
overblk = j;
|
|
status = j < 0 || j >= numresults || results[j] < 0 || results[j] >= numblocks ? NULL : blocks[results[j]].name;
|
|
sdlredraw();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Search Block window keypress event handler
|
|
*/
|
|
void search_key(SDL_Event *event)
|
|
{
|
|
int i, j, l;
|
|
|
|
switch(event->type) {
|
|
case SDL_TEXTINPUT:
|
|
j = strlen(event->text.text);
|
|
if(!ctrl && searchlen + j < (int)(sizeof(search))) {
|
|
for(i = searchlen - 1; i >= searchpos; i--) search[i + j] = search[i];
|
|
memcpy(search + searchpos, &event->text.text, j);
|
|
searchpos += j;
|
|
searchlen += j;
|
|
search[searchlen] = 0;
|
|
}
|
|
break;
|
|
case SDL_KEYUP:
|
|
switch (event->key.keysym.sym) {
|
|
case SDLK_BACKSPACE:
|
|
if(searchpos) {
|
|
searchpos--;
|
|
for(i = searchpos; i < searchlen + 1; i++) search[i] = search[i+1];
|
|
searchlen--;
|
|
}
|
|
break;
|
|
case SDLK_DELETE:
|
|
if(searchpos < searchlen) {
|
|
for(i = searchpos; i < searchlen + 1; i++) search[i] = search[i+1];
|
|
searchlen--;
|
|
}
|
|
break;
|
|
case SDLK_UP: searchpos = 0; break;
|
|
case SDLK_DOWN: searchpos = searchlen; break;
|
|
case SDLK_LEFT: if(searchpos) searchpos--; break;
|
|
case SDLK_RIGHT: if(searchpos < searchlen) searchpos++; break;
|
|
case SDLK_TAB:
|
|
case SDLK_RETURN: sdldo(-1); break;
|
|
}
|
|
if(ctrl && event->key.keysym.sym >= SDLK_1 && event->key.keysym.sym <= SDLK_9)
|
|
search_addblock(event->key.keysym.sym - SDLK_1);
|
|
break;
|
|
}
|
|
if(!searchlen) {
|
|
numresults = numblocks - 1;
|
|
for(i = 0; (int)i < numresults; i++) results[i] = i + 1;
|
|
} else {
|
|
for(numresults = 0, i = 1; i < numblocks; i++) {
|
|
l = strlen(blocks[i].name) - searchlen;
|
|
for(j = 0; j < l + 1; j++)
|
|
if(!strncasecmp(blocks[i].name + j, search, searchlen)) {
|
|
results[numresults++] = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|