separating golden_array

master
Allen Webster 2015-10-16 16:31:04 -04:00
parent c38d6ce47b
commit 6918ae0be4
12 changed files with 1439 additions and 833 deletions

View File

@ -3,59 +3,148 @@
*/
// NOTE(allen): NEW THINGS TO LOOK FOR:
// MAPID_USER_CUSTOM - define maps other than the built in GLOBAL/FILE maps
// inherit_map
// mapid_user_custom - define maps other than the built in global and file maps
//
// inherit_map - override bindings or add new bindings in a new map with another
//
// set_hook - if you were using start_hook, it is still available if you use set_hook
//
// push_parameter - see description of parameter stack immediately below
// clear_parameters
// exec_command_keep_stack
//
// THE PARAMETER STACK:
// In this version I have introduced a parameter stack.
// Calls to commands through exec_command can now be parameterized
// by first pushing parameters onto that stack. This is achieved through
// the push_parameter. If you look at the signature for the function it
// uses a "Dynamic" struct, but 4coder_helper.h has overrides that accept
// ints or strings. The helper functions also take care of copying the
// strings inline into the stack so that you don't have to maintain your copy.
//
// If you'd like to optimize out the extra copy it will work, just use the
// main app.push_parameter and keep the memory of the string alive until
// the stack is cleared.
//
// A call to exec_command executes the command with the current stack,
// then clears the stack. To keep the stack use exec_command_keep_stack.
//
// If you would like to allocate your own memory, you can tie your memory
// to the parameter stack by calling push_memory which takes a cmd_context and len.
// It will return a char* to your memory block. Until you call clear_parameters
// or exec_command the memory will remain on the stack for you to use. Memory
// chunks on the stack are ignored by commands that use parameters, so your memory
// will not influence the behavior of any commands.
//
// get_settings
#include "4coder_custom.h"
#include "4coder_helper.h"
#define exec_command app.exec_command
#define fulfill_interaction app.fulfill_interaction
#define exec_command_keep_stack app.exec_command_keep_stack
#define clear_parameters app.clear_parameters
#define get_active_buffer app.get_active_buffer
extern "C" START_HOOK_SIG(start_hook){
#define exec_command(cmd_context, id) \
exec_command_keep_stack(cmd_context, id); \
clear_parameters(cmd_context)
#define push_parameter(cmd_context, ...) push_parameter_helper(cmd_context, app, __VA_ARGS__)
#define push_memory(cmd_context, len) app.push_memory(cmd_context, len)
#define literal(s) s, (sizeof(s)-1)
// NOTE(allen): All of your custom ids should be >= mapid_user_custom.
// I recommend enumerating your own map ids as shown here.
enum My_Maps{
my_code_map = mapid_user_custom,
};
HOOK_SIG(my_start){
exec_command(cmd_context, cmdid_open_panel_vsplit);
exec_command(cmd_context, cmdid_change_active_panel);
}
CUSTOM_COMMAND_SIG(open_my_files){
// NOTE(allen): The command cmdid_interactive_open has is now able to
// open a file specified on the parameter stack. If the file does not
// exist cmdid_interactive_open behaves as usual.
push_parameter(cmd_context, par_name, literal("w:/4ed/data/test/basic.cpp"));
exec_command(cmd_context, cmdid_interactive_open);
exec_command(cmd_context, cmdid_change_active_panel);
char my_file[256];
int my_file_len;
my_file_len = sizeof("w:/4ed/data/test/basic.txt") - 1;
for (int i = 0; i < my_file_len; ++i){
my_file[i] = ("w:/4ed/data/test/basic.txt")[i];
}
// NOTE(allen): null terminators are not needed for strings.
push_parameter(cmd_context, par_name, my_file, my_file_len);
exec_command(cmd_context, cmdid_interactive_open);
exec_command(cmd_context, cmdid_change_active_panel);
}
char *get_extension(const char *filename, int len, int *extension_len){
char *c = (char*)(filename + len - 1);
char *end = c;
while (*c != '.' && c > filename) --c;
*extension_len = (int)(end - c);
return c+1;
}
bool str_match(const char *a, int len_a, const char *b, int len_b){
bool result = 0;
if (len_a == len_b){
char *end = (char*)(a + len_a);
while (a < end && *a == *b){
++a; ++b;
}
if (a == end) result = 1;
}
return result;
}
HOOK_SIG(my_file_settings){
Buffer_Summary buffer = get_active_buffer(cmd_context);
int treat_as_code = 0;
// NOTE(allen): This checks buffer.file_name just in case get_active_buffer returns back
// a null buffer (where every member is 0).
if (buffer.file_name && buffer.size < (16 << 20)){
int extension_len;
char *extension = get_extension(buffer.file_name, buffer.file_name_len, &extension_len);
if (str_match(extension, extension_len, literal("cpp"))) treat_as_code = 1;
else if (str_match(extension, extension_len, literal("h"))) treat_as_code = 1;
else if (str_match(extension, extension_len, literal("c"))) treat_as_code = 1;
else if (str_match(extension, extension_len, literal("hpp"))) treat_as_code = 1;
}
push_parameter(cmd_context, par_lex_as_cpp_file, treat_as_code);
push_parameter(cmd_context, par_wrap_lines, !treat_as_code);
push_parameter(cmd_context, par_key_mapid, (treat_as_code)?(my_code_map):(mapid_file));
push_parameter(cmd_context, par_end_line_mode, EOL_USE_CRLF);
exec_command(cmd_context, cmdid_set_settings);
}
CUSTOM_COMMAND_SIG(open_in_other){
exec_command(cmd_context, cmdid_change_active_panel);
exec_command(cmd_context, cmdid_interactive_open);
}
extern "C" GET_BINDING_DATA(get_binding){
extern "C" GET_BINDING_DATA(get_bindings){
Bind_Helper context_actual = begin_bind_helper(data, size);
Bind_Helper *context = &context_actual;
begin_settings_group(context);
// NOTE(allen): Right now hooks have no loyalties to maps, all hooks are
// global and once set they always apply.
set_hook(context, hook_start, my_start);
set_hook(context, hook_open_file, my_file_settings);
use_when(context, when_default, 1);
set(context, set_lex_as_cpp_file, 0);
set(context, set_wrap_lines, 1);
set(context, set_key_mapid, MAPID_FILE);
// NOTE(allen): options include EOL_USE_CRLF, EOL_USE_CR_USE_LF, EOL_SHOW_CR_USE_LF
// EOL_USE_CRLF - treats a crlf and lf as newline markers, renders lone cr as special character "\r"
// EOL_USE_CR_USE_LF - treats both as separate newline markers
// EOL_SHOW_CR_USE_LF - treats lf as newline marker, renders cr as special character "\r"
set(context, set_end_line_mode, EOL_USE_CRLF);
end_group(context);
begin_settings_group(context);
use_when(context, when_extension, "cpp");
use_when(context, when_extension, "hpp");
use_when(context, when_extension, "c");
use_when(context, when_extension, "h");
set(context, set_lex_as_cpp_file, 1);
set(context, set_key_mapid, MAPID_USER_CUSTOM + 0);
begin_map(context, MAPID_GLOBAL);
begin_map(context, mapid_global);
bind(context, 'p', MDFR_CTRL, cmdid_open_panel_vsplit);
bind(context, '-', MDFR_CTRL, cmdid_open_panel_hsplit);
@ -68,19 +157,22 @@ extern "C" GET_BINDING_DATA(get_binding){
bind(context, 'c', MDFR_ALT, cmdid_open_color_tweaker);
bind(context, 'x', MDFR_ALT, cmdid_open_menu);
bind_me(context, 'o', MDFR_ALT, open_in_other);
// NOTE(allen): Go look at open_my_files, that's the only point of this being here.
bind_me(context, 'M', MDFR_ALT | MDFR_CTRL, open_my_files);
end_map(context);
begin_map(context, MAPID_USER_CUSTOM + 0);
// NOTE(allen): Set this map (MAPID_USER_CUSTOM + 0) to
// inherit from MAPID_FILE. When searching if a key is bound
// in this map, if it is not found here it will then search MAPID_FILE.
begin_map(context, my_code_map);
// NOTE(allen): Set this map (my_code_map == mapid_user_custom) to
// inherit from mapid_file. When searching if a key is bound
// in this map, if it is not found here it will then search mapid_file.
//
// If this is not set, it defaults to MAPID_GLOBAL.
inherit_map(context, MAPID_FILE);
// If this is not set, it defaults to mapid_global.
inherit_map(context, mapid_file);
// NOTE(allen): This demonstrates that children can override parent's bindings.
bind(context, codes->right, MDFR_CTRL, cmdid_seek_alphanumeric_or_camel_right);
bind(context, codes->left, MDFR_CTRL, cmdid_seek_alphanumeric_or_camel_left);
@ -90,7 +182,7 @@ extern "C" GET_BINDING_DATA(get_binding){
end_map(context);
begin_map(context, MAPID_FILE);
begin_map(context, mapid_file);
// NOTE(allen): Binding this essentially binds all key combos that
// would normally insert a character into a buffer.
@ -121,15 +213,21 @@ extern "C" GET_BINDING_DATA(get_binding){
bind(context, 'x', MDFR_CTRL, cmdid_cut);
bind(context, 'v', MDFR_CTRL, cmdid_paste);
bind(context, 'V', MDFR_CTRL, cmdid_paste_next);
bind(context, 'Z', MDFR_CTRL, cmdid_timeline_scrub);
bind(context, 'z', MDFR_CTRL, cmdid_undo);
bind(context, 'y', MDFR_CTRL, cmdid_redo);
bind(context, codes->left, MDFR_ALT, cmdid_increase_rewind_speed);
bind(context, codes->right, MDFR_ALT, cmdid_increase_fastforward_speed);
bind(context, codes->down, MDFR_ALT, cmdid_stop_rewind_fastforward);
bind(context, 'h', MDFR_CTRL, cmdid_history_backward);
bind(context, 'H', MDFR_CTRL, cmdid_history_forward);
bind(context, 'd', MDFR_CTRL, cmdid_delete_chunk);
bind(context, 'l', MDFR_CTRL, cmdid_toggle_line_wrap);
bind(context, 'L', MDFR_CTRL, cmdid_toggle_endline_mode);
bind(context, 'u', MDFR_CTRL, cmdid_to_uppercase);
bind(context, 'j', MDFR_CTRL, cmdid_to_lowercase);
bind(context, '?', MDFR_CTRL, cmdid_toggle_show_whitespace);
// NOTE(allen): These whitespace manipulators are not currently functional
bind(context, '`', MDFR_CTRL, cmdid_clean_line);
bind(context, '~', MDFR_CTRL, cmdid_clean_all_lines);

View File

@ -70,8 +70,14 @@ enum Command_ID{
cmdid_paste,
cmdid_paste_next,
cmdid_delete_chunk,
cmdid_timeline_scrub,
cmdid_undo,
cmdid_redo,
cmdid_increase_rewind_speed,
cmdid_increase_fastforward_speed,
cmdid_stop_rewind_fastforward,
cmdid_history_backward,
cmdid_history_forward,
cmdid_interactive_new,
cmdid_interactive_open,
cmdid_reopen,
@ -108,106 +114,202 @@ enum Command_ID{
cmdid_close_minor_view,
cmdid_cursor_mark_swap,
cmdid_open_menu,
cmdid_set_settings,
//
cmdid_count
};
enum Param_ID{
par_name,
par_lex_as_cpp_file,
par_wrap_lines,
par_key_mapid,
par_end_line_mode,
// never below this
par_type_count
};
enum Hook_ID{
hook_start,
hook_open_file,
// never below this
hook_type_count
};
enum Dynamic_Type{
dynamic_type_int,
dynamic_type_string,
// never below this
dynamic_type_count
};
struct Dynamic{
int type;
union{
struct{
int str_len;
char *str_value;
};
int int_value;
};
};
inline Dynamic
dynamic_int(int x){
Dynamic result;
result.type = dynamic_type_int;
result.int_value = x;
return result;
}
inline Dynamic
dynamic_string(const char *string, int len){
Dynamic result;
result.type = dynamic_type_string;
result.str_len = len;
result.str_value = (char*)(string);
return result;
}
inline int
dynamic_to_int(Dynamic *dynamic){
int result = 0;
if (dynamic->type == dynamic_type_int){
result = dynamic->int_value;
}
return result;
}
inline char*
dynamic_to_string(Dynamic *dynamic, int *len){
char *result = 0;
if (dynamic->type == dynamic_type_string){
result = dynamic->str_value;
*len = dynamic->str_len;
}
return result;
}
inline int
dynamic_to_bool(Dynamic *dynamic){
int result = 0;
if (dynamic->type == dynamic_type_int){
result = (dynamic->int_value != 0);
}
else{
result = 1;
}
return result;
}
struct Extra_Font{
char file_name[256];
char font_name[24];
int size;
};
#define GET_BINDING_DATA(name) int name(void *data, int size, Key_Codes *codes)
#define SET_EXTRA_FONT_SIG(name) void name(Extra_Font *font_out)
#define CUSTOM_COMMAND_SIG(name) void name(void *cmd_context, struct Application_Links app)
#define START_HOOK_SIG(name) void name(void *cmd_context, struct Application_Links app)
extern "C"{
typedef CUSTOM_COMMAND_SIG(Custom_Command_Function);
typedef GET_BINDING_DATA(Get_Binding_Data_Function);
typedef SET_EXTRA_FONT_SIG(Set_Extra_Font_Function);
typedef START_HOOK_SIG(Start_Hook_Function);
}
#define EXECUTE_COMMAND_SIG(name) void name(void *cmd_context, int command_id)
#define FULFILL_INTERACTION_SIG(name) void name(void *cmd_context, char *data, bool full_set)
extern "C"{
typedef EXECUTE_COMMAND_SIG(Exec_Command_Function);
typedef FULFILL_INTERACTION_SIG(Fulfill_Interaction_Function);
}
struct Application_Links{
Exec_Command_Function *exec_command;
Fulfill_Interaction_Function *fulfill_interaction;
};
enum Settings_Unit_Type{
SUNIT_HEADER,
SUNIT_GROUP,
SUNIT_USE_CLAUSE,
SUNIT_USE_CLAUSE_STRING,
SUNIT_SETTING
};
enum Setting_ID{
set_lex_as_cpp_file,
set_wrap_lines,
set_key_mapid,
set_end_line_mode
};
enum Setting_When_Type{
when_default,
when_extension
};
enum End_Of_Line_Options{
enum EOL_Option{
EOL_USE_CRLF,
EOL_USE_CR_USE_LF,
EOL_SHOW_CR_USE_LF
};
struct Buffer_Summary{
// NOTE(allen): None of these members nor any of the data pointed to
// by these members should be modified.
int file_id;
int size;
const char *data;
int file_name_len;
int buffer_name_len;
const char *file_name;
const char *buffer_name;
int file_cursor_pos;
EOL_Option eol_mode;
int is_lexed;
int map_id;
};
#define GET_BINDING_DATA(name) int name(void *data, int size, Key_Codes *codes)
#define SET_EXTRA_FONT_SIG(name) void name(Extra_Font *font_out)
#define CUSTOM_COMMAND_SIG(name) void name(void *cmd_context, struct Application_Links app)
#define HOOK_SIG(name) void name(void *cmd_context, struct Application_Links app)
extern "C"{
typedef CUSTOM_COMMAND_SIG(Custom_Command_Function);
typedef GET_BINDING_DATA(Get_Binding_Data_Function);
typedef SET_EXTRA_FONT_SIG(Set_Extra_Font_Function);
typedef HOOK_SIG(Hook_Function);
}
#define PUSH_PARAMETER_SIG(name) void name(void *cmd_context, Dynamic param, Dynamic value)
#define PUSH_MEMORY_SIG(name) char* name(void *cmd_context, int len)
#define EXECUTE_COMMAND_SIG(name) void name(void *cmd_context, int command_id)
#define CLEAR_PARAMETERS_SIG(name) void name(void *cmd_context)
#define GET_ACTIVE_BUFFER_SIG(name) Buffer_Summary name(void *cmd_context)
extern "C"{
typedef EXECUTE_COMMAND_SIG(Exec_Command_Function);
typedef PUSH_PARAMETER_SIG(Push_Parameter_Function);
typedef PUSH_MEMORY_SIG(Push_Memory_Function);
typedef CLEAR_PARAMETERS_SIG(Clear_Parameters_Function);
typedef GET_ACTIVE_BUFFER_SIG(Get_Active_Buffer_Function);
}
struct Application_Links{
Exec_Command_Function *exec_command_keep_stack;
Push_Parameter_Function *push_parameter;
Push_Memory_Function *push_memory;
Clear_Parameters_Function *clear_parameters;
Get_Active_Buffer_Function *get_active_buffer;
};
// NOTE(allen): definitions for the buffer that communicates to 4ed.exe
enum Binding_Unit_Type{
UNIT_HEADER,
UNIT_MAP_BEGIN,
UNIT_BINDING,
UNIT_CALLBACK,
UNIT_INHERIT,
UNIT_SETTINGS_BEGIN,
UNIT_USE_CLAUSE,
UNIT_USE_CLAUSE_STRING,
UNIT_SETTING
unit_header,
unit_map_begin,
unit_binding,
unit_callback,
unit_inherit,
unit_hook
};
enum Map_ID{
MAPID_GLOBAL,
MAPID_FILE,
MAPID_USER_CUSTOM
mapid_global,
mapid_file,
// NOTE(allen): mapid_nomap will remain empty even if you attempt to fill it
// it is for setting a map's parent to nothing
mapid_nomap,
mapid_user_custom = 100
};
struct Binding_Unit{
Binding_Unit_Type type;
union{
struct{ int total_size; int map_count; int group_count; int error; } header;
struct{ int total_size; int user_map_count; int error; } header;
struct{ int mapid; int bind_count; } map_begin;
struct{ int mapid; } map_inherit;
struct{
int command_id;
short code;
unsigned char modifiers;
int command_id;
} binding;
struct{
Custom_Command_Function *func;
short code;
unsigned char modifiers;
Custom_Command_Function *func;
} callback;
struct{ int clause_type; int value; } use_clause;
struct{ int clause_type; int len; char *value; } use_clause_string;
struct{ int setting_id; int value; } setting;
struct{
int hook_id;
Custom_Command_Function *func;
} hook;
};
};

View File

@ -1,135 +0,0 @@
/*
* This is an example of how vim-keys might start
* to work in 4coder, through the customization API.
*/
#include "4coder_custom.h"
#include "4coder_helper.h"
#define exec_command app.exec_command
#define fulfill_interaction app.fulfill_interaction
extern "C" START_HOOK_SIG(start_hook){
exec_command(cmd_context, cmdid_open_panel_vsplit);
exec_command(cmd_context, cmdid_change_active_panel);
}
extern "C" GET_BINDING_DATA(get_binding){
Bind_Helper context_actual = begin_bind_helper(data, size);
Bind_Helper *context = &context_actual;
begin_settings_group(context);
use_when(context, when_default, 1);
set(context, set_lex_as_cpp_file, 0);
set(context, set_wrap_lines, 1);
set(context, set_key_mapid, MAPID_FILE);
// NOTE(allen): options include EOL_USE_CRLF, EOL_USE_CR_USE_LF, EOL_SHOW_CR_USE_LF
// EOL_USE_CRLF - treats a crlf and lf as newline markers, renders lone cr as special character "\r"
// EOL_USE_CR_USE_LF - treats both as separate newline markers
// EOL_SHOW_CR_USE_LF - treats lf as newline marker, renders cr as special character "\r"
set(context, set_end_line_mode, EOL_USE_CRLF);
end_group(context);
begin_settings_group(context);
use_when(context, when_extension, "cpp");
use_when(context, when_extension, "hpp");
use_when(context, when_extension, "c");
use_when(context, when_extension, "h");
set(context, set_lex_as_cpp_file, 1);
set(context, set_key_mapid, MAPID_USER_CUSTOM + 0);
begin_map(context, MAPID_GLOBAL);
bind(context, 'p', MDFR_CTRL, cmdid_open_panel_vsplit);
bind(context, '-', MDFR_CTRL, cmdid_open_panel_hsplit);
bind(context, 'P', MDFR_CTRL, cmdid_close_panel);
bind(context, 'n', MDFR_CTRL, cmdid_interactive_new);
bind(context, 'o', MDFR_CTRL, cmdid_interactive_open);
bind(context, ',', MDFR_CTRL, cmdid_change_active_panel);
bind(context, 'k', MDFR_CTRL, cmdid_interactive_kill_buffer);
bind(context, 'i', MDFR_CTRL, cmdid_interactive_switch_buffer);
bind(context, 'c', MDFR_ALT, cmdid_open_color_tweaker);
bind(context, 'x', MDFR_ALT, cmdid_open_menu);
bind_me(context, 'o', MDFR_ALT, open_in_other);
end_map(context);
begin_map(context, MAPID_USER_CUSTOM + 0);
inherit_map(context, MAPID_FILE);
end_map(context);
int sub_id;
begin_map(context, MAPID_FILE);
sub_id = begin_sub_map(context);
{
bind_vanilla_keys(context, cmdid_write_character);
bind(context, codes->left, MDFR_NONE, cmdid_move_left);
bind(context, codes->right, MDFR_NONE, cmdid_move_right);
bind(context, codes->del, MDFR_NONE, cmdid_delete);
bind(context, codes->back, MDFR_NONE, cmdid_backspace);
bind(context, codes->up, MDFR_NONE, cmdid_move_up);
bind(context, codes->down, MDFR_NONE, cmdid_move_down);
bind(context, codes->end, MDFR_NONE, cmdid_seek_end_of_line);
bind(context, codes->home, MDFR_NONE, cmdid_seek_beginning_of_line);
bind(context, codes->page_up, MDFR_NONE, cmdid_page_up);
bind(context, codes->page_down, MDFR_NONE, cmdid_page_down);
}
end_sub_map(context);
bind_params(context, 'i', MDFR_NONE, cmdid_use_sub_map);
fill_param(context, "sub_id", sub_id);
end_params(context);
bind_multi(context, 'a', MDFR_NONE);
{
bind(context, 'a', MDFR_NONE, cmdid_move_left);
bind_params(context, 'a', MDFR_NONE, cmdid_use_sub_map);
fill_param(context, "sub_id", sub_id);
end_params(context);
}
end_multi(context);
bind(context, 'b', cmdid_seek_alphanumeric_left);
bind(context, 'w', cmdid_seek_alphanumeric_right);
bind(context, 'e', cmdid_seek_white_or_token_right);
// ???? this seems a bit off
bind_compound(context, 'g');
{
bind(context, 'e', cmdid_seek_white_or_token_left);
}
end_compound(context);
end_map(context);
end_bind_helper(context);
return context->write_total;
}
inline void
strset_(char *dst, char *src){
do{
*dst++ = *src++;
}while (*src);
}
#define strset(d,s) if (sizeof(s) <= sizeof(d)) strset_(d,s)
extern "C" SET_EXTRA_FONT_SIG(set_extra_font){
strset(font_out->file_name, "liberation-mono.ttf");
strset(font_out->font_name, "BIG");
font_out->size = 25;
}

View File

@ -14,15 +14,8 @@ struct Bind_Helper{
#define BH_ERR_MISSING_BEGIN 2
#define BH_ERR_OUT_OF_MEMORY 3
inline int
seek_null(char *str){
char *start = str;
while (*str) ++str;
return (int)(str - start);
}
inline void
copy(char *dest, char *src, int len){
copy(char *dest, const char *src, int len){
for (int i = 0; i < len; ++i){
*dest++ = *src++;
}
@ -73,11 +66,10 @@ begin_bind_helper(void *data, int size){
result.end = result.start + size / sizeof(*result.cursor);
Binding_Unit unit;
unit.type = UNIT_HEADER;
unit.type = unit_header;
unit.header.total_size = sizeof(*result.header);
result.header = write_unit(&result, unit);
result.header->header.map_count = 0;
result.header->header.group_count = 0;
result.header->header.user_map_count = 0;
return result;
}
@ -85,10 +77,10 @@ begin_bind_helper(void *data, int size){
inline void
begin_map(Bind_Helper *helper, int mapid){
if (helper->group != 0 && helper->error == 0) helper->error = BH_ERR_MISSING_END;
if (!helper->error) ++helper->header->header.map_count;
if (!helper->error && mapid >= mapid_user_custom) ++helper->header->header.user_map_count;
Binding_Unit unit;
unit.type = UNIT_MAP_BEGIN;
unit.type = unit_map_begin;
unit.map_begin.mapid = mapid;
helper->group = write_unit(helper, unit);
helper->group->map_begin.bind_count = 0;
@ -106,7 +98,7 @@ bind(Bind_Helper *helper, short code, unsigned char modifiers, int cmdid){
if (!helper->error) ++helper->group->map_begin.bind_count;
Binding_Unit unit;
unit.type = UNIT_BINDING;
unit.type = unit_binding;
unit.binding.command_id = cmdid;
unit.binding.code = code;
unit.binding.modifiers = modifiers;
@ -120,7 +112,7 @@ bind_me(Bind_Helper *helper, short code, unsigned char modifiers, Custom_Command
if (!helper->error) ++helper->group->map_begin.bind_count;
Binding_Unit unit;
unit.type = UNIT_CALLBACK;
unit.type = unit_callback;
unit.callback.func = func;
unit.callback.code = code;
unit.callback.modifiers = modifiers;
@ -141,14 +133,25 @@ bind_me_vanilla_keys(Bind_Helper *helper, Custom_Command_Function *func){
inline void
inherit_map(Bind_Helper *helper, int mapid){
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
if (!helper->error && mapid >= mapid_user_custom) ++helper->header->header.user_map_count;
Binding_Unit unit;
unit.type = UNIT_INHERIT;
unit.type = unit_inherit;
unit.map_inherit.mapid = mapid;
write_unit(helper, unit);
}
inline void
set_hook(Bind_Helper *helper, int hook_id, Custom_Command_Function *func){
Binding_Unit unit;
unit.type = unit_hook;
unit.hook.hook_id = hook_id;
unit.hook.func = func;
write_unit(helper, unit);
}
inline void
end_bind_helper(Bind_Helper *helper){
if (helper->header){
@ -157,72 +160,32 @@ end_bind_helper(Bind_Helper *helper){
}
}
// NOTE(allen): Useful functions and overloads on app links
inline void
begin_settings_group(Bind_Helper *helper){
if (helper->group != 0 && helper->error == 0) helper->error = BH_ERR_MISSING_END;
if (!helper->error) ++helper->header->header.group_count;
Binding_Unit unit;
unit.type = UNIT_SETTINGS_BEGIN;
helper->group = write_unit(helper, unit);
push_parameter_helper(void *cmd_context, Application_Links app, int param, int value){
app.push_parameter(cmd_context, dynamic_int(param), dynamic_int(value));
}
inline void
end_group(Bind_Helper *helper){
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
helper->group = 0;
push_parameter_helper(void *cmd_context, Application_Links app, int param, const char *value, int value_len){
char *value_copy = app.push_memory(cmd_context, value_len);
copy(value_copy, value, value_len);
app.push_parameter(cmd_context, dynamic_int(param), dynamic_string(value_copy, value_len));
}
inline void
use_when(Bind_Helper *helper, int clause_type, int value){
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
Binding_Unit unit;
unit.type = UNIT_USE_CLAUSE;
unit.use_clause.clause_type = clause_type;
unit.use_clause.value = value;
write_unit(helper, unit);
push_parameter_helper(void *cmd_context, Application_Links app, const char *param, int param_len, int value){
char *param_copy = app.push_memory(cmd_context, param_len);
copy(param_copy, param, param_len);
app.push_parameter(cmd_context, dynamic_string(param_copy, param_len), dynamic_int(value));
}
inline void
use_when(Bind_Helper *helper, int clause_type, char *value){
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
Binding_Unit unit;
unit.type = UNIT_USE_CLAUSE;
unit.use_clause_string.clause_type = clause_type;
unit.use_clause_string.len = seek_null(value);
Binding_Unit *u = write_unit(helper, unit);
u->use_clause_string.value = write_inline_string(helper, value, unit.use_clause_string.len);
}
inline void
use_when(Bind_Helper *helper, int clause_type, char *value, int len){
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
Binding_Unit unit;
unit.type = UNIT_USE_CLAUSE;
unit.use_clause_string.clause_type = clause_type;
unit.use_clause_string.len = len;
unit.use_clause_string.value = value;
write_unit(helper, unit);
}
inline void
set(Bind_Helper *helper, int setting_id, int value){
if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN;
Binding_Unit unit;
unit.type = UNIT_SETTING;
unit.setting.setting_id = setting_id;
unit.setting.value = value;
write_unit(helper, unit);
}
inline void
end_settings_helper(Bind_Helper *helper){
if (helper->header){
helper->header->header.error = helper->error;
}
push_parameter_helper(void *cmd_context, Application_Links app, const char *param, int param_len, const char *value, int value_len){
char *param_copy = app.push_memory(cmd_context, param_len);
char *value_copy = app.push_memory(cmd_context, value_len);
copy(param_copy, param, param_len);
copy(value_copy, value, value_len);
app.push_parameter(cmd_context, dynamic_string(param_copy, param_len), dynamic_string(value_copy, value_len));
}

733
4ed.cpp

File diff suppressed because it is too large Load Diff

21
4ed.h
View File

@ -3,7 +3,7 @@
*
* 12.12.2014
*
* Win32 Layer for project codename "4ed"
* Application Layer for project codename "4ed"
*
*/
@ -15,7 +15,7 @@ struct Partition{
i32 pos, max;
};
internal Partition
inline Partition
partition_open(void *memory, i32 size){
Partition partition;
partition.base = (u8*)memory;;
@ -24,16 +24,21 @@ partition_open(void *memory, i32 size){
return partition;
}
internal void*
inline void*
partition_allocate(Partition *data, i32 size){
void *ret = 0;
if (size > 0 && data->pos + size < data->max){
if (size > 0 && data->pos + size <= data->max){
ret = data->base + data->pos;
data->pos += size;
}
return ret;
}
inline void
partition_align(Partition *data, u32 boundary){
data->pos = (data->pos + (boundary - 1)) & (~boundary);
}
inline void*
partition_current(Partition *data){
return data->base + data->pos;
@ -44,6 +49,14 @@ partition_remaining(Partition *data){
return data->max - data->pos;
}
inline Partition
partition_sub_part(Partition *data, i32 size){
Partition result = {};
void *d = partition_allocate(data, size);
if (d) result = partition_open(d, size);
return result;
}
#define push_struct(part, T) (T*)partition_allocate(part, sizeof(T))
#define push_array(part, T, size) (T*)partition_allocate(part, sizeof(T)*(size))
#define push_block(part, size) partition_allocate(part, size)

View File

@ -123,15 +123,6 @@ view_to_color_view(View *view){
return (Color_View*)view;
}
internal real32
font_string_width(Font *font, char *str){
real32 x = 0;
for (i32 i = 0; str[i]; ++i){
x += font_get_glyph_width(font, str[i]);
}
return x;
}
internal void
draw_gradient_slider(Render_Target *target, Vec4 base, i32 channel,
i32 steps, real32 top, real32_Rect slider, bool32 hsla){
@ -213,51 +204,6 @@ do_label(UI_State *state, UI_Layout *layout, char *text, real32 height = 2.f){
}
}
internal bool32
do_button(i32 id, UI_State *state, UI_Layout *layout, char *text,
bool32 is_toggle = 0, bool32 on = 0){
bool32 result = 0;
Font *font = state->font;
i32 character_h = font->height;
i32_Rect btn_rect = layout_rect(layout, character_h * 2);
btn_rect = get_inner_rect(btn_rect, 2);
Widget_ID wid = make_id(state, id);
if (state->input_stage){
if (ui_do_button_input(state, btn_rect, wid, 0)){
result = 1;
}
}
else{
Render_Target *target = state->target;
UI_Style ui_style = get_ui_style(state->style);
u32 back, fore, outline;
outline = ui_style.bright;
get_colors(state, &back, &fore, wid, ui_style);
draw_rectangle(target, btn_rect, back);
draw_rectangle_outline(target, btn_rect, outline);
real32 text_width = font_string_width(font, text);
i32 box_width = btn_rect.x1 - btn_rect.x0;
i32 box_height = btn_rect.y1 - btn_rect.y0;
i32 x_pos = TRUNC32(btn_rect.x0 + (box_width - text_width)*.5f);
draw_string(target, font, text, x_pos, btn_rect.y0 + (box_height - character_h) / 2, fore);
if (is_toggle){
i32_Rect on_box = get_inner_rect(btn_rect, character_h/2);
on_box.x1 = on_box.x0 + (on_box.y1 - on_box.y0);
if (on) draw_rectangle(target, on_box, fore);
else draw_rectangle(target, on_box, back);
draw_rectangle_outline(target, on_box, fore);
}
}
return result;
}
internal void
do_scroll_bar(UI_State *state, i32_Rect rect){
i32 id = 1;
@ -1051,7 +997,7 @@ step_draw_adjusting(Color_View *color_view, i32_Rect rect, View_Message message,
ui.layout.rect.x1 -= 20;
if (!ui.state.input_stage) draw_push_clip(target, ui.layout.rect);
if (do_button(-1, &ui.state, &ui.layout, "Back to Library")){
if (do_button(-1, &ui.state, &ui.layout, "Back to Library", 2)){
color_view->mode = CV_MODE_LIBRARY;
ui.state.view_y = 0;
}
@ -1174,7 +1120,7 @@ update_highlighting(Color_View *color_view){
Editing_File *file = file_view->file;
i32 pos = view_get_cursor_pos(file_view);
char c = file->data[pos];
char c = file->buffer.data[pos];
if (c == '\r'){
color_view->highlight.ids[0] =
@ -1607,19 +1553,19 @@ step_draw_library(Color_View *color_view, i32_Rect rect, View_Message message,
begin_row(&ui.layout, 3);
if (ui.state.style->name.size >= 1){
if (do_button(-2, &ui.state, &ui.layout, "Save")){
if (do_button(-2, &ui.state, &ui.layout, "Save", 2)){
style_library_add(ui.styles, ui.state.style);
}
}
else{
do_button(-2, &ui.state, &ui.layout, "~Need's Name~");
do_button(-2, &ui.state, &ui.layout, "~Need's Name~", 2);
}
if (do_button(-3, &ui.state, &ui.layout, "Import")){
if (do_button(-3, &ui.state, &ui.layout, "Import", 2)){
color_view->mode = CV_MODE_IMPORT_FILE;
hot_directory_clean_end(color_view->hot_directory);
hot_directory_reload(color_view->hot_directory, color_view->working_set);
}
if (do_button(-4, &ui.state, &ui.layout, "Export")){
if (do_button(-4, &ui.state, &ui.layout, "Export", 2)){
color_view->mode = CV_MODE_EXPORT;
hot_directory_clean_end(color_view->hot_directory);
hot_directory_reload(color_view->hot_directory, color_view->working_set);
@ -1647,10 +1593,10 @@ step_draw_library(Color_View *color_view, i32_Rect rect, View_Message message,
do_label(&ui.state, &ui.layout, "Import Which File?");
begin_row(&ui.layout, 2);
if (do_button(-2, &ui.state, &ui.layout, "*.p4c only", 1, color_view->p4c_only)){
if (do_button(-2, &ui.state, &ui.layout, "*.p4c only", 2, 1, color_view->p4c_only)){
color_view->p4c_only = !color_view->p4c_only;
}
if (do_button(-3, &ui.state, &ui.layout, "Cancel")){
if (do_button(-3, &ui.state, &ui.layout, "Cancel", 2)){
color_view->mode = CV_MODE_LIBRARY;
}
@ -1689,10 +1635,10 @@ step_draw_library(Color_View *color_view, i32_Rect rect, View_Message message,
do_label(&ui.state, &ui.layout, "Export File Name?");
begin_row(&ui.layout, 2);
if (do_button(-2, &ui.state, &ui.layout, "Finish Export")){
if (do_button(-2, &ui.state, &ui.layout, "Finish Export", 2)){
file_selected = 1;
}
if (do_button(-3, &ui.state, &ui.layout, "Cancel")){
if (do_button(-3, &ui.state, &ui.layout, "Cancel", 2)){
color_view->mode = CV_MODE_LIBRARY;
}
@ -1740,14 +1686,14 @@ step_draw_library(Color_View *color_view, i32_Rect rect, View_Message message,
do_label(&ui.state, &ui.layout, "Pack");
begin_row(&ui.layout, 2);
if (do_button(-2, &ui.state, &ui.layout, "Finish Import")){
if (do_button(-2, &ui.state, &ui.layout, "Finish Import", 2)){
Style *style = styles;
for (i32 i = 0; i < style_count; ++i, ++style){
if (import_check[i]) style_library_add(ui.styles, style);
}
color_view->mode = CV_MODE_LIBRARY;
}
if (do_button(-3, &ui.state, &ui.layout, "Cancel")){
if (do_button(-3, &ui.state, &ui.layout, "Cancel", 2)){
color_view->mode = CV_MODE_LIBRARY;
}
@ -1767,10 +1713,10 @@ step_draw_library(Color_View *color_view, i32_Rect rect, View_Message message,
do_label(&ui.state, &ui.layout, "Export Which Themes?");
begin_row(&ui.layout, 2);
if (do_button(-2, &ui.state, &ui.layout, "Export")){
if (do_button(-2, &ui.state, &ui.layout, "Export", 2)){
color_view->mode = CV_MODE_EXPORT_FILE;
}
if (do_button(-3, &ui.state, &ui.layout, "Cancel")){
if (do_button(-3, &ui.state, &ui.layout, "Cancel", 2)){
color_view->mode = CV_MODE_LIBRARY;
}

View File

@ -18,8 +18,9 @@ struct Command_Binding{
};
struct Command_Map{
Command_Map *parent;
Command_Binding vanilla_keyboard_default;
Command_Binding commands[101];
Command_Binding *commands;
i32 count, max;
};
@ -93,10 +94,12 @@ map_drop(Command_Map *map, u16 event_code, u8 modifiers){
}
internal void
map_init(Command_Map *commands){
map_init(Command_Map *commands, Partition *part, i32 max, Command_Map *parent){
commands->parent = parent;
commands->commands = push_array(part, Command_Binding, max);
memset(commands->commands, 0, max*sizeof(*commands->commands));
commands->vanilla_keyboard_default = {};
memset(commands->commands, 0, sizeof(commands->commands));
commands->max = ArrayCount(commands->commands);
commands->max = max;
commands->count = 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -825,6 +825,15 @@ font_get_glyph_width(Font *font, u16 character){
return font->chardata[character].xadvance;
}
internal real32
font_string_width(Font *font, char *str){
real32 x = 0;
for (i32 i = 0; str[i]; ++i){
x += font_get_glyph_width(font, str[i]);
}
return x;
}
internal i32
draw_string(Render_Target *target, Font *font, char *str,
i32 x_, i32 y, u32 color){

View File

@ -0,0 +1,118 @@
/*
* Mr. 4th Dimention - Allen Webster
* Four Tech
*
* 16.10.2015
*
* Buffer data object
* type - Golden Array
*
*/
#define inline_4tech inline
#define internal_4tech static
typedef struct{
char *data;
int size, max;
} Buffer;
typedef struct{
Buffer *buffer;
char *data;
int size;
} Buffer_Save_Loop;
inline_4tech Buffer_Save_Loop
buffer_save_loop(Buffer *buffer){
Buffer_Save_Loop result;
result.buffer = buffer;
result.data = buffer->data;
result.size = buffer->size;
return(result);
}
inline_4tech int
buffer_save_good(Buffer_Save_Loop *loop){
int result;
result = (loop->buffer != 0);
return(result);
}
inline_4tech void
buffer_save_next(Buffer_Save_Loop *loop){
loop->buffer = 0;
}
internal_4tech int
buffer_count_newlines(Buffer *buffer, int start, int end, int CR, int LF){
int new_line, count;
char *data;
int i;
data = buffer->data;
new_line = 0;
count = 0;
for (i = start; i < end; ++i){
switch(data[i]){
case '\n': new_line = LF; break;
case '\r': new_line = CR; break;
default: new_line = 0; break;
}
count += new_line;
}
return (count);
}
typedef struct{
int i;
int count;
int start;
} Buffer_Measure_Starts;
internal_4tech int
buffer_measure_starts_(Buffer_Measure_Starts *state, Buffer *buffer, int *starts, int max, int CR, int LF){
char *data;
int size;
int start, count, i, new_line;
int result;
data = buffer->data;
size = buffer->size;
result = 0;
start = state->start;
count = state->count;
for (i = state->i; i < size; ++i){
switch (data[i]){
case '\n': new_line = LF; break;
case '\r': new_line = CR; break;
default: new_line = 0; break;
}
if (new_line){
if (count == max){
result = 1;
break;
}
starts[count++] = start;
start = i + 1;
}
}
if (i == size){
if (count == max) result = 1;
else starts[count++] = start;
}
state->i = i;
state->count = count;
state->start = start;
return (result);
}

View File

@ -72,7 +72,6 @@
struct TEMP_BACKDOOR{
Get_Binding_Data_Function *get_bindings;
Set_Extra_Font_Function *set_extra_font;
Start_Hook_Function *start_hook;
} TEMP;
#if FRED_INTERNAL
@ -931,9 +930,6 @@ WinMain(HINSTANCE hInstance,
TEMP.set_extra_font = (Set_Extra_Font_Function*)
GetProcAddress(win32vars.custom, "set_extra_font");
TEMP.start_hook = (Start_Hook_Function*)
GetProcAddress(win32vars.custom, "start_hook");
}
#endif