bug fixing
This commit is contained in:
parent
770c48f95b
commit
c8db4004a6
|
@ -23,7 +23,7 @@ enum My_Maps{
|
|||
HOOK_SIG(my_start){
|
||||
exec_command(cmd_context, cmdid_open_panel_hsplit);
|
||||
exec_command(cmd_context, cmdid_change_active_panel);
|
||||
|
||||
|
||||
exec_command(cmd_context, cmdid_open_panel_vsplit);
|
||||
exec_command(cmd_context, cmdid_change_active_panel);
|
||||
}
|
||||
|
@ -50,9 +50,9 @@ bool str_match(const char *a, int len_a, const char *b, int len_b){
|
|||
|
||||
HOOK_SIG(my_file_settings){
|
||||
Buffer_Summary buffer = get_active_buffer(cmd_context);
|
||||
|
||||
|
||||
int treat_as_code = 0;
|
||||
|
||||
|
||||
// NOTE(allen|a3.1): 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)){
|
||||
|
@ -63,7 +63,7 @@ HOOK_SIG(my_file_settings){
|
|||
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(app, cmd_context, par_lex_as_cpp_file, treat_as_code);
|
||||
push_parameter(app, cmd_context, par_wrap_lines, !treat_as_code);
|
||||
push_parameter(app, cmd_context, par_key_mapid, (treat_as_code)?(my_code_map):(mapid_file));
|
||||
|
@ -81,21 +81,21 @@ CUSTOM_COMMAND_SIG(open_my_files){
|
|||
// cmdid_interactive_open behaves as usual.
|
||||
push_parameter(app, 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|a3.1): null terminators are not needed for strings.
|
||||
push_parameter(app, cmd_context, par_name, my_file, my_file_len);
|
||||
exec_command(cmd_context, cmdid_interactive_open);
|
||||
|
||||
|
||||
exec_command(cmd_context, cmdid_change_active_panel);
|
||||
}
|
||||
|
||||
|
@ -147,20 +147,20 @@ CUSTOM_COMMAND_SIG(build_search){
|
|||
push_parameter(app, cmd_context, par_cli_overlap_with_conflict, 0);
|
||||
push_parameter(app, cmd_context, par_target_buffer_name, literal("*compilation*"));
|
||||
push_parameter(app, cmd_context, par_cli_path, dir.str, dir.size);
|
||||
|
||||
|
||||
if (append(&dir, "build")){
|
||||
app->push_parameter(cmd_context,
|
||||
dynamic_int(par_cli_command),
|
||||
dynamic_string(dir.str, dir.size));
|
||||
dynamic_int(par_cli_command),
|
||||
dynamic_string(dir.str, dir.size));
|
||||
exec_command(cmd_context, cmdid_build);
|
||||
}
|
||||
else{
|
||||
clear_parameters(cmd_context);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (app->directory_cd(&dir, "..") == 0){
|
||||
keep_going = 0;
|
||||
}
|
||||
|
@ -187,14 +187,14 @@ CUSTOM_COMMAND_SIG(cut_line){
|
|||
extern "C" GET_BINDING_DATA(get_bindings){
|
||||
Bind_Helper context_actual = begin_bind_helper(data, size);
|
||||
Bind_Helper *context = &context_actual;
|
||||
|
||||
|
||||
// NOTE(allen|a3.1): Right now hooks have no loyalties to maps, all hooks are
|
||||
// global and once set they always apply, regardless of what map is active.
|
||||
set_hook(context, hook_start, my_start);
|
||||
set_hook(context, hook_open_file, my_file_settings);
|
||||
|
||||
|
||||
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);
|
||||
|
@ -206,18 +206,18 @@ extern "C" GET_BINDING_DATA(get_bindings){
|
|||
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): These callbacks may not actually be useful to you, but
|
||||
// go look at them and see what they do.
|
||||
bind_me(context, 'M', MDFR_ALT | MDFR_CTRL, open_my_files);
|
||||
bind_me(context, 'M', MDFR_ALT, build_at_launch_location);
|
||||
bind_me(context, 'm', MDFR_ALT, build_search);
|
||||
|
||||
|
||||
end_map(context);
|
||||
|
||||
|
||||
|
||||
|
||||
begin_map(context, my_code_map);
|
||||
|
||||
|
||||
// NOTE(allen|a3.1): 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.
|
||||
|
@ -228,7 +228,7 @@ extern "C" GET_BINDING_DATA(get_bindings){
|
|||
// NOTE(allen|a3.1): 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);
|
||||
|
||||
|
||||
// NOTE(allen|a3.2): Specific keys can override vanilla keys,
|
||||
// and write character writes whichever character corresponds
|
||||
// to the key that triggered the command.
|
||||
|
@ -237,11 +237,11 @@ extern "C" GET_BINDING_DATA(get_bindings){
|
|||
bind_me(context, ')', MDFR_NONE, write_and_auto_tab);
|
||||
bind_me(context, ']', MDFR_NONE, write_and_auto_tab);
|
||||
bind_me(context, ';', MDFR_NONE, write_and_auto_tab);
|
||||
|
||||
bind(context, '\t', MDFR_NONE, cmdid_auto_tab_line_at_cursor);
|
||||
bind(context, '\t', MDFR_CTRL, cmdid_auto_tab_range);
|
||||
bind(context, '\t', MDFR_CTRL | MDFR_SHIFT, cmdid_write_character);
|
||||
|
||||
bind(context, '\t', MDFR_NONE, cmdid_word_complete);
|
||||
bind(context, '\t', MDFR_CTRL, cmdid_auto_tab_range);
|
||||
bind(context, '\t', MDFR_SHIFT, cmdid_auto_tab_line_at_cursor);
|
||||
|
||||
end_map(context);
|
||||
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ enum Command_ID{
|
|||
cmdid_seek_alphanumeric_or_camel_right,
|
||||
cmdid_search,
|
||||
cmdid_rsearch,
|
||||
cmdid_word_complete,
|
||||
cmdid_goto_line,
|
||||
cmdid_set_mark,
|
||||
cmdid_copy,
|
||||
|
@ -96,7 +97,6 @@ enum Command_ID{
|
|||
cmdid_clean_all_lines,
|
||||
cmdid_eol_dosify,
|
||||
cmdid_eol_nixify,
|
||||
cmdid_auto_tab,
|
||||
cmdid_auto_tab_range,
|
||||
cmdid_auto_tab_line_at_cursor,
|
||||
cmdid_auto_tab_whole_file,
|
||||
|
|
|
@ -173,6 +173,7 @@ FCPP_LINK int reverse_seek_slash(String str);
|
|||
FCPP_LINK int reverse_seek_slash(String str, int start_pos);
|
||||
inline bool get_front_of_directory(String *dest, String dir) { return append_checked(dest, substr(dir, reverse_seek_slash(dir) + 1)); }
|
||||
inline bool get_path_of_directory(String *dest, String dir) { return append_checked(dest, substr(dir, 0, reverse_seek_slash(dir) + 1)); }
|
||||
inline void truncate_to_path_of_directory(String *dir) { dir->size = reverse_seek_slash(*dir) + 1; }
|
||||
FCPP_LINK bool set_last_folder(String *dir, char *folder_name);
|
||||
FCPP_LINK bool set_last_folder(String *dir, String folder_name);
|
||||
FCPP_LINK String file_extension(String str);
|
||||
|
|
110
4ed.cpp
110
4ed.cpp
|
@ -44,6 +44,7 @@ struct Complete_State{
|
|||
Table hits;
|
||||
String_Space str;
|
||||
i32 word_start, word_end;
|
||||
b32 initialized;
|
||||
};
|
||||
|
||||
struct App_Vars{
|
||||
|
@ -487,6 +488,10 @@ COMMAND_DECL(word_complete){
|
|||
if (vars->prev_command.function != command_word_complete){
|
||||
do_init = 1;
|
||||
}
|
||||
|
||||
if (complete_state->initialized == 0){
|
||||
do_init = 1;
|
||||
}
|
||||
|
||||
if (do_init){
|
||||
word_end = view->cursor.pos;
|
||||
|
@ -514,6 +519,12 @@ COMMAND_DECL(word_complete){
|
|||
|
||||
size = word_end - word_start;
|
||||
|
||||
if (size == 0){
|
||||
complete_state->initialized = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
complete_state->initialized = 1;
|
||||
search_iter_init(general, &complete_state->iter, size);
|
||||
buffer_stringify(buffer, word_start, word_end, complete_state->iter.word.str);
|
||||
complete_state->iter.word.size = size;
|
||||
|
@ -863,65 +874,6 @@ COMMAND_DECL(interactive_new){
|
|||
copy(&int_view->query, "New: ");
|
||||
}
|
||||
|
||||
#if 0
|
||||
internal File_View*
|
||||
app_open_file(System_Functions *system, Exchange *exchange,
|
||||
App_Vars *vars, Mem_Options *mem, Panel *panel,
|
||||
Working_Set *working_set, String *string, Style *style,
|
||||
Live_Views *live_set, Command_Data *command_data){
|
||||
File_View *result = 0;
|
||||
Editing_File *target_file = 0;
|
||||
b32 created_file = 0;
|
||||
|
||||
target_file = working_set_contains(working_set, *string);
|
||||
if (!target_file){
|
||||
Get_File_Result file = working_set_get_available_file(working_set);
|
||||
if (file.file){
|
||||
file_get_dummy(file.file);
|
||||
created_file = file_create(system, mem, file.file, string->str, style->font);
|
||||
table_add(&working_set->table, file.file->source_path, file.index);
|
||||
if (created_file){
|
||||
target_file = file.file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (target_file){
|
||||
View *new_view = live_set_alloc_view(live_set, &vars->mem);
|
||||
|
||||
view_replace_major(system, exchange, new_view, panel, live_set);
|
||||
|
||||
File_View *file_view = file_view_init(new_view, &vars->layout);
|
||||
result = file_view;
|
||||
|
||||
View *old_view = command_data->view;
|
||||
command_data->view = new_view;
|
||||
|
||||
Partition old_part = command_data->part;
|
||||
Temp_Memory temp = begin_temp_memory(&vars->mem.part);
|
||||
command_data->part = partition_sub_part(&vars->mem.part, 16 << 10);
|
||||
|
||||
view_set_file(system, file_view, target_file, style,
|
||||
vars->hooks[hook_open_file], command_data, &app_links);
|
||||
|
||||
command_data->part = old_part;
|
||||
end_temp_memory(temp);
|
||||
command_data->view = old_view;
|
||||
|
||||
new_view->map = app_get_map(vars, target_file->base_map_id);
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
if (created_file && target_file->tokens_exist &&
|
||||
target_file->token_stack.tokens == 0){
|
||||
file_first_lex_parallel(system, &mem->general, target_file);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
internal void
|
||||
app_push_file_binding(App_Vars *vars, int sys_id, int app_id){
|
||||
Sys_App_Binding binding;
|
||||
|
@ -951,7 +903,7 @@ app_open_file_background(App_Vars *vars, Exchange *exchange, Working_Set *workin
|
|||
result.is_new = 1;
|
||||
result.file = file.file;
|
||||
file_init_strings(result.file);
|
||||
file_set_name(result.file, filename.str);
|
||||
file_set_name(working_set, result.file, filename.str);
|
||||
file_set_to_loading(result.file);
|
||||
table_add(&working_set->table, result.file->name.source_path, file.index);
|
||||
|
||||
|
@ -1311,21 +1263,6 @@ COMMAND_DECL(eol_nixify){
|
|||
file->state.last_4ed_edit_time = system->time();
|
||||
}
|
||||
|
||||
COMMAND_DECL(auto_tab){
|
||||
#if 0
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
REQ_FILE(file, view);
|
||||
USE_LAYOUT(layout);
|
||||
USE_MEM(mem);
|
||||
|
||||
if (file->token_stack.tokens && file->tokens_complete){
|
||||
Range range = get_range(view->cursor.pos, view->mark);
|
||||
view_auto_tab_tokens(mem, view, layout, range.start, range.end);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
COMMAND_DECL(auto_tab_range){
|
||||
ProfileMomentFunction();
|
||||
REQ_FILE_VIEW(view);
|
||||
|
@ -1887,7 +1824,7 @@ build(System_Functions *system, Mem_Options *mem,
|
|||
}
|
||||
|
||||
if (file){
|
||||
file_create_super_locked(system, mem, file, buffer_name, font_set, style->font_id);
|
||||
file_create_super_locked(system, mem, working_set, file, buffer_name, font_set, style->font_id);
|
||||
file->settings.unimportant = 1;
|
||||
table_add(&working_set->table, file->name.source_path, index);
|
||||
|
||||
|
@ -2246,7 +2183,6 @@ setup_file_commands(Command_Map *commands, Partition *part, Key_Codes *codes, Co
|
|||
map_add(commands, 'j', MDFR_CTRL, command_to_lowercase);
|
||||
map_add(commands, '~', MDFR_CTRL, command_clean_all_lines);
|
||||
map_add(commands, 'f', MDFR_CTRL, command_search);
|
||||
map_add(commands, 't', MDFR_CTRL, command_word_complete);
|
||||
|
||||
map_add(commands, 'r', MDFR_CTRL, command_rsearch);
|
||||
map_add(commands, 'g', MDFR_CTRL, command_goto_line);
|
||||
|
@ -2257,9 +2193,9 @@ setup_file_commands(Command_Map *commands, Partition *part, Key_Codes *codes, Co
|
|||
map_add(commands, ']', MDFR_NONE, compose_write_auto_tab_line);
|
||||
map_add(commands, ';', MDFR_NONE, compose_write_auto_tab_line);
|
||||
|
||||
map_add(commands, '\t', MDFR_NONE, command_auto_tab_line_at_cursor);
|
||||
map_add(commands, '\t', MDFR_NONE, command_word_complete);
|
||||
map_add(commands, '\t', MDFR_CTRL, command_auto_tab_range);
|
||||
map_add(commands, '\t', MDFR_CTRL | MDFR_SHIFT, command_write_character);
|
||||
map_add(commands, '\t', MDFR_SHIFT, command_auto_tab_line_at_cursor);
|
||||
|
||||
map_add(commands, 'K', MDFR_CTRL, command_kill_buffer);
|
||||
map_add(commands, 'O', MDFR_CTRL, command_reopen);
|
||||
|
@ -2312,6 +2248,7 @@ setup_command_table(){
|
|||
SET(seek_alphanumeric_or_camel_left);
|
||||
SET(search);
|
||||
SET(rsearch);
|
||||
SET(word_complete);
|
||||
SET(goto_line);
|
||||
SET(set_mark);
|
||||
SET(copy);
|
||||
|
@ -2343,7 +2280,6 @@ setup_command_table(){
|
|||
SET(clean_all_lines);
|
||||
SET(eol_dosify);
|
||||
SET(eol_nixify);
|
||||
SET(auto_tab);
|
||||
SET(auto_tab_range);
|
||||
SET(auto_tab_line_at_cursor);
|
||||
SET(auto_tab_whole_file);
|
||||
|
@ -3629,7 +3565,7 @@ App_Step_Sig(app_step){
|
|||
if (fview){
|
||||
Editing_File *file = fview->file;
|
||||
if (file && !file->state.is_dummy){
|
||||
i32 sys_id = file_save_and_set_names(system, exchange, mem, file, string->str);
|
||||
i32 sys_id = file_save_and_set_names(system, exchange, mem, working_set, file, string->str);
|
||||
app_push_file_binding(vars, sys_id, get_file_id(working_set, file));
|
||||
}
|
||||
}
|
||||
|
@ -3647,7 +3583,7 @@ App_Step_Sig(app_step){
|
|||
case DACT_NEW:
|
||||
{
|
||||
Get_File_Result file = working_set_get_available_file(working_set);
|
||||
file_create_empty(system, mem, file.file, string->str,
|
||||
file_create_empty(system, mem, working_set, file.file, string->str,
|
||||
vars->font_set, style->font_id);
|
||||
table_add(&working_set->table, file.file->name.source_path, file.index);
|
||||
|
||||
|
@ -3818,20 +3754,22 @@ App_Step_Sig(app_step){
|
|||
Editing_File_Preload preload_settings;
|
||||
char *filename;
|
||||
|
||||
Working_Set *working_set = &vars->working_set;
|
||||
|
||||
if (exchange_file_ready(exchange, binding->sys_id, &data, &size, &max)){
|
||||
ed_file = vars->working_set.files + binding->app_id;
|
||||
ed_file = working_set->files + binding->app_id;
|
||||
filename = exchange_file_filename(exchange, binding->sys_id);
|
||||
preload_settings = ed_file->preload;
|
||||
if (data){
|
||||
String val = make_string((char*)data, size);
|
||||
file_create_from_string(system, &vars->mem, ed_file, filename,
|
||||
file_create_from_string(system, &vars->mem, working_set, ed_file, filename,
|
||||
vars->font_set, vars->style.font_id, val);
|
||||
|
||||
if (ed_file->settings.tokens_exist)
|
||||
file_first_lex_parallel(system, &vars->mem.general, ed_file);
|
||||
}
|
||||
else{
|
||||
file_create_empty(system, &vars->mem, ed_file, filename,
|
||||
file_create_empty(system, &vars->mem, working_set, ed_file, filename,
|
||||
vars->font_set, vars->style.font_id);
|
||||
}
|
||||
|
||||
|
@ -3854,7 +3792,7 @@ App_Step_Sig(app_step){
|
|||
exchange_clear_file(exchange, binding->sys_id);
|
||||
}
|
||||
|
||||
Editing_File *file = get_file(&vars->working_set, binding->app_id);
|
||||
Editing_File *file = get_file(working_set, binding->app_id);
|
||||
if (file){
|
||||
file_synchronize_times(system, file, file->name.source_path.str);
|
||||
}
|
||||
|
|
328
4ed_command.cpp
328
4ed_command.cpp
|
@ -1,163 +1,165 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 19.08.2015
|
||||
*
|
||||
* Command management functions for 4coder
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#define Command_Function_Sig(name) void (name)( \
|
||||
System_Functions *system, \
|
||||
struct Command_Data *command, \
|
||||
struct Command_Binding binding)
|
||||
|
||||
typedef Command_Function_Sig(*Command_Function);
|
||||
|
||||
struct Command_Binding{
|
||||
Command_Function function;
|
||||
Custom_Command_Function *custom;
|
||||
i64 hash;
|
||||
};
|
||||
|
||||
struct Command_Map{
|
||||
Command_Map *parent;
|
||||
Command_Binding vanilla_keyboard_default;
|
||||
Command_Binding *commands;
|
||||
i32 count, max;
|
||||
};
|
||||
|
||||
internal void command_null(Command_Data *command);
|
||||
|
||||
internal i64
|
||||
map_hash(u16 event_code, u8 modifiers){
|
||||
i64 result = (event_code << 8) | modifiers;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal b32
|
||||
map_add(Command_Map *map, u16 event_code, u8 modifiers,
|
||||
Command_Function function, Custom_Command_Function *custom = 0){
|
||||
Assert(map->count * 8 < map->max * 7);
|
||||
Command_Binding bind;
|
||||
bind.function = function;
|
||||
bind.custom = custom;
|
||||
bind.hash = map_hash(event_code, modifiers);
|
||||
|
||||
i32 max = map->max;
|
||||
i32 index = bind.hash % max;
|
||||
Command_Binding entry;
|
||||
while ((entry = map->commands[index]).function && entry.hash != -1){
|
||||
if (entry.hash == bind.hash){
|
||||
return 1;
|
||||
}
|
||||
index = (index + 1) % max;
|
||||
}
|
||||
map->commands[index] = bind;
|
||||
++map->count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal b32
|
||||
map_find_entry(Command_Map *map, u16 event_code, u8 modifiers,
|
||||
i32 *index_out){
|
||||
i64 hash = map_hash(event_code, modifiers);
|
||||
i32 max = map->max;
|
||||
i32 index = hash % map->max;
|
||||
Command_Binding entry;
|
||||
while ((entry = map->commands[index]).function){
|
||||
if (entry.hash == hash){
|
||||
*index_out = index;
|
||||
return 1;
|
||||
}
|
||||
index = (index + 1) % max;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal b32
|
||||
map_find(Command_Map *map, u16 event_code, u8 modifiers,
|
||||
Command_Binding *bind_out){
|
||||
b32 result;
|
||||
i32 index;
|
||||
result = map_find_entry(map, event_code, modifiers, &index);
|
||||
if (result){
|
||||
*bind_out = map->commands[index];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal b32
|
||||
map_drop(Command_Map *map, u16 event_code, u8 modifiers){
|
||||
b32 result;
|
||||
i32 index;
|
||||
result = map_find_entry(map, event_code, modifiers, &index);
|
||||
if (result){
|
||||
map->commands[index].function = 0;
|
||||
map->commands[index].hash = -1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
map_init(Command_Map *commands, Partition *part, i32 max, Command_Map *parent){
|
||||
max = ((max < 6)?(6):(max));
|
||||
commands->parent = parent;
|
||||
commands->commands = push_array(part, Command_Binding, max);
|
||||
memset(commands->commands, 0, max*sizeof(*commands->commands));
|
||||
commands->vanilla_keyboard_default = {};
|
||||
commands->max = max;
|
||||
commands->count = 0;
|
||||
}
|
||||
|
||||
internal void
|
||||
map_get_vanilla_keyboard_default(Command_Map *map, u8 command,
|
||||
Command_Binding *bind_out){
|
||||
if (command == MDFR_NONE){
|
||||
*bind_out = map->vanilla_keyboard_default;
|
||||
}
|
||||
}
|
||||
|
||||
inline u8
|
||||
apply_shift_to_code(u8 keycode){
|
||||
return !(keycode >= 0x20 && keycode < 0x7F && keycode != ' ');
|
||||
}
|
||||
|
||||
internal Command_Binding
|
||||
map_extract(Command_Map *map, Key_Event_Data key){
|
||||
Command_Binding bind = {};
|
||||
|
||||
b32 ctrl = key.modifiers[CONTROL_KEY_CONTROL];
|
||||
b32 alt = key.modifiers[CONTROL_KEY_ALT];
|
||||
b32 shift = key.modifiers[CONTROL_KEY_SHIFT];
|
||||
u16 code;
|
||||
u8 command = MDFR_NONE;
|
||||
|
||||
if (key.character_no_caps_lock != 0 &&
|
||||
key.character_no_caps_lock != ' ') shift = 0;
|
||||
|
||||
if (shift) command |= MDFR_SHIFT;
|
||||
if (ctrl) command |= MDFR_CTRL;
|
||||
if (alt) command |= MDFR_ALT;
|
||||
|
||||
code = key.character_no_caps_lock;
|
||||
if (code == 0){
|
||||
code = key.keycode;
|
||||
map_find(map, code, command, &bind);
|
||||
}
|
||||
else{
|
||||
command &= ~(MDFR_SHIFT);
|
||||
|
||||
map_find(map, code, command, &bind);
|
||||
if (bind.function == 0){
|
||||
map_get_vanilla_keyboard_default(map, command, &bind);
|
||||
}
|
||||
}
|
||||
|
||||
return bind;
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 19.08.2015
|
||||
*
|
||||
* Command management functions for 4coder
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#define Command_Function_Sig(name) void (name)( \
|
||||
System_Functions *system, \
|
||||
struct Command_Data *command, \
|
||||
struct Command_Binding binding)
|
||||
|
||||
typedef Command_Function_Sig(*Command_Function);
|
||||
|
||||
struct Command_Binding{
|
||||
Command_Function function;
|
||||
Custom_Command_Function *custom;
|
||||
i64 hash;
|
||||
};
|
||||
|
||||
struct Command_Map{
|
||||
Command_Map *parent;
|
||||
Command_Binding vanilla_keyboard_default;
|
||||
Command_Binding *commands;
|
||||
i32 count, max;
|
||||
};
|
||||
|
||||
internal void command_null(Command_Data *command);
|
||||
|
||||
internal i64
|
||||
map_hash(u16 event_code, u8 modifiers){
|
||||
i64 result = (event_code << 8) | modifiers;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal b32
|
||||
map_add(Command_Map *map, u16 event_code, u8 modifiers,
|
||||
Command_Function function, Custom_Command_Function *custom = 0){
|
||||
Assert(map->count * 8 < map->max * 7);
|
||||
Command_Binding bind;
|
||||
bind.function = function;
|
||||
bind.custom = custom;
|
||||
bind.hash = map_hash(event_code, modifiers);
|
||||
|
||||
i32 max = map->max;
|
||||
i32 index = bind.hash % max;
|
||||
Command_Binding entry;
|
||||
while ((entry = map->commands[index]).function && entry.hash != -1){
|
||||
if (entry.hash == bind.hash){
|
||||
return 1;
|
||||
}
|
||||
index = (index + 1) % max;
|
||||
}
|
||||
map->commands[index] = bind;
|
||||
++map->count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal b32
|
||||
map_find_entry(Command_Map *map, u16 event_code, u8 modifiers,
|
||||
i32 *index_out){
|
||||
i64 hash = map_hash(event_code, modifiers);
|
||||
i32 max = map->max;
|
||||
i32 index = hash % map->max;
|
||||
Command_Binding entry;
|
||||
while ((entry = map->commands[index]).function){
|
||||
if (entry.hash == hash){
|
||||
*index_out = index;
|
||||
return 1;
|
||||
}
|
||||
index = (index + 1) % max;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal b32
|
||||
map_find(Command_Map *map, u16 event_code, u8 modifiers,
|
||||
Command_Binding *bind_out){
|
||||
b32 result;
|
||||
i32 index;
|
||||
result = map_find_entry(map, event_code, modifiers, &index);
|
||||
if (result){
|
||||
*bind_out = map->commands[index];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal b32
|
||||
map_drop(Command_Map *map, u16 event_code, u8 modifiers){
|
||||
b32 result;
|
||||
i32 index;
|
||||
result = map_find_entry(map, event_code, modifiers, &index);
|
||||
if (result){
|
||||
map->commands[index].function = 0;
|
||||
map->commands[index].hash = -1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
map_init(Command_Map *commands, Partition *part, i32 max, Command_Map *parent){
|
||||
max = ((max < 6)?(6):(max));
|
||||
commands->parent = parent;
|
||||
commands->commands = push_array(part, Command_Binding, max);
|
||||
memset(commands->commands, 0, max*sizeof(*commands->commands));
|
||||
commands->vanilla_keyboard_default = {};
|
||||
commands->max = max;
|
||||
commands->count = 0;
|
||||
}
|
||||
|
||||
internal void
|
||||
map_get_vanilla_keyboard_default(Command_Map *map, u8 command,
|
||||
Command_Binding *bind_out){
|
||||
if (command == MDFR_NONE){
|
||||
*bind_out = map->vanilla_keyboard_default;
|
||||
}
|
||||
}
|
||||
|
||||
inline u8
|
||||
apply_shift_to_code(u8 keycode){
|
||||
return !(keycode >= 0x20 && keycode < 0x7F && keycode != ' ');
|
||||
}
|
||||
|
||||
internal Command_Binding
|
||||
map_extract(Command_Map *map, Key_Event_Data key){
|
||||
Command_Binding bind = {};
|
||||
|
||||
b32 ctrl = key.modifiers[CONTROL_KEY_CONTROL];
|
||||
b32 alt = key.modifiers[CONTROL_KEY_ALT];
|
||||
b32 shift = key.modifiers[CONTROL_KEY_SHIFT];
|
||||
u16 code;
|
||||
u8 command = MDFR_NONE;
|
||||
|
||||
//if (key.character_no_caps_lock != 0 &&
|
||||
// key.character_no_caps_lock != ' ') shift = 0;
|
||||
|
||||
if (shift) command |= MDFR_SHIFT;
|
||||
if (ctrl) command |= MDFR_CTRL;
|
||||
if (alt) command |= MDFR_ALT;
|
||||
|
||||
code = key.character_no_caps_lock;
|
||||
if (code == 0){
|
||||
code = key.keycode;
|
||||
map_find(map, code, command, &bind);
|
||||
}
|
||||
else{
|
||||
if (code != '\n' && code != '\t' && code != ' '){
|
||||
command &= ~(MDFR_SHIFT);
|
||||
}
|
||||
|
||||
map_find(map, code, command, &bind);
|
||||
if (bind.function == 0){
|
||||
map_get_vanilla_keyboard_default(map, command, &bind);
|
||||
}
|
||||
}
|
||||
|
||||
return bind;
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
|
@ -1203,16 +1203,30 @@ file_init_strings(Editing_File *file){
|
|||
file->name.extension = make_fixed_width_string(file->name.extension_);
|
||||
}
|
||||
|
||||
inline b32
|
||||
file_is_ready(Editing_File *file){
|
||||
b32 result = 0;
|
||||
if (file && file->state.is_loading == 0){
|
||||
result = 1;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline void
|
||||
file_set_name(Editing_File *file, char *filename){
|
||||
file_set_name(Working_Set *working_set, Editing_File *file, char *filename){
|
||||
String f, ext;
|
||||
Editing_File *file_ptr;
|
||||
i32 i, count, file_x, original_len;
|
||||
b32 hit_conflict;
|
||||
|
||||
Assert(file->name.live_name.str != 0);
|
||||
|
||||
f = make_string_slowly(filename);
|
||||
copy_checked(&file->name.source_path, f);
|
||||
|
||||
file->name.live_name.size = 0;
|
||||
get_front_of_directory(&file->name.live_name, f);
|
||||
|
||||
if (file->name.source_path.size == file->name.live_name.size){
|
||||
file->name.extension.size = 0;
|
||||
}
|
||||
|
@ -1220,6 +1234,31 @@ file_set_name(Editing_File *file, char *filename){
|
|||
ext = file_extension(f);
|
||||
copy(&file->name.extension, ext);
|
||||
}
|
||||
|
||||
original_len = file->name.live_name.size;
|
||||
count = working_set->file_index_count;
|
||||
hit_conflict = 1;
|
||||
file_x = 0;
|
||||
while (hit_conflict){
|
||||
hit_conflict = 0;
|
||||
file_ptr = working_set->files;
|
||||
for (i = 0; i < count; ++i, ++file_ptr){
|
||||
if (file_ptr != file && !file_ptr->state.is_dummy && file_is_ready(file_ptr)){
|
||||
if (match(file->name.live_name, file_ptr->name.live_name)){
|
||||
++file_x;
|
||||
hit_conflict = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hit_conflict){
|
||||
file->name.live_name.size = original_len;
|
||||
append(&file->name.live_name, " <");
|
||||
append_int_to_str(file_x, &file->name.live_name);
|
||||
append(&file->name.live_name, ">");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
|
@ -1271,11 +1310,12 @@ file_save(System_Functions *system, Exchange *exchange, Mem_Options *mem,
|
|||
|
||||
inline b32
|
||||
file_save_and_set_names(System_Functions *system, Exchange *exchange,
|
||||
Mem_Options *mem, Editing_File *file, char *filename){
|
||||
Mem_Options *mem, Working_Set *working_set, Editing_File *file,
|
||||
char *filename){
|
||||
b32 result = 0;
|
||||
result = file_save(system, exchange, mem, file, filename);
|
||||
if (result){
|
||||
file_set_name(file, filename);
|
||||
file_set_name(working_set, file, filename);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -1501,9 +1541,10 @@ alloc_for_buffer(void *context, int *size){
|
|||
|
||||
internal void
|
||||
file_create_from_string(System_Functions *system, Mem_Options *mem,
|
||||
Editing_File *file, char *filename,
|
||||
Font_Set *set, i16 font_id,
|
||||
String val, b8 super_locked = 0){
|
||||
Working_Set *working_set, Editing_File *file, char *filename,
|
||||
Font_Set *set, i16 font_id,
|
||||
String val, b8 super_locked = 0){
|
||||
|
||||
General_Memory *general = &mem->general;
|
||||
Partition *part = &mem->part;
|
||||
Buffer_Init_Type init;
|
||||
|
@ -1529,7 +1570,7 @@ file_create_from_string(System_Functions *system, Mem_Options *mem,
|
|||
#endif
|
||||
|
||||
file_init_strings(file);
|
||||
file_set_name(file, (char*)filename);
|
||||
file_set_name(working_set, file, (char*)filename);
|
||||
|
||||
file->state.font_id = font_id;
|
||||
|
||||
|
@ -1570,20 +1611,25 @@ file_create_from_string(System_Functions *system, Mem_Options *mem,
|
|||
}
|
||||
|
||||
internal b32
|
||||
file_create_empty(System_Functions *system, Mem_Options *mem, Editing_File *file,
|
||||
char *filename, Font_Set *set, i16 font_id){
|
||||
file_create_empty(
|
||||
System_Functions *system, Mem_Options *mem,
|
||||
Working_Set *working_set, Editing_File *file,
|
||||
char *filename, Font_Set *set, i16 font_id){
|
||||
|
||||
b32 result = 1;
|
||||
String empty_str = {};
|
||||
file_create_from_string(system, mem, file, filename, set, font_id, empty_str);
|
||||
file_create_from_string(system, mem, working_set, file, filename, set, font_id, empty_str);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal b32
|
||||
file_create_super_locked(System_Functions *system, Mem_Options *mem, Editing_File *file,
|
||||
char *filename, Font_Set *set, i16 font_id){
|
||||
file_create_super_locked(
|
||||
System_Functions *system, Mem_Options *mem,
|
||||
Working_Set *working_set, Editing_File *file,
|
||||
char *filename, Font_Set *set, i16 font_id){
|
||||
b32 result = 1;
|
||||
String empty_str = {};
|
||||
file_create_from_string(system, mem, file, filename, set, font_id, empty_str, 1);
|
||||
file_create_from_string(system, mem, working_set, file, filename, set, font_id, empty_str, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1671,15 +1717,6 @@ file_set_to_loading(Editing_File *file){
|
|||
file->state.is_loading = 1;
|
||||
}
|
||||
|
||||
inline b32
|
||||
file_is_ready(Editing_File *file){
|
||||
b32 result = 0;
|
||||
if (file && file->state.is_loading == 0){
|
||||
result = 1;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
struct Shift_Information{
|
||||
i32 start, end, amount;
|
||||
};
|
||||
|
@ -2826,14 +2863,6 @@ file_do_single_edit(System_Functions *system,
|
|||
void *old_data = buffer_edit_provide_memory(&file->state.buffer, new_data, request_amount);
|
||||
if (old_data) general_memory_free(general, old_data);
|
||||
}
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL == 3
|
||||
buffer_rope_check(&file->buffer, part->base + part->pos, scratch_size);
|
||||
#endif
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL == 2
|
||||
buffer_mugab_check(&file->buffer);
|
||||
#endif
|
||||
|
||||
i32 line_start = buffer_get_line_index(&file->state.buffer, start);
|
||||
i32 line_end = buffer_get_line_index(&file->state.buffer, end);
|
||||
|
@ -3544,8 +3573,8 @@ view_auto_tab_tokens(System_Functions *system,
|
|||
i32 start = file->state.buffer.line_starts[line_i];
|
||||
i32 preferred_indentation;
|
||||
i32 correct_indentation;
|
||||
bool32 all_whitespace = 0;
|
||||
bool32 all_space = 0;
|
||||
b32 all_whitespace = 0;
|
||||
b32 all_space = 0;
|
||||
i32 hard_start =
|
||||
buffer_find_hard_start(&file->state.buffer, start, &all_whitespace, &all_space,
|
||||
&preferred_indentation, 4);
|
||||
|
@ -3565,6 +3594,7 @@ view_auto_tab_tokens(System_Functions *system,
|
|||
new_edit.end = hard_start;
|
||||
edits[edit_count++] = new_edit;
|
||||
}
|
||||
|
||||
Assert(edit_count <= edit_max);
|
||||
}
|
||||
|
||||
|
@ -3583,6 +3613,18 @@ view_auto_tab_tokens(System_Functions *system,
|
|||
view_do_white_batch_edit(system, mem, view, file, layout, spec, hist_normal);
|
||||
}
|
||||
|
||||
{
|
||||
b32 all_whitespace = 0;
|
||||
b32 all_space = 0;
|
||||
i32 preferred_indentation;
|
||||
i32 start = view->cursor.pos;
|
||||
i32 hard_start = buffer_find_hard_start(
|
||||
&file->state.buffer, start, &all_whitespace, &all_space,
|
||||
&preferred_indentation, 4);
|
||||
|
||||
view_cursor_move(view, hard_start);
|
||||
}
|
||||
|
||||
end_temp_memory(temp);
|
||||
#endif
|
||||
}
|
||||
|
|
1072
4ed_layout.cpp
1072
4ed_layout.cpp
File diff suppressed because it is too large
Load Diff
1006
4ed_rendering.cpp
1006
4ed_rendering.cpp
File diff suppressed because it is too large
Load Diff
|
@ -1,241 +1,267 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 12.17.2014
|
||||
*
|
||||
* Rendering layer for project codename "4ed"
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
inline void
|
||||
draw_push_clip(Render_Target *target, i32_Rect clip_box){
|
||||
target->push_clip(target, clip_box);
|
||||
}
|
||||
|
||||
inline void
|
||||
draw_pop_clip(Render_Target *target){
|
||||
target->pop_clip(target);
|
||||
}
|
||||
|
||||
internal void
|
||||
begin_render_section(Render_Target *target, System_Functions *system){
|
||||
Font_Set *font_set = &target->font_set;
|
||||
system->acquire_lock(RENDER_LOCK);
|
||||
font_set->used_this_frame = 0;
|
||||
memset(font_set->font_used_flags, 0, font_set->max);
|
||||
target->size = 0;
|
||||
target->clip_top = -1;
|
||||
|
||||
i32_Rect clip;
|
||||
clip.x0 = 0;
|
||||
clip.y0 = 0;
|
||||
clip.x1 = target->width;
|
||||
clip.y1 = target->height;
|
||||
draw_push_clip(target, clip);
|
||||
}
|
||||
|
||||
internal void
|
||||
end_render_section(Render_Target *target, System_Functions *system){
|
||||
Assert(target->clip_top == 0);
|
||||
system->release_lock(RENDER_LOCK);
|
||||
}
|
||||
|
||||
internal void
|
||||
draw_rectangle(Render_Target *target, i32_Rect rect, u32 color){
|
||||
Render_Piece_Combined piece;
|
||||
piece.header.type = piece_type_rectangle;
|
||||
piece.rectangle.rect = f32R(rect);
|
||||
piece.rectangle.color = color;
|
||||
target->push_piece(target, piece);
|
||||
}
|
||||
|
||||
internal void
|
||||
draw_rectangle(Render_Target *target, f32_Rect rect, u32 color){
|
||||
Render_Piece_Combined piece;
|
||||
piece.header.type = piece_type_rectangle;
|
||||
piece.rectangle.rect = rect;
|
||||
piece.rectangle.color = color;
|
||||
target->push_piece(target, piece);
|
||||
}
|
||||
|
||||
internal void
|
||||
draw_gradient_2corner_clipped(Render_Target *target, f32_Rect rect,
|
||||
Vec4 left_color, Vec4 right_color){
|
||||
Render_Piece_Combined piece;
|
||||
piece.header.type = piece_type_gradient;
|
||||
piece.gradient.rect = rect;
|
||||
piece.gradient.left_color = pack_color4(left_color);
|
||||
piece.gradient.right_color = pack_color4(right_color);
|
||||
target->push_piece(target, piece);
|
||||
}
|
||||
|
||||
inline void
|
||||
draw_gradient_2corner_clipped(Render_Target *target, f32 l, f32 t, f32 r, f32 b,
|
||||
Vec4 color_left, Vec4 color_right){
|
||||
draw_gradient_2corner_clipped(target, f32R(l,t,r,b), color_left, color_right);
|
||||
}
|
||||
|
||||
internal void
|
||||
draw_rectangle_outline(Render_Target *target, f32_Rect rect, u32 color){
|
||||
Render_Piece_Combined piece;
|
||||
piece.header.type = piece_type_outline;
|
||||
piece.rectangle.rect = rect;
|
||||
piece.rectangle.color = color;
|
||||
target->push_piece(target, piece);
|
||||
}
|
||||
|
||||
inline void
|
||||
draw_rectangle_outline(Render_Target *target, i32_Rect rect, u32 color){
|
||||
draw_rectangle_outline(target, f32R(rect), color);
|
||||
}
|
||||
|
||||
internal void
|
||||
draw_margin(Render_Target *target, i32_Rect outer, i32_Rect inner, u32 color){
|
||||
draw_rectangle(target, i32R(outer.x0, outer.y0, outer.x1, inner.y0), color);
|
||||
draw_rectangle(target, i32R(outer.x0, inner.y1, outer.x1, outer.y1), color);
|
||||
draw_rectangle(target, i32R(outer.x0, inner.y0, inner.x0, inner.y1), color);
|
||||
draw_rectangle(target, i32R(inner.x1, inner.y0, outer.x1, inner.y1), color);
|
||||
}
|
||||
|
||||
inline void
|
||||
draw_margin(Render_Target *target, i32_Rect outer, i32 width, u32 color){
|
||||
i32_Rect inner = get_inner_rect(outer, width);
|
||||
draw_margin(target, outer, inner, color);
|
||||
}
|
||||
|
||||
inline internal i32
|
||||
font_predict_size(i32 pt_size){
|
||||
return pt_size*pt_size*128;
|
||||
}
|
||||
|
||||
internal void
|
||||
font_set_tabwidth(Render_Font *font, i32 tab_width){
|
||||
font->chardata['\t'].xadvance *= font->chardata[' '].xadvance * tab_width;
|
||||
}
|
||||
|
||||
internal void
|
||||
font_draw_glyph_mono(Render_Target *target, i16 font_id,
|
||||
u8 character, f32 x, f32 y, f32 advance, u32 color){
|
||||
Render_Piece_Combined piece;
|
||||
piece.header.type = piece_type_mono_glyph;
|
||||
piece.glyph.pos.x = x;
|
||||
piece.glyph.pos.y = y;
|
||||
piece.glyph.color = color;
|
||||
piece.glyph.font_id = font_id;
|
||||
piece.glyph.character = character;
|
||||
target->push_piece(target, piece);
|
||||
font_set_use(target->partition, &target->font_set, font_id);
|
||||
}
|
||||
|
||||
inline void
|
||||
font_draw_glyph_mono(Render_Target *target, i16 font_id,
|
||||
u8 character, f32 x, f32 y, u32 color){
|
||||
f32 advance = (f32)get_font_info(&target->font_set, font_id)->advance;
|
||||
font_draw_glyph_mono(target, font_id, character, x, y, advance, color);
|
||||
}
|
||||
|
||||
internal void
|
||||
font_draw_glyph(Render_Target *target, i16 font_id,
|
||||
u8 character, f32 x, f32 y, u32 color){
|
||||
Render_Piece_Combined piece;
|
||||
piece.header.type = piece_type_glyph;
|
||||
piece.glyph.pos.x = x;
|
||||
piece.glyph.pos.y = y;
|
||||
piece.glyph.color = color;
|
||||
piece.glyph.font_id = font_id;
|
||||
piece.glyph.character = character;
|
||||
target->push_piece(target, piece);
|
||||
font_set_use(target->partition, &target->font_set, font_id);
|
||||
}
|
||||
|
||||
inline f32
|
||||
font_get_glyph_width(Render_Target *target, i16 font_id, u16 character){
|
||||
Render_Font *font = get_font_info(&target->font_set, font_id)->font;
|
||||
f32 result = 0.f;
|
||||
if (font) result = font->chardata[character].xadvance;
|
||||
return (result);
|
||||
}
|
||||
|
||||
internal f32
|
||||
font_string_width(Render_Target *target, i16 font_id, char *str){
|
||||
f32 x = 0;
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
x += font_get_glyph_width(target, font_id, str[i]);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
internal i32
|
||||
draw_string(Render_Target *target, i16 font_id,
|
||||
char *str, i32 x_, i32 y, u32 color){
|
||||
real32 x = (real32)x_;
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
char c = str[i];
|
||||
font_draw_glyph(target, font_id, c, x, (f32)y, color);
|
||||
x += font_get_glyph_width(target, font_id, c);
|
||||
}
|
||||
return CEIL32(x);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string_mono(Render_Target *target, i16 font_id,
|
||||
char *str, f32 x, f32 y, f32 advance, u32 color){
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
font_draw_glyph_mono(target, font_id, str[i],
|
||||
x, y, advance, color);
|
||||
x += advance;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
internal i32
|
||||
draw_string(Render_Target *target, i16 font_id,
|
||||
String str, i32 x_, i32 y, u32 color){
|
||||
f32 x = (f32)x_;
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
char c = str.str[i];
|
||||
font_draw_glyph(target, font_id, c,
|
||||
x, (f32)y, color);
|
||||
x += font_get_glyph_width(target, font_id, c);
|
||||
}
|
||||
return CEIL32(x);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string_mono(Render_Target *target, i16 font_id,
|
||||
String str, f32 x, f32 y, f32 advance, u32 color){
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
font_draw_glyph_mono(target, font_id,
|
||||
str.str[i], x, y, advance, color);
|
||||
x += advance;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
internal f32
|
||||
font_get_max_width(Font_Set *font_set, i16 font_id, char *characters){
|
||||
Render_Font *font = get_font_info(font_set, font_id)->font;
|
||||
f32 cx, x = 0;
|
||||
if (font){
|
||||
stbtt_packedchar *chardata = font->chardata;
|
||||
for (i32 i = 0; characters[i]; ++i){
|
||||
cx = chardata[characters[i]].xadvance;
|
||||
if (x < cx) x = cx;
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
internal f32
|
||||
font_get_string_width(Render_Target *target, i16 font_id, String string){
|
||||
f32 result = 0;
|
||||
for (i32 i = 0; i < string.size; ++i){
|
||||
font_get_glyph_width(target, font_id, string.str[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 12.17.2014
|
||||
*
|
||||
* Rendering layer for project codename "4ed"
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
inline void
|
||||
draw_push_clip(Render_Target *target, i32_Rect clip_box){
|
||||
target->push_clip(target, clip_box);
|
||||
}
|
||||
|
||||
inline void
|
||||
draw_pop_clip(Render_Target *target){
|
||||
target->pop_clip(target);
|
||||
}
|
||||
|
||||
internal void
|
||||
begin_render_section(Render_Target *target, System_Functions *system){
|
||||
Font_Set *font_set = &target->font_set;
|
||||
system->acquire_lock(RENDER_LOCK);
|
||||
font_set->used_this_frame = 0;
|
||||
memset(font_set->font_used_flags, 0, font_set->max);
|
||||
target->size = 0;
|
||||
target->clip_top = -1;
|
||||
|
||||
i32_Rect clip;
|
||||
clip.x0 = 0;
|
||||
clip.y0 = 0;
|
||||
clip.x1 = target->width;
|
||||
clip.y1 = target->height;
|
||||
draw_push_clip(target, clip);
|
||||
}
|
||||
|
||||
internal void
|
||||
end_render_section(Render_Target *target, System_Functions *system){
|
||||
Assert(target->clip_top == 0);
|
||||
system->release_lock(RENDER_LOCK);
|
||||
}
|
||||
|
||||
internal void
|
||||
draw_rectangle(Render_Target *target, i32_Rect rect, u32 color){
|
||||
Render_Piece_Combined piece;
|
||||
piece.header.type = piece_type_rectangle;
|
||||
piece.rectangle.rect = f32R(rect);
|
||||
piece.rectangle.color = color;
|
||||
target->push_piece(target, piece);
|
||||
}
|
||||
|
||||
internal void
|
||||
draw_rectangle(Render_Target *target, f32_Rect rect, u32 color){
|
||||
Render_Piece_Combined piece;
|
||||
piece.header.type = piece_type_rectangle;
|
||||
piece.rectangle.rect = rect;
|
||||
piece.rectangle.color = color;
|
||||
target->push_piece(target, piece);
|
||||
}
|
||||
|
||||
internal void
|
||||
draw_gradient_2corner_clipped(Render_Target *target, f32_Rect rect,
|
||||
Vec4 left_color, Vec4 right_color){
|
||||
Render_Piece_Combined piece;
|
||||
piece.header.type = piece_type_gradient;
|
||||
piece.gradient.rect = rect;
|
||||
piece.gradient.left_color = pack_color4(left_color);
|
||||
piece.gradient.right_color = pack_color4(right_color);
|
||||
target->push_piece(target, piece);
|
||||
}
|
||||
|
||||
inline void
|
||||
draw_gradient_2corner_clipped(Render_Target *target, f32 l, f32 t, f32 r, f32 b,
|
||||
Vec4 color_left, Vec4 color_right){
|
||||
draw_gradient_2corner_clipped(target, f32R(l,t,r,b), color_left, color_right);
|
||||
}
|
||||
|
||||
internal void
|
||||
draw_rectangle_outline(Render_Target *target, f32_Rect rect, u32 color){
|
||||
Render_Piece_Combined piece;
|
||||
piece.header.type = piece_type_outline;
|
||||
piece.rectangle.rect = rect;
|
||||
piece.rectangle.color = color;
|
||||
target->push_piece(target, piece);
|
||||
}
|
||||
|
||||
inline void
|
||||
draw_rectangle_outline(Render_Target *target, i32_Rect rect, u32 color){
|
||||
draw_rectangle_outline(target, f32R(rect), color);
|
||||
}
|
||||
|
||||
internal void
|
||||
draw_margin(Render_Target *target, i32_Rect outer, i32_Rect inner, u32 color){
|
||||
draw_rectangle(target, i32R(outer.x0, outer.y0, outer.x1, inner.y0), color);
|
||||
draw_rectangle(target, i32R(outer.x0, inner.y1, outer.x1, outer.y1), color);
|
||||
draw_rectangle(target, i32R(outer.x0, inner.y0, inner.x0, inner.y1), color);
|
||||
draw_rectangle(target, i32R(inner.x1, inner.y0, outer.x1, inner.y1), color);
|
||||
}
|
||||
|
||||
inline void
|
||||
draw_margin(Render_Target *target, i32_Rect outer, i32 width, u32 color){
|
||||
i32_Rect inner = get_inner_rect(outer, width);
|
||||
draw_margin(target, outer, inner, color);
|
||||
}
|
||||
|
||||
inline internal i32
|
||||
font_predict_size(i32 pt_size){
|
||||
return pt_size*pt_size*128;
|
||||
}
|
||||
|
||||
internal void
|
||||
font_set_tabwidth(Render_Font *font, i32 tab_width){
|
||||
font->chardata['\t'].xadvance *= font->chardata[' '].xadvance * tab_width;
|
||||
}
|
||||
|
||||
internal void
|
||||
font_draw_glyph_mono(Render_Target *target, i16 font_id,
|
||||
u8 character, f32 x, f32 y, f32 advance, u32 color){
|
||||
Render_Piece_Combined piece;
|
||||
piece.header.type = piece_type_mono_glyph;
|
||||
piece.glyph.pos.x = x;
|
||||
piece.glyph.pos.y = y;
|
||||
piece.glyph.color = color;
|
||||
piece.glyph.font_id = font_id;
|
||||
piece.glyph.character = character;
|
||||
target->push_piece(target, piece);
|
||||
font_set_use(target->partition, &target->font_set, font_id);
|
||||
}
|
||||
|
||||
inline void
|
||||
font_draw_glyph_mono(Render_Target *target, i16 font_id,
|
||||
u8 character, f32 x, f32 y, u32 color){
|
||||
f32 advance = (f32)get_font_info(&target->font_set, font_id)->advance;
|
||||
font_draw_glyph_mono(target, font_id, character, x, y, advance, color);
|
||||
}
|
||||
|
||||
internal void
|
||||
font_draw_glyph(Render_Target *target, i16 font_id,
|
||||
u8 character, f32 x, f32 y, u32 color){
|
||||
Render_Piece_Combined piece;
|
||||
piece.header.type = piece_type_glyph;
|
||||
piece.glyph.pos.x = x;
|
||||
piece.glyph.pos.y = y;
|
||||
piece.glyph.color = color;
|
||||
piece.glyph.font_id = font_id;
|
||||
piece.glyph.character = character;
|
||||
target->push_piece(target, piece);
|
||||
font_set_use(target->partition, &target->font_set, font_id);
|
||||
}
|
||||
|
||||
inline f32
|
||||
font_get_glyph_width(Render_Target *target, i16 font_id, u16 character){
|
||||
Render_Font *font = get_font_info(&target->font_set, font_id)->font;
|
||||
f32 result = 0.f;
|
||||
if (font) result = font->chardata[character].xadvance;
|
||||
return (result);
|
||||
}
|
||||
|
||||
internal f32
|
||||
font_string_width(Render_Target *target, i16 font_id, char *str){
|
||||
f32 x = 0;
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
u8 c = str[i];
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
c = c % 128;
|
||||
x += font_get_glyph_width(target, font_id, c);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
internal f32
|
||||
font_string_width(Render_Target *target, i16 font_id, String str){
|
||||
f32 x = 0;
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
u8 c = str.str[i];
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
c = c % 128;
|
||||
x += font_get_glyph_width(target, font_id, c);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
internal i32
|
||||
draw_string(Render_Target *target, i16 font_id,
|
||||
char *str, i32 x_, i32 y, u32 color){
|
||||
real32 x = (real32)x_;
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
u8 c = str[i];
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
c = c % 128;
|
||||
font_draw_glyph(target, font_id, c, x, (f32)y, color);
|
||||
x += font_get_glyph_width(target, font_id, c);
|
||||
}
|
||||
return CEIL32(x);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string_mono(Render_Target *target, i16 font_id,
|
||||
char *str, f32 x, f32 y, f32 advance, u32 color){
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
u8 c = str[i];
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
c = c % 128;
|
||||
font_draw_glyph_mono(target, font_id, c, x, y, advance, color);
|
||||
x += advance;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
internal i32
|
||||
draw_string(Render_Target *target, i16 font_id,
|
||||
String str, i32 x_, i32 y, u32 color){
|
||||
f32 x = (f32)x_;
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
u8 c = str.str[i];
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
c = c % 128;
|
||||
font_draw_glyph(target, font_id, c,
|
||||
x, (f32)y, color);
|
||||
x += font_get_glyph_width(target, font_id, c);
|
||||
}
|
||||
return CEIL32(x);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string_mono(Render_Target *target, i16 font_id,
|
||||
String str, f32 x, f32 y, f32 advance, u32 color){
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
u8 c = str.str[i];
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
c = c % 128;
|
||||
font_draw_glyph_mono(target, font_id, c, x, y, advance, color);
|
||||
x += advance;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
internal f32
|
||||
font_get_max_width(Font_Set *font_set, i16 font_id, char *characters){
|
||||
Render_Font *font = get_font_info(font_set, font_id)->font;
|
||||
f32 cx, x = 0;
|
||||
if (font){
|
||||
stbtt_packedchar *chardata = font->chardata;
|
||||
for (i32 i = 0; characters[i]; ++i){
|
||||
cx = chardata[characters[i]].xadvance;
|
||||
if (x < cx) x = cx;
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
internal f32
|
||||
font_get_string_width(Render_Target *target, i16 font_id, String string){
|
||||
f32 result = 0;
|
||||
for (i32 i = 0; i < string.size; ++i){
|
||||
u8 c = string.str[i];
|
||||
// TODO(allen): Someday let's not punt on the the unicode rendering
|
||||
c = c % 128;
|
||||
font_get_glyph_width(target, font_id, c);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
|
@ -1061,100 +1061,6 @@ main(int argc, char **argv)
|
|||
}break;
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
if((Event.xcookie.type == GenericEvent) &&
|
||||
(Event.xcookie.extension == XInput2OpCode) &&
|
||||
XGetEventData(linuxvars.XDisplay, &Event.xcookie))
|
||||
{
|
||||
switch(Event.xcookie.evtype)
|
||||
{
|
||||
case XI_Motion:
|
||||
{
|
||||
Window root_return, child_return;
|
||||
int root_x_return, root_y_return;
|
||||
int MouseX, MouseY;
|
||||
unsigned int mask_return;
|
||||
XQueryPointer(linuxvars.XDisplay,
|
||||
linuxvars.XWindow,
|
||||
&root_return, &child_return,
|
||||
&root_x_return, &root_y_return,
|
||||
&MouseX, &MouseY,
|
||||
&mask_return);
|
||||
} break;
|
||||
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
{
|
||||
b32 Down = (Event.xcookie.evtype == XI_ButtonPress);
|
||||
XIDeviceEvent *DevEvent = (XIDeviceEvent *)Event.xcookie.data;
|
||||
int Button = DevEvent->detail;
|
||||
} break;
|
||||
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
{
|
||||
b32 Down = (Event.xcookie.evtype == XI_KeyPress);
|
||||
XIDeviceEvent *DevEvent = (XIDeviceEvent *)Event.xcookie.data;
|
||||
int keycode = DevEvent->detail;
|
||||
|
||||
if (Down){
|
||||
printf("Keycode %d\n", keycode);
|
||||
|
||||
// NOTE(allen): Thanks to eisbehr for providing the code
|
||||
// for initializing an XKeyPressedEvent struct for use in
|
||||
// Xmb8LookupString
|
||||
XKeyPressedEvent eventBase = {};
|
||||
eventBase.type = KeyPress;
|
||||
eventBase.serial = 0xF00D;
|
||||
eventBase.send_event = 1; // at least admit that this isn't a genuine event
|
||||
eventBase.display = DevEvent->display;
|
||||
eventBase.window = DevEvent->event;
|
||||
eventBase.root = DevEvent->root;
|
||||
eventBase.subwindow = 0;
|
||||
eventBase.time = {}; // Let's hope we don't need a real time.
|
||||
eventBase.x = 0;
|
||||
eventBase.y = 0;
|
||||
eventBase.x_root = 0;
|
||||
eventBase.y_root = 0;
|
||||
eventBase.state = 0; // state of modifiers
|
||||
// Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask,
|
||||
// ShiftMask, LockMask, ControlMask,
|
||||
// Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask.
|
||||
//eventBase.keycode = 10;//minKeyCode;
|
||||
eventBase.same_screen = 1;
|
||||
|
||||
eventBase.keycode = keycode;
|
||||
|
||||
char lookup_buffer[32];
|
||||
Status status;
|
||||
i32 size;
|
||||
KeySym keysym;
|
||||
|
||||
size = XmbLookupString(linuxvars.xic, &eventBase,
|
||||
lookup_buffer, sizeof(lookup_buffer),
|
||||
&keysym, &status);
|
||||
|
||||
if (status == XBufferOverflow){
|
||||
printf("Buffer overflow %d\n", size);
|
||||
}
|
||||
else if (status == XLookupNone){
|
||||
printf("nothing branch\n");
|
||||
}
|
||||
else if (status == XLookupChars || status == XLookupBoth){
|
||||
printf("keysym %lu translation: %.*s\n", keysym, size, lookup_buffer);
|
||||
}
|
||||
else{
|
||||
printf("unknown branch %d\n", status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
XFreeEventData(linuxvars.XDisplay, &Event.xcookie);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
b32 redraw = 1;
|
||||
|
|
|
@ -37,12 +37,14 @@ struct Font_Load_System{
|
|||
#define Sys_File_Can_Be_Made(name) b32 name(char *filename)
|
||||
#define Sys_Load_File_Sig(name) Data name(char *filename)
|
||||
#define Sys_Save_File_Sig(name) b32 name(char *filename, char *data, i32 size)
|
||||
#define Sys_To_Binary_Path(name) b32 name(String *out_filename, char *filename)
|
||||
|
||||
internal Sys_Get_Memory_Sig(system_get_memory_);
|
||||
internal Sys_Free_Memory_Sig(system_free_memory);
|
||||
internal Sys_File_Can_Be_Made(system_file_can_be_made);
|
||||
internal Sys_Load_File_Sig(system_load_file);
|
||||
internal Sys_Save_File_Sig(system_save_file);
|
||||
internal Sys_To_Binary_Path(system_to_binary_path);
|
||||
|
||||
#define system_get_memory(size) system_get_memory_((size), __LINE__, __FILE__)
|
||||
|
||||
|
|
3606
win32_4ed.cpp
3606
win32_4ed.cpp
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue