int _al_show_native_message_box(ALLEGRO_DISPLAY *display, ALLEGRO_NATIVE_DIALOG *fd) { UINT type = 0; int result; uint16_t *wide_text, *wide_title; size_t text_len, title_len; /* Note: the message box code cannot assume that Allegro is installed. */ if (fd->flags & ALLEGRO_MESSAGEBOX_QUESTION) type |= MB_ICONQUESTION; else if (fd->flags & ALLEGRO_MESSAGEBOX_WARN) type |= MB_ICONWARNING; else if (fd->flags & ALLEGRO_MESSAGEBOX_ERROR) type |= MB_ICONERROR; else type |= MB_ICONINFORMATION; if (fd->flags & ALLEGRO_MESSAGEBOX_YES_NO) type |= MB_YESNO; else if (fd->flags & ALLEGRO_MESSAGEBOX_OK_CANCEL) type |= MB_OKCANCEL; /* heading + text are combined together */ if (al_ustr_size(fd->mb_heading)) al_ustr_append_cstr(fd->mb_heading, "\n\n"); al_ustr_append(fd->mb_heading, fd->mb_text); text_len = al_ustr_size_utf16(fd->mb_heading); title_len = al_ustr_size_utf16(fd->title); wide_text = al_malloc(text_len + 1); if (!wide_text) return 0; wide_title = al_malloc(title_len + 1); if (!wide_title) { al_free(wide_text); return 0; } al_ustr_encode_utf16(fd->mb_heading, wide_text, text_len); al_ustr_encode_utf16(fd->title, wide_title, title_len); result = MessageBoxW(al_get_win_window_handle(display), (LPCWSTR) wide_text, (LPCWSTR) wide_title, type); al_free(wide_text); al_free(wide_title); if (result == IDYES || result == IDOK) return 1; else return 0; }
//return the new start int wz_find_eol(ALLEGRO_USTR* text, ALLEGRO_FONT* font, float max_width, int start, int* end) { int a, b; int first = 1; int last = 0; a = start; while(1) { ALLEGRO_USTR_INFO info; ALLEGRO_USTR* token; float len; /* Find the end of current token */ b = al_ustr_find_set_cstr(text, a, "\t\n "); if(b == -1) //found nothing { b = al_ustr_size(text); //this is the last whole word last = 1; } /* Check to see if the token fits */ token = al_ref_ustr(&info, text, start, b); len = al_get_ustr_width(font, token); if (len < max_width || first) { if(last) { *end = b + 1; return -1; } } else //we return the last num { *end = a - 1; return a; } /* Check what character we found */ { int character = al_ustr_get(text, b); if(character == '\n') { *end = b; return b + 1; } } a = b + 1; first = 0; } }
/* No memory needs to be freed. */ static void t4(void) { const char *s = "This contains an embedded NUL: \0 <-- here"; ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *us = al_ref_buffer(&info, s, sizeof(s)); CHECK(al_ustr_size(us) == sizeof(s)); CHECK(0 == memcmp(al_cstr(us), s, sizeof(s))); }
/* Function: al_ustr_append_chr */ size_t al_ustr_append_chr(ALLEGRO_USTR *us, int32_t c) { uint32_t uc = c; if (uc < 128) { return (_al_bconchar(us, uc) == _AL_BSTR_OK) ? 1 : 0; } return al_ustr_insert_chr(us, al_ustr_size(us), c); }
/* [gtk thread] */ static gboolean create_native_message_box(gpointer data) { Msg *msg = data; ALLEGRO_DISPLAY *display = msg->display; ALLEGRO_NATIVE_DIALOG *fd = msg->dialog; GtkWidget *window; /* Create a new file selection widget */ GtkMessageType type = GTK_MESSAGE_INFO; GtkButtonsType buttons = GTK_BUTTONS_OK; if (fd->flags & ALLEGRO_MESSAGEBOX_YES_NO) type = GTK_MESSAGE_QUESTION; if (fd->flags & ALLEGRO_MESSAGEBOX_QUESTION) type = GTK_MESSAGE_QUESTION; if (fd->flags & ALLEGRO_MESSAGEBOX_WARN) type = GTK_MESSAGE_WARNING; if (fd->flags & ALLEGRO_MESSAGEBOX_ERROR) type = GTK_MESSAGE_ERROR; if (fd->flags & ALLEGRO_MESSAGEBOX_YES_NO) buttons = GTK_BUTTONS_YES_NO; if (fd->flags & ALLEGRO_MESSAGEBOX_OK_CANCEL) buttons = GTK_BUTTONS_OK_CANCEL; if (fd->mb_buttons) buttons = GTK_BUTTONS_NONE; window = gtk_message_dialog_new(NULL, 0, type, buttons, "%s", al_cstr(fd->mb_heading)); gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(window), "%s", al_cstr(fd->mb_text)); make_transient(display, window); if (fd->mb_buttons) { int i = 1; int pos = 0; while (1) { int next = al_ustr_find_chr(fd->mb_buttons, pos, '|'); int pos2 = next; if (next == -1) pos2 = al_ustr_size(fd->mb_buttons); ALLEGRO_USTR_INFO info; const ALLEGRO_USTR *button_text; button_text = al_ref_ustr(&info, fd->mb_buttons, pos, pos2); pos = pos2 + 1; char buffer[256]; al_ustr_to_buffer(button_text, buffer, sizeof buffer); gtk_dialog_add_button(GTK_DIALOG(window), buffer, i++); if (next == -1) break; } } gtk_window_set_title(GTK_WINDOW(window), al_cstr(fd->title)); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(dialog_destroy), fd); g_signal_connect(G_OBJECT(window), "response", G_CALLBACK(msgbox_response), fd); g_signal_connect_swapped(G_OBJECT(window), "response", G_CALLBACK(gtk_widget_destroy), window); gtk_widget_show(window); return FALSE; }
/* Test that we can create and destroy strings and get their data and size. */ static void t1(void) { ALLEGRO_USTR *us1 = al_ustr_new(""); ALLEGRO_USTR *us2 = al_ustr_new("áƵ"); CHECK(0 == strcmp(al_cstr(us1), "")); CHECK(0 == strcmp(al_cstr(us2), "áƵ")); CHECK(4 == al_ustr_size(us2)); al_ustr_free(us1); al_ustr_free(us2); }
/* _find_executable_file: * Helper function: searches path and current directory for executable. * Returns 1 on succes, 0 on failure. */ static ALLEGRO_PATH *_find_executable_file(const char *filename) { char *env; /* If filename has an explicit path, search current directory */ if (strchr(filename, '/')) { if (filename[0] == '/') { /* Full path; done */ return al_create_path(filename); } else { struct stat finfo; char pathname[1024]; /* Prepend current directory */ ALLEGRO_PATH *path = al_get_current_directory(); al_append_path_component(path, filename); if ((stat(pathname, &finfo)==0) && (!S_ISDIR (finfo.st_mode))) { return path; } } } /* If filename has no explicit path, but we do have $PATH, search * there */ else if ((env = getenv("PATH"))) { struct stat finfo; ALLEGRO_USTR *us = al_ustr_new(env); int start_pos = 0; while (start_pos >= 0) { int next_start_pos = al_ustr_find_chr(us, start_pos + 1, ':'); int end_pos = next_start_pos; if (next_start_pos < 0) end_pos = al_ustr_size(us); ALLEGRO_USTR_INFO info; ALLEGRO_USTR *sub = al_ref_ustr(&info, us, start_pos, end_pos); ALLEGRO_PATH *path = al_create_path_for_directory(al_cstr(sub)); al_append_path_component(path, filename); if (stat(al_path_cstr(path, '/'), &finfo) == 0 && !S_ISDIR (finfo.st_mode)) { return path; } start_pos = next_start_pos; } } return NULL; }
/* Function: al_get_path_basename */ const char *al_get_path_basename(const ALLEGRO_PATH *path) { int dot; ASSERT(path); dot = al_ustr_rfind_chr(path->filename, al_ustr_size(path->filename), '.'); if (dot >= 0) { al_ustr_assign_substr(path->basename, path->filename, 0, dot); return al_cstr(path->basename); } return al_cstr(path->filename); }
/* Test al_ustr_assign, al_ustr_assign_cstr. */ static void t40(void) { ALLEGRO_USTR *us1 = al_ustr_new("我隻氣墊船裝滿晒鱔"); ALLEGRO_USTR *us2 = al_ustr_new("Τὸ χόβερκράφτ μου εἶναι γεμᾶτο χέλια"); CHECK(al_ustr_assign(us1, us2)); CHECK(0 == strcmp(al_cstr(us1), "Τὸ χόβερκράφτ μου εἶναι γεμᾶτο χέλια")); CHECK(al_ustr_assign_cstr(us1, "私のホバークラフトは鰻でいっぱいです")); CHECK(54 == al_ustr_size(us1)); al_ustr_free(us1); al_ustr_free(us2); }
/* An ALLEGRO_MENU_INFO structure represents a heirarchy of menus. This function * recursively steps through it and builds the entire menu. */ static ALLEGRO_MENU_INFO *parse_menu_info(ALLEGRO_MENU *parent, ALLEGRO_MENU_INFO *info) { ASSERT(parent); ASSERT(info); /* The end of the menu is marked by a NULL caption and an id of 0. */ while (info->caption || info->id) { if (!info->caption) { /* A separator */ al_append_menu_item(parent, NULL, 0, 0, NULL, NULL); ++info; } else if (strlen(info->caption) > 2 && !strncmp("->", info->caption + strlen(info->caption) - 2, 2)) { /* An item with a sub-menu has a -> marker as part of its caption. * (e.g., "File->"). */ ALLEGRO_MENU *menu = al_create_menu(); if (menu) { /* Strip the -> mark off the end. */ ALLEGRO_USTR *s = al_ustr_new(info->caption); al_ustr_remove_range(s, al_ustr_size(s) - 2, al_ustr_size(s)); al_append_menu_item(parent, al_cstr(s), info->id, 0, NULL, menu); info = parse_menu_info(menu, info + 1); al_ustr_free(s); } } else { /* Just ar regular item */ al_append_menu_item(parent, info->caption, info->id, info->flags, info->icon, NULL); ++info; } } return info + 1; }
/* Test al_ustr_set_chr. */ static void t42(void) { ALLEGRO_USTR *us = al_ustr_new("abcdef"); /* Same size (ASCII). */ CHECK(al_ustr_set_chr(us, 1, 'B') == 1); CHECK(0 == strcmp(al_cstr(us), "aBcdef")); CHECK(6 == al_ustr_size(us)); /* Enlarge to 2-bytes. */ CHECK(al_ustr_set_chr(us, 1, U_beta) == 2); CHECK(0 == strcmp(al_cstr(us), "aβcdef")); CHECK(7 == al_ustr_size(us)); /* Enlarge to 3-bytes. */ CHECK(al_ustr_set_chr(us, 5, U_1d08) == 3); CHECK(0 == strcmp(al_cstr(us), "aβcdᴈf")); CHECK(9 == al_ustr_size(us)); /* Reduce to 2-bytes. */ CHECK(al_ustr_set_chr(us, 5, U_schwa) == 2); CHECK(0 == strcmp(al_cstr(us), "aβcdəf")); CHECK(8 == al_ustr_size(us)); /* Set at end of string. */ CHECK(al_ustr_set_chr(us, al_ustr_size(us), U_1ff7) == 3); CHECK(0 == strcmp(al_cstr(us), "aβcdəfῷ")); CHECK(11 == al_ustr_size(us)); /* Set past end of string. */ CHECK(al_ustr_set_chr(us, al_ustr_size(us) + 2, U_2051) == 3); CHECK(0 == memcmp(al_cstr(us), "aβcdəfῷ\0\0⁑", 16)); CHECK(16 == al_ustr_size(us)); /* Set before start of string (not allowed). */ CHECK(al_ustr_set_chr(us, -1, U_2051) == 0); CHECK(16 == al_ustr_size(us)); al_ustr_free(us); }
/* Test al_ustr_rfind_str, al_ustr_rfind_cstr. */ static void t38(void) { ALLEGRO_USTR *us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); int end = al_ustr_size(us); /* al_ustr_find_cstr is s simple wrapper for al_ustr_find_str * so we test using that. */ CHECK(al_ustr_rfind_cstr(us, 0, "") == 0); CHECK(al_ustr_rfind_cstr(us, 1, "") == 1); CHECK(al_ustr_rfind_cstr(us, end, "hií") == end - 4); CHECK(al_ustr_rfind_cstr(us, end - 1, "hií") == 12); CHECK(al_ustr_rfind_cstr(us, end, "ábz") == -1); al_ustr_free(us); }
/* Test al_ustr_rfind_chr. */ static void t32(void) { ALLEGRO_USTR *us = al_ustr_new("aábdðeéfghiíaábdðeéfghií"); int end = al_ustr_size(us); /* Find ASCII. */ CHECK(al_ustr_rfind_chr(us, end, 'e') == 23); CHECK(al_ustr_rfind_chr(us, 23, 'e') == 7); /* end_pos exclusive */ CHECK(al_ustr_rfind_chr(us, end, '.') == -1); /* Find non-ASCII. */ CHECK(al_ustr_rfind_chr(us, end, U_i_acute) == 30); CHECK(al_ustr_rfind_chr(us, end - 1, U_i_acute) == 14); /* end_pos exclusive */ CHECK(al_ustr_rfind_chr(us, end, U_z_bar) == -1); al_ustr_free(us); }
/* Test al_ustr_prev_get. */ static void t30(void) { ALLEGRO_USTR *us = al_ustr_new("aþ€"); int pos; pos = al_ustr_size(us); CHECK(al_ustr_prev_get(us, &pos) == U_euro); CHECK(al_ustr_prev_get(us, &pos) == U_thorn); CHECK(al_ustr_prev_get(us, &pos) == 'a'); CHECK(al_ustr_prev_get(us, &pos) == -1); /* Start in the middle of þ. */ pos = 2; CHECK(al_ustr_prev_get(us, &pos) == U_thorn); al_ustr_free(us); }
void TextEntry::draw() { const Theme & theme = dialog->get_theme(); SaveState state; ALLEGRO_COLOR bg = theme.bg; if (is_disabled()) { bg = al_map_rgb(64, 64, 64); } al_draw_filled_rectangle(x1, y1, x2, y2, bg); al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); if (!focused) { al_draw_ustr(theme.font, theme.fg, x1, y1, 0, UString(text, left_pos)); } else { int x = x1; if (cursor_pos > 0) { UString sub(text, left_pos, cursor_pos); al_draw_ustr(theme.font, theme.fg, x1, y1, 0, sub); x += al_get_ustr_width(theme.font, sub); } if ((unsigned) cursor_pos == al_ustr_size(text)) { al_draw_filled_rectangle(x, y1, x + CURSOR_WIDTH, y1 + al_get_font_line_height(theme.font), theme.fg); } else { int post_cursor = cursor_pos; al_ustr_next(text, &post_cursor); UString sub(text, cursor_pos, post_cursor); int subw = al_get_ustr_width(theme.font, sub); al_draw_filled_rectangle(x, y1, x + subw, y1 + al_get_font_line_height(theme.font), theme.fg); al_draw_ustr(theme.font, theme.bg, x, y1, 0, sub); x += subw; al_draw_ustr(theme.font, theme.fg, x, y1, 0, UString(text, post_cursor)); } } }
void wz_snap_editbox(WZ_EDITBOX* box) { WZ_WIDGET* wgt = (WZ_WIDGET*)box; ALLEGRO_FONT* font = wgt->theme->get_font(wgt->theme, 0); int len = al_ustr_length(box->text); int size = al_ustr_size(box->text); int scroll_offset = al_ustr_offset(box->text, box->scroll_pos); int cursor_offset; ALLEGRO_USTR_INFO info; ALLEGRO_USTR* text = al_ref_ustr(&info, box->text, scroll_offset, size); int max_rel_cursor_pos = wz_get_text_pos(font, text, wgt->w); if (box->cursor_pos < box->scroll_pos) { box->scroll_pos = box->cursor_pos; } if (box->cursor_pos > box->scroll_pos + max_rel_cursor_pos) { box->scroll_pos = box->cursor_pos - max_rel_cursor_pos; } if (box->cursor_pos > 0 && box->cursor_pos - box->scroll_pos < 1) { box->scroll_pos--; } if (box->cursor_pos > len) { box->cursor_pos = len; } if (box->cursor_pos < 0) { box->cursor_pos = 0; } scroll_offset = al_ustr_offset(box->text, box->scroll_pos); cursor_offset = al_ustr_offset(box->text, box->cursor_pos); text = al_ref_ustr(&info, box->text, scroll_offset, cursor_offset); if (al_get_ustr_width(font, text) > wgt->w) { box->scroll_pos++; } }
static bool ljoy_detect_device_name(int num, ALLEGRO_USTR *device_name) { char key[80]; const char *value; struct stat stbuf; al_ustr_truncate(device_name, 0); snprintf(key, sizeof(key), "device%d", num); value = al_get_config_value(al_get_system_config(), "joystick", key); if (value) al_ustr_assign_cstr(device_name, value); if (al_ustr_size(device_name) == 0) al_ustr_appendf(device_name, "/dev/input/event%d", num); return (stat(al_cstr(device_name), &stbuf) == 0); }
/* Test al_ustr_get_next. */ static void t29(void) { ALLEGRO_USTR *us = al_ustr_new("aþ€"); int pos; pos = 0; CHECK(al_ustr_get_next(us, &pos) == 'a'); CHECK(al_ustr_get_next(us, &pos) == U_thorn); CHECK(al_ustr_get_next(us, &pos) == U_euro); CHECK(al_ustr_get_next(us, &pos) == -1); CHECK(pos == (int) al_ustr_size(us)); /* Start in the middle of þ. */ pos = 2; CHECK(al_ustr_get_next(us, &pos) == -2); CHECK(al_ustr_get_next(us, &pos) == U_euro); al_ustr_free(us); }
void TextEntry::on_key_down(const ALLEGRO_KEYBOARD_EVENT & event) { if (is_disabled()) return; switch (event.keycode) { case ALLEGRO_KEY_LEFT: al_ustr_prev(text, &cursor_pos); break; case ALLEGRO_KEY_RIGHT: al_ustr_next(text, &cursor_pos); break; case ALLEGRO_KEY_HOME: cursor_pos = 0; break; case ALLEGRO_KEY_END: cursor_pos = al_ustr_size(text); break; case ALLEGRO_KEY_DELETE: al_ustr_remove_chr(text, cursor_pos); break; case ALLEGRO_KEY_BACKSPACE: if (al_ustr_prev(text, &cursor_pos)) al_ustr_remove_chr(text, cursor_pos); break; default: if (event.unichar >= ' ') { al_ustr_insert_chr(text, cursor_pos, event.unichar); cursor_pos += al_utf8_width(event.unichar); } break; } maybe_scroll(); dialog->request_draw(); }
static bool fs_apk_change_directory(const char *path) { ALLEGRO_USTR *us; bool ret; /* Figure out which directory we are trying to change to. */ if (path_is_absolute(path)) us = al_ustr_new(path); else us = apply_cwd(path); ensure_trailing_slash(us); if ((size_t) al_ustr_size(us) < sizeof(fs_apk_cwd)) { al_ustr_to_buffer(us, fs_apk_cwd, sizeof(fs_apk_cwd)); ret = true; } al_ustr_free(us); return ret; }
/* Test al_ustr_prev. */ static void t26(void) { ALLEGRO_USTR *us = al_ustr_new("aþ€\xf4\x8f\xbf\xbf"); int pos = al_ustr_size(us); CHECK(al_ustr_prev(us, &pos)); /* U+10FFFF */ CHECK(pos == 6); CHECK(al_ustr_prev(us, &pos)); /* € */ CHECK(pos == 3); CHECK(al_ustr_prev(us, &pos)); /* þ */ CHECK(pos == 1); CHECK(al_ustr_prev(us, &pos)); /* a */ CHECK(pos == 0); CHECK(!al_ustr_prev(us, &pos)); /* begin */ CHECK(pos == 0); al_ustr_free(us); }
/* Test al_ustr_remove_chr. */ static void t43(void) { ALLEGRO_USTR *us = al_ustr_new("«aβῷ»"); CHECK(al_ustr_remove_chr(us, 2)); CHECK(0 == strcmp(al_cstr(us), "«βῷ»")); CHECK(al_ustr_remove_chr(us, 2)); CHECK(0 == strcmp(al_cstr(us), "«ῷ»")); CHECK(al_ustr_remove_chr(us, 2)); CHECK(0 == strcmp(al_cstr(us), "«»")); /* Not at beginning of code point. */ CHECK(! al_ustr_remove_chr(us, 1)); /* Out of bounds. */ CHECK(! al_ustr_remove_chr(us, -1)); CHECK(! al_ustr_remove_chr(us, al_ustr_size(us))); al_ustr_free(us); }
int _al_parse_key_binding(const char *s, unsigned int *modifiers) { ALLEGRO_USTR *us; unsigned start = 0; int keycode = 0; us = al_ustr_new(s); al_ustr_trim_ws(us); *modifiers = 0; while (start < al_ustr_size(us)) { /* XXX not all keys can be bound due to a conflict with the delimiter * characters */ int end = al_ustr_find_set_cstr(us, start, "+-"); unsigned int mod; /* Last component must be a key. */ if (end == -1) { keycode = match_key_name(al_cstr(us) + start); break; } /* Otherwise must be a modifier. */ al_ustr_set_chr(us, end, '\0'); mod = match_modifier(al_cstr(us) + start); if (!mod) { break; } (*modifiers) |= mod; start = end + 1; } al_ustr_free(us); return keycode; }
/* Function: al_is_path_present */ bool al_is_path_present(const ALLEGRO_PATH *path) { ALLEGRO_USTR *ustr; bool rc; ASSERT(path); ustr = al_ustr_new(""); path_to_ustr(path, ALLEGRO_NATIVE_PATH_SEP, ustr); /* Windows' stat() doesn't like the slash at the end of the path when * the path is pointing to a directory. There are other places which * might require the same fix. */ #ifdef ALLEGRO_WINDOWS if (al_ustr_has_suffix_cstr(ustr, "\\")) { al_ustr_truncate(ustr, al_ustr_size(ustr) - 1); } #endif rc = al_filename_exists(al_cstr(ustr)); al_ustr_free(ustr); return rc; }
/* Title: Edit Box Section: Internal Function: wz_editbox_proc See also: <wz_widget_proc> */ int wz_editbox_proc(WZ_WIDGET* wgt, ALLEGRO_EVENT* event) { int ret = 1; WZ_EDITBOX* box = (WZ_EDITBOX*)wgt; switch (event->type) { case WZ_DRAW: { if (wgt->flags & WZ_STATE_HIDDEN) { ret = 0; } else { int size = al_ustr_size(box->text); int scroll_offset = al_ustr_offset(box->text, box->scroll_pos); ALLEGRO_USTR_INFO info; ALLEGRO_USTR* text = al_ref_ustr(&info, box->text, scroll_offset, size); int pos = box->cursor_pos - box->scroll_pos; int flags = 0; if(wgt->flags & WZ_STATE_DISABLED) flags = WZ_STYLE_DISABLED; else if(wgt->flags & WZ_STATE_HAS_FOCUS) flags = WZ_STYLE_FOCUSED; wgt->theme->draw_editbox(wgt->theme, wgt->local_x, wgt->local_y, wgt->w, wgt->h, pos, text, flags); } break; } case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: { if (wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else if (event->mouse.button == 1 && wz_widget_rect_test(wgt, event->mouse.x, event->mouse.y)) { int len = al_ustr_length(box->text); ALLEGRO_USTR_INFO info; ALLEGRO_USTR* text = al_ref_ustr(&info, box->text, box->scroll_pos, len - 1); ALLEGRO_FONT* font = wgt->theme->get_font(wgt->theme, 0); wz_ask_parent_for_focus(wgt); box->cursor_pos = wz_get_text_pos(font, text, event->mouse.x - wgt->x) + box->scroll_pos; } else ret = 0; break; } #if (ALLEGRO_SUB_VERSION > 0) case ALLEGRO_EVENT_TOUCH_BEGIN: { if (wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else if (wz_widget_rect_test(wgt, event->touch.x, event->touch.y)) { int len = al_ustr_length(box->text); ALLEGRO_USTR_INFO info; ALLEGRO_USTR* text = al_ref_ustr(&info, box->text, box->scroll_pos, len - 1); ALLEGRO_FONT* font = wgt->theme->get_font(wgt->theme, 0); wz_ask_parent_for_focus(wgt); box->cursor_pos = wz_get_text_pos(font, text, event->touch.x - wgt->x) + box->scroll_pos; } else ret = 0; break; } #endif case WZ_HANDLE_SHORTCUT: { wz_ask_parent_for_focus(wgt); break; } case WZ_DESTROY: { if(box->own) al_ustr_free(box->text); ret = 0; break; } case ALLEGRO_EVENT_KEY_CHAR: { int len; if(wgt->flags & WZ_STATE_DISABLED || !(wgt->flags & WZ_STATE_HAS_FOCUS)) { ret = 0; break; } else if(event->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL || event->keyboard.modifiers & ALLEGRO_KEYMOD_ALT) { ret = 0; } len = al_ustr_length(box->text); if((int)(event->keyboard.unichar) > 31 && (int)(event->keyboard.unichar) != 127) { al_ustr_insert_chr(box->text, al_ustr_offset(box->text, box->cursor_pos), event->keyboard.unichar); box->cursor_pos++; } else { switch (event->keyboard.keycode) { case ALLEGRO_KEY_BACKSPACE: { if (len > 0 && box->cursor_pos > 0) { al_ustr_remove_chr(box->text, al_ustr_offset(box->text, box->cursor_pos - 1)); box->cursor_pos--; } break; } case ALLEGRO_KEY_DELETE: { if (len > 0 && box->cursor_pos < len) { al_ustr_remove_chr(box->text, al_ustr_offset(box->text, box->cursor_pos)); } break; } case ALLEGRO_KEY_LEFT: { if (box->cursor_pos > 0) { box->cursor_pos--; } else ret = 0; break; } case ALLEGRO_KEY_RIGHT: { if (box->cursor_pos < len) { box->cursor_pos++; } else ret = 0; break; } case ALLEGRO_KEY_HOME: { box->cursor_pos = 0; break; } case ALLEGRO_KEY_END: { len = al_ustr_length(box->text); box->cursor_pos = len; break; } case ALLEGRO_KEY_ENTER: { wz_trigger(wgt); break; } default: ret = 0; } } wz_snap_editbox(box); break; } case WZ_SET_CURSOR_POS: { box->cursor_pos = event->user.data3; wz_snap_editbox(box); } case WZ_SET_TEXT: { if(box->own) { al_ustr_assign(box->text, (ALLEGRO_USTR*)event->user.data3); } else box->text = (ALLEGRO_USTR*)event->user.data3; wz_snap_editbox(box); break; } case WZ_TRIGGER: { ALLEGRO_EVENT ev; wz_craft_event(&ev, WZ_TEXT_CHANGED, wgt, 0); al_emit_user_event(wgt->source, &ev, 0); break; } case ALLEGRO_EVENT_MOUSE_AXES: { if (wgt->flags & WZ_STATE_DISABLED) { ret = 0; } if (wz_widget_rect_test(wgt, event->mouse.x, event->mouse.y)) { wz_ask_parent_for_focus(wgt); } return wz_widget_proc(wgt, event); break; } default: ret = 0; } if (ret == 0) ret = wz_widget_proc(wgt, event); return ret; }
static void t2(void) { CHECK(0 == al_ustr_size(al_ustr_empty_string())); CHECK(0 == strcmp(al_cstr(al_ustr_empty_string()), "")); }
/* parse_path_string: * * Parse a path string according to the following grammar. The last * component, if it is not followed by a directory separator, is interpreted * as the filename component, unless it is "." or "..". * * GRAMMAR * * path ::= "//" c+ "/" nonlast [Windows only] * | c ":" nonlast [Windows only] * | nonlast * * nonlast ::= c* "/" nonlast * | last * * last ::= "." * | ".." * | filename * * filename ::= c* [but not "." and ".."] * * c ::= any character but '/' */ static bool parse_path_string(const ALLEGRO_USTR *str, ALLEGRO_PATH *path) { ALLEGRO_USTR_INFO dot_info; ALLEGRO_USTR_INFO dotdot_info; const ALLEGRO_USTR * dot = al_ref_cstr(&dot_info, "."); const ALLEGRO_USTR * dotdot = al_ref_cstr(&dotdot_info, ".."); ALLEGRO_USTR *piece = al_ustr_new(""); int pos = 0; bool on_windows; /* We compile the drive handling code on non-Windows platforms to prevent * it becoming broken. */ #ifdef ALLEGRO_WINDOWS on_windows = true; #else on_windows = false; #endif if (on_windows) { /* UNC \\server\share name */ if (al_ustr_has_prefix_cstr(str, "//")) { int slash = al_ustr_find_chr(str, 2, '/'); if (slash == -1 || slash == 2) { /* Missing slash or server component is empty. */ goto Error; } al_ustr_assign_substr(path->drive, str, pos, slash); pos = slash + 1; } else { /* Drive letter. */ int colon = al_ustr_offset(str, 1); if (colon > -1 && al_ustr_get(str, colon) == ':') { /* Include the colon in the drive string. */ al_ustr_assign_substr(path->drive, str, 0, colon + 1); pos = colon + 1; } } } for (;;) { int slash = al_ustr_find_chr(str, pos, '/'); if (slash == -1) { /* Last component. */ al_ustr_assign_substr(piece, str, pos, al_ustr_size(str)); if (al_ustr_equal(piece, dot) || al_ustr_equal(piece, dotdot)) { al_append_path_component(path, al_cstr(piece)); } else { /* This might be an empty string, but that's okay. */ al_ustr_assign(path->filename, piece); } break; } /* Non-last component. */ al_ustr_assign_substr(piece, str, pos, slash); al_append_path_component(path, al_cstr(piece)); pos = slash + 1; } al_ustr_free(piece); return true; Error: al_ustr_free(piece); return false; }
static bool path_is_absolute(const ALLEGRO_PATH *path) { /* If the first segment is empty, we have an absolute path. */ return (_al_vector_size(&path->segments) > 0) && (al_ustr_size(get_segment(path, 0)) == 0); }
int main(int argc, char **argv) { InitAllegro(); ALLEGRO_KEYBOARD_STATE klawiatura; ALLEGRO_MOUSE_STATE mysz; ALLEGRO_EVENT_QUEUE* event_queue = al_create_event_queue(); ALLEGRO_EVENT_QUEUE* key_queue = al_create_event_queue(); ALLEGRO_DISPLAY* okno = al_create_display(WINDOW_WIDTH, WINDOW_HEIGHT); ALLEGRO_FONT* defaultFont = al_create_builtin_font(); ALLEGRO_TIMER* timer = al_create_timer(1.0 / 60.0); al_register_event_source(key_queue, al_get_display_event_source(okno)); al_register_event_source(event_queue, al_get_display_event_source(okno)); al_register_event_source(key_queue, al_get_keyboard_event_source()); al_register_event_source(event_queue, al_get_timer_event_source(timer)); al_set_window_title(okno, "Fraktale"); al_set_target_bitmap(al_get_backbuffer(okno)); Menu* menu = new Menu(WINDOW_WIDTH, WINDOW_HEIGHT); Mandelbrot* mandelbrot = new Mandelbrot(WINDOW_WIDTH, WINDOW_HEIGHT, defaultFont); Julia* julia = new Julia(WINDOW_WIDTH, WINDOW_HEIGHT, defaultFont); Window* window = new Window(menu, mandelbrot, julia); menu->SetWindow(window); mandelbrot->SetWindow(window); julia->SetWindow(window); const ALLEGRO_COLOR backgroundColor = al_map_rgb(255, 255, 255); const ALLEGRO_COLOR frameColor = al_map_rgb(255, 255, 255); const int frameThickness = 2; ALLEGRO_USTR* str = al_ustr_new(""); int pos = (int)al_ustr_size(str); ALLEGRO_EVENT ev; double blokadaKlikniecia = al_get_time(); int poczX = -1, poczY = -1, poprzedniStan = window->stanOkna; bool petla = true, klikniecieMyszy = false, klawiszWcisniety = false, wpisywanieIteracji = false; double screenRatio = static_cast<double>(WINDOW_HEIGHT) / static_cast<double>(WINDOW_WIDTH); while (petla) { if (poprzedniStan != window->stanOkna) { blokadaKlikniecia = al_get_time(); } poprzedniStan = window->stanOkna; al_get_next_event(event_queue, &ev); al_get_mouse_state(&mysz); int mx = mysz.x; int my = mysz.y; bool koniecKlikniecia = false; if (mysz.buttons & 1 && klikniecieMyszy == false && al_get_time() > blokadaKlikniecia + 0.3) { klikniecieMyszy = true; if (window->CzyFraktal()) { poczX = mx; poczY = my; } } else if (!(mysz.buttons & 1) && klikniecieMyszy == true && al_get_time() > blokadaKlikniecia + 0.3) { klikniecieMyszy = false; int pp = window->stanOkna; int respond = window->Click(mx, my); if (respond == Responds_t::RESPOND_CLOSE_WINDOW) petla = false; if (window->CzyFraktal() && (pp == WINDOWSTATE_MANDELBROT || pp == WINDOWSTATE_JULIA)) { koniecKlikniecia = true; } if (pp == WINDOWSTATE_MENU && window->CzyFraktal()) { window->ZaladujFraktal(); } } if (koniecKlikniecia) { if (window->CzyFraktal()) { Fraktal* fraktal = window->AktualnyFraktal(); fraktal->Powieksz(poczX, mx, poczY, SkalujY(poczY, screenRatio, poczX, mx)); } poczX = -1, poczY = -1; } al_get_next_event(key_queue, &ev); if (ev.type == ALLEGRO_EVENT_KEY_DOWN && klawiszWcisniety == false && window->CzyFraktal()) { int kod = ev.keyboard.keycode; klawiszWcisniety = true; if (kod == 9) { wpisywanieIteracji = true; } else if (kod == 10) { Fraktal* fraktal = window->AktualnyFraktal(); fraktal->Resetuj(); } else if (kod >= 27 && kod <= 36 && wpisywanieIteracji) { pos += al_ustr_append_chr(str, kod + 21); } else if (kod == ALLEGRO_KEY_ENTER) { if (wpisywanieIteracji == true) wpisywanieIteracji = false; unsigned char* tmp = str->data; int t = atoi((const char*)tmp); window->SetIteracje(t); } else if (kod == ALLEGRO_KEY_BACKSPACE) { if (al_ustr_prev(str, &pos)) al_ustr_truncate(str, pos); } else if (kod == ALLEGRO_KEY_ESCAPE) { window->stanOkna = WINDOWSTATE_MENU; } } else if (ev.type == ALLEGRO_EVENT_KEY_UP) { klawiszWcisniety = false; } al_clear_to_color(backgroundColor); if (wpisywanieIteracji) window->Draw(str); else window->Draw(NULL); if(poczX != -1) al_draw_rectangle(poczX, poczY, mx, SkalujY(poczY, screenRatio, poczX, mx), frameColor, frameThickness); al_flip_display(); } al_destroy_display(okno); return 0; }
/* [nd_gtk thread] */ static gboolean create_gtk_file_dialog(gpointer data) { GTK_FILE_DIALOG_MESSAGE *msg = data; ALLEGRO_DISPLAY *display = msg->display; ALLEGRO_NATIVE_DIALOG *fd = msg->dialog; bool save = fd->flags & ALLEGRO_FILECHOOSER_SAVE; gint result; GtkWidget *window; window = gtk_file_chooser_dialog_new(al_cstr(fd->title), NULL, save ? GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, save ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); _al_gtk_make_transient(display, window); if (fd->fc_initial_path) { gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(window), al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP)); } if (fd->flags & ALLEGRO_FILECHOOSER_MULTIPLE) gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(window), true); /* FIXME: Move all this filter parsing stuff into a common file. */ if (al_ustr_size(fd->fc_patterns) > 0) { GtkFileFilter* filter = gtk_file_filter_new(); int start = 0; int end = 0; bool is_mime_type = false; while (true) { int32_t c = al_ustr_get(fd->fc_patterns, end); if (c < 0 || c == ';') { if (end - start > 0) { ALLEGRO_USTR* pattern = al_ustr_dup_substr(fd->fc_patterns, start, end); if (is_mime_type) { gtk_file_filter_add_mime_type(filter, al_cstr(pattern)); } else { gtk_file_filter_add_pattern(filter, al_cstr(pattern)); } al_ustr_free(pattern); } start = end + 1; is_mime_type = false; } if (c == '/') is_mime_type = true; if (c < 0) break; end += al_utf8_width(c); } gtk_file_filter_set_name(filter, "All supported files"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(window), filter); } result = gtk_dialog_run(GTK_DIALOG(window)); if (result == GTK_RESPONSE_ACCEPT) { GSList* filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(window)); int i; GSList* iter; fd->fc_path_count = g_slist_length(filenames); fd->fc_paths = al_malloc(fd->fc_path_count * sizeof(void *)); for (i = 0, iter = filenames; i < (int)fd->fc_path_count; i++, iter = g_slist_next(iter)) { fd->fc_paths[i] = al_create_path((const char*)iter->data); g_free(iter->data); } g_slist_free(filenames); } gtk_widget_destroy(window); ASSERT(fd->async_queue); g_async_queue_push(fd->async_queue, ACK_CLOSED); return FALSE; }