23#include "land_outfits.h"
24#include "nlua_colour.h"
26#include "nlua_outfit.h"
31#define TK_CUSTNAME "__cstdlg"
32#define TK_CUSTOMDONE "__customDone"
33typedef struct custom_functions_s {
46static int cust_update(
double dt,
void *data );
47static void cust_render(
double x,
double y,
double w,
double h,
void *data );
48static int cust_event(
unsigned int wid, SDL_Event *event,
void *data );
49static int cust_key( SDL_Keycode key, SDL_Keymod mod,
int pressed,
int isrepeat,
52static int cust_mouse(
int type,
int button,
double x,
double y,
54static int cust_event_window( SDL_WindowEventID event, Sint32 w, Sint32 h,
60static int tkL_msg( lua_State *L );
151 const char *wdwname, *wgtname;
153 int bx, by, x, y, w, h;
154 wdwname = luaL_checkstring( L, 1 );
155 wgtname = luaL_optstring( L, 2, NULL );
160 if ( wgtname == NULL ) {
170 lua_pushinteger( L, x );
171 lua_pushinteger( L, y );
172 lua_pushinteger( L, w );
173 lua_pushinteger( L, h );
195 const char *title = luaL_checkstring( L, 1 );
196 const char *str = luaL_checkstring( L, 2 );
198 if ( lua_gettop( L ) > 2 ) {
200 const char *img = luaL_checkstring( L, 3 );
203 width = ( lua_gettop( L ) < 4 ) ? -1 : luaL_checkinteger( L, 4 );
204 height = ( lua_gettop( L ) < 5 ) ? -1 : luaL_checkinteger( L, 5 );
225 const char *title = luaL_checkstring( L, 1 );
226 const char *str = luaL_checkstring( L, 2 );
229 lua_pushboolean( L, ret );
248 const char *title, *str;
252 title = luaL_checkstring( L, 1 );
253 min = luaL_checkint( L, 2 );
254 max = luaL_checkint( L, 3 );
255 str = luaL_checkstring( L, 4 );
259 lua_pushstring( L, ret );
282 const char *title, *str;
286 opts = lua_gettop( L ) - 2;
287 title = luaL_checkstring( L, 1 );
288 str = luaL_checkstring( L, 2 );
291 for (
int i = 0; i < opts; i++ )
292 luaL_checkstring( L, i + 3 );
296 for (
int i = 0; i < opts; i++ )
299 if ( result == NULL )
304 for (
int i = 0; i < opts && ret == -1; i++ ) {
305 if ( strcmp( result, luaL_checkstring( L, i + 3 ) ) == 0 )
310 lua_pushnumber( L, ret );
311 lua_pushstring( L, result );
335 const char *title, *str;
340 opts = lua_gettop( L ) - 2;
341 title = luaL_checkstring( L, 1 );
342 str = luaL_checkstring( L, 2 );
345 for (
int i = 0; i < opts; i++ )
346 luaL_checkstring( L, i + 3 );
349 choices = malloc(
sizeof(
char * ) * opts );
350 for (
int i = 0; i < opts; i++ )
351 choices[i] = strdup( luaL_checkstring( L, i + 3 ) );
360 lua_pushnumber( L, ret + 1 );
361 lua_pushstring( L, choices[ret] );
388 name = luaL_checkstring( L, 1 );
390 if ( !lua_istable( L, 2 ) )
391 NLUA_INVALID_PARAMETER( L, 2 );
396 while ( lua_next( L, -2 ) != 0 ) {
402 if ( SCREEN_W < LAND_WIDTH || SCREEN_H < LAND_HEIGHT ) {
406 w = LAND_WIDTH + 0.5 * ( SCREEN_W - LAND_WIDTH );
407 h = LAND_HEIGHT + 0.5 * ( SCREEN_H - LAND_HEIGHT );
409 wid =
window_create(
"wdwMerchantOutfit", name, -1, -1, w, h );
421 lua_State *L = cf->
L;
422 luaL_unref( L, LUA_REGISTRYINDEX, cf->update );
423 luaL_unref( L, LUA_REGISTRYINDEX, cf->draw );
424 luaL_unref( L, LUA_REGISTRYINDEX, cf->keyboard );
425 luaL_unref( L, LUA_REGISTRYINDEX, cf->mouse );
426 luaL_unref( L, LUA_REGISTRYINDEX, cf->resize );
427 luaL_unref( L, LUA_REGISTRYINDEX, cf->textinput );
428 luaL_unref( L, LUA_REGISTRYINDEX, cf->
env );
455 int w = luaL_checkinteger( L, 2 );
456 int h = luaL_checkinteger( L, 3 );
457 const char *caption = luaL_checkstring( L, 1 );
460 char *buf, dlgname[STRMAX_SHORT];
466 cf->
env = luaL_ref( L, LUA_REGISTRYINDEX );
467#define GETFUNC( address, pos ) \
469 lua_pushvalue( L, ( pos ) ); \
470 luaL_checktype( L, -1, LUA_TFUNCTION ); \
471 ( address ) = luaL_ref( L, LUA_REGISTRYINDEX ); \
473 GETFUNC( cf->update, 4 );
474 GETFUNC( cf->draw, 5 );
475 GETFUNC( cf->keyboard, 6 );
476 GETFUNC( cf->mouse, 7 );
477 GETFUNC( cf->resize, 8 );
478 GETFUNC( cf->textinput, 9 );
480 nodynamic = lua_toboolean( L, 10 );
483 lua_pushboolean( L, 0 );
484 nlua_setenv( L, cf->
env, TK_CUSTOMDONE );
488 nlua_getenv( L, cf->
env, TK_CUSTNAME );
489 if ( lua_isstring( L, -1 ) )
490 buf = strdup( lua_tostring( L, -1 ) );
493 static unsigned int dlgcust_counter = 0;
494 snprintf( dlgname,
sizeof( dlgname ),
"dlgCust%u", ++dlgcust_counter );
495 lua_pushstring( L, dlgname );
496 nlua_setenv( L, cf->
env, TK_CUSTNAME );
507 lua_pushstring( L, buf );
508 nlua_setenv( L, cf->
env, TK_CUSTNAME );
515static unsigned int dlgWid( lua_State *L )
518 unsigned int wid =
window_get( luaL_checkstring( L, -1 ) );
531 const char *s = luaL_checkstring( L, 1 );
532 unsigned int wid = dlgWid( L );
534 return NLUA_ERROR( L, _(
"custom dialogue not open" ) );
547 int enable = lua_toboolean( L, 1 );
548 unsigned int wid = dlgWid( L );
550 return NLUA_ERROR( L, _(
"custom dialogue not open" ) );
565 unsigned int wid = dlgWid( L );
567 return NLUA_ERROR( L, _(
"custom dialogue not open" ) );
568 w = luaL_checkinteger( L, 1 );
569 h = luaL_checkinteger( L, 2 );
584 unsigned int wid = dlgWid( L );
586 return NLUA_ERROR( L, _(
"custom dialogue not open" ) );
588 lua_pushinteger( L, w );
589 lua_pushinteger( L, h );
602 unsigned int wid = dlgWid( L );
604 return NLUA_ERROR( L, _(
"custom dialogue not open" ) );
605 lua_pushboolean( L, 1 );
611static int cust_update(
double dt,
void *data )
617 lua_State *L = cf->
L;
618 lua_rawgeti( L, LUA_REGISTRYINDEX, cf->update );
619 lua_pushnumber( L, dt );
620 if ( nlua_pcall( cf->
env, 1, 0 ) ) {
622 NLUA_WARN( L, _(
"Custom dialogue internal error: %s" ),
623 lua_tostring( L, -1 ) );
628 nlua_getenv( L, cf->
env, TK_CUSTOMDONE );
629 ret = lua_toboolean( L, -1 );
633static void cust_render(
double x,
double y,
double w,
double h,
void *data )
638 lua_State *L = cf->
L;
639 lua_rawgeti( L, LUA_REGISTRYINDEX, cf->draw );
640 lua_pushnumber( L, x );
641 lua_pushnumber( L, y );
642 lua_pushnumber( L, w );
643 lua_pushnumber( L, h );
644 if ( nlua_pcall( cf->
env, 4, 0 ) ) {
646 NLUA_WARN( L, _(
"Custom dialogue internal error: %s" ),
647 lua_tostring( L, -1 ) );
651static int cust_event(
unsigned int wid, SDL_Event *event,
void *data )
660 switch ( event->type ) {
661 case SDL_MOUSEBUTTONDOWN:
664 return cust_mouse( 1, event->button.button, event->button.x + x,
665 event->button.y + y, cf );
666 case SDL_MOUSEBUTTONUP:
669 return cust_mouse( 2, event->button.button, event->button.x + x,
670 event->button.y + y, cf );
671 case SDL_MOUSEMOTION:
674 return cust_mouse( 3, -1, event->button.x + x, event->button.y + y, cf );
676 return cust_mouse( 4, -1, event->wheel.x, event->wheel.y, cf );
679 return cust_key( event->key.keysym.sym, event->key.keysym.mod, 1,
680 event->key.repeat, cf );
682 return cust_key( event->key.keysym.sym, event->key.keysym.mod, 0,
683 event->key.repeat, cf );
686 return cust_text( event->text.text, cf );
688 case SDL_WINDOWEVENT:
689 return cust_event_window( event->window.event, event->window.data1,
690 event->window.data2, cf );
698static int cust_key( SDL_Keycode key, SDL_Keymod mod,
int pressed,
int isrepeat,
702 lua_State *L = cf->
L;
703 lua_rawgeti( L, LUA_REGISTRYINDEX, cf->keyboard );
704 lua_pushboolean( L, pressed );
705 lua_pushstring( L, SDL_GetKeyName( key ) );
707 lua_pushboolean( L, isrepeat );
708 if ( nlua_pcall( cf->
env, 4, 1 ) ) {
710 NLUA_WARN( L, _(
"Custom dialogue internal error: %s" ),
711 lua_tostring( L, -1 ) );
715 b = lua_toboolean( L, -1 );
722 lua_State *L = cf->
L;
723 lua_rawgeti( L, LUA_REGISTRYINDEX, cf->textinput );
724 lua_pushstring( L, str );
725 if ( nlua_pcall( cf->
env, 1, 1 ) ) {
727 NLUA_WARN( L, _(
"Custom dialogue internal error: %s" ),
728 lua_tostring( L, -1 ) );
732 b = lua_toboolean( L, -1 );
736static int cust_mouse(
int type,
int button,
double x,
double y,
740 lua_State *L = cf->
L;
741 lua_rawgeti( L, LUA_REGISTRYINDEX, cf->mouse );
742 lua_pushnumber( L, x );
743 lua_pushnumber( L, y );
744 lua_pushnumber( L, type );
747 case SDL_BUTTON_LEFT:
750 case SDL_BUTTON_RIGHT:
757 lua_pushnumber( L, button );
760 if ( nlua_pcall( cf->
env, nargs, 1 ) ) {
762 NLUA_WARN( L, _(
"Custom dialogue internal error: %s" ),
763 lua_tostring( L, -1 ) );
767 b = lua_toboolean( L, -1 );
771static int cust_event_window( SDL_WindowEventID event, Sint32 w, Sint32 h,
775 lua_State *L = cf->
L;
777 if ( event == SDL_WINDOWEVENT_RESIZED )
780 lua_rawgeti( L, LUA_REGISTRYINDEX, cf->resize );
781 lua_pushinteger( L, w );
782 lua_pushinteger( L, h );
783 if ( nlua_pcall( cf->
env, 2, 1 ) ) {
785 NLUA_WARN( L, _(
"Custom dialogue internal error: %s" ),
786 lua_tostring( L, -1 ) );
790 b = lua_toboolean( L, -1 );
Provides macros to work with dynamic arrays.
#define array_create_size(basic_type, capacity)
Creates a new dynamic array of ‘basic_type’ with an initial capacity.
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
char * dialogue_runChoice(void)
Run the dialog and return the clicked string.
char * dialogue_inputRaw(const char *title, int min, int max, const char *msg)
Creates a dialogue that allows the player to write a message.
void dialogue_custom(const char *wdwname, const char *caption, int width, int height, int(*update)(double dt, void *data), void(*render)(double x, double y, double w, double h, void *data), int(*event)(unsigned int wid, SDL_Event *event, void *data), void *data, int dynamic, void(*freefunc)(void *data))
Opens a custom dialogue window.
int dialogue_customFullscreen(unsigned int wid, int enable)
Converts a custom dialogue to fullscreen.
int dialogue_listRaw(const char *title, char **items, int nitems, const char *msg)
Creates a list dialogue with OK and Cancel button.
int dialogue_YesNoRaw(const char *caption, const char *msg)
Runs a dialogue with both yes and no options.
int dialogue_customResize(unsigned int wid, int width, int height)
Resizes a custom dialogue.
void dialogue_addChoice(const char *caption, const char *msg, const char *opt)
Add a choice to the dialog.
void dialogue_msgImgRaw(const char *caption, const char *msg, const char *img, int width, int height)
Opens a dialogue window with an ok button, a fixed message and an image.
void dialogue_makeChoice(const char *caption, const char *msg, int opts)
Create the choice dialog. Need to add choices with below method.
void dialogue_msgRaw(const char *caption, const char *msg)
Opens a dialogue window with an ok button and a fixed message.
void outfits_open(unsigned int wid, const Outfit **outfits, int blackmarket)
Opens the outfit exchange center window.
Header file with generic functions and naev-specifics.
int nlua_loadCol(nlua_env env)
Loads the colour library.
int nlua_loadGFX(nlua_env env)
Loads the graphics library.
const Outfit * luaL_validoutfit(lua_State *L, int ind)
Makes sure the outfit is valid or raises a Lua error.
static int tkL_customSize(lua_State *L)
Gets the size of a custom widget.
static int tkL_customRename(lua_State *L)
Renames the custom widget window.
static int tkL_isOpen(lua_State *L)
Bindings for interacting with the Toolkit.
static const luaL_Reg tkL_methods[]
static int tkL_msg(lua_State *L)
Creates a window with an ok button, and optionally an image.
int nlua_loadTk(nlua_env env)
Loads the Toolkit Lua library.
static int tkL_input(lua_State *L)
Creates a window that allows player to write text input.
static void cust_cleanup(void *data)
Cleans up after the window.
static int tkL_choice(lua_State *L)
Creates a window with a number of selectable options.
static int tkL_refresh(lua_State *L)
Forces the toolkit to rerender the screen.
static int tkL_query(lua_State *L)
Gets the position and dimensions of either a window or a widget.
static int tkL_yesno(lua_State *L)
Displays a window with Yes and No buttons.
static int tkL_customFullscreen(lua_State *L)
Sets the custom widget fullscreen.
static int tkL_list(lua_State *L)
Creates a window with an embedded list of choices.
static int tkL_customDone(lua_State *L)
Ends the execution of a custom widget.
static int tkL_customResize(lua_State *L)
Sets the custom widget fullscreen.
static int tkL_merchantOutfit(lua_State *L)
Opens an outfit merchant window.
static int tkL_custom(lua_State *L)
Creates a custom widget window.
A ship outfit, depends radically on the type.