/** * This function creates a new check box widget. It allocates required memory * and intializes necessary windows to create the widget. If there is not enough * memory, the function returns NULL. * * To destroy the widget and all its contents, and free its memory, call * win_destroy() on the check box' child reference, given by * wtk_check_box_as_child(), like this: * "win_destroy(wtk_check_box_as_child(my_check_box_ptr));". * Usually it will be destroyed automatically when it's parent is destroyed. * * \param parent Parent window, possibly wtk_frame_as_parent(my_frame_ptr). * \param area Area of the internal contents. * \param caption Pointer to caption string. Will be copied into widget. * \param selected Initial state of check box, true if checked/selected. * \param command Command to send to parent window. Must be non-zero to be * enabled. * * \return Pointer to check box, or NULL if failed. */ struct wtk_check_box *wtk_check_box_create(struct win_window *parent, struct win_area const *area, char const *caption, bool selected, win_command_t command) { struct win_attributes attr; struct wtk_check_box *check_box; Assert(area); Assert(caption); Assert(parent); /* Allocate memory for check box control data. */ check_box = membag_alloc(sizeof(struct wtk_check_box)); if (!check_box) { goto outofmem_check_box; } check_box->state = WTK_CHECKBOX_NORMAL; check_box->selected = selected; check_box->command = command; /* Allocate memory for caption string, and copy text. */ check_box->caption = membag_alloc((strlen(caption) + 1) * sizeof(char)); if (!check_box->caption) { goto outofmem_caption; } wtk_copy_string(check_box->caption, caption); /* Handling information. */ attr.event_handler = wtk_check_box_handler; attr.custom = check_box; /* Prepare container frame. */ attr.area = *area; attr.background = NULL; attr.behavior = WIN_BEHAVIOR_REDRAW_PARENT; check_box->container = win_create(parent, &attr); if (!check_box->container) { goto outofmem_container; } return check_box; outofmem_container: membag_free(check_box->caption); outofmem_caption: membag_free(check_box); outofmem_check_box: return NULL; }
/** * This function creates a new button widget. It allocates required memory and * intializes necessary windows to create the widget. If there is not enough * memory, the function returns NULL. * * To destroy the widget and all its contents, and free its memory, call * win_destroy() on the button's child reference, given by * wtk_button_as_child(), like this: * "win_destroy(wtk_button_as_child(myButtonPtr));". * Usually it will be destroyed automatically when it's parent is destroyed. * * \param parent Parent window, possibly wtk_frame_as_parent(myFramePtr). * \param area Area of the internal contents. * \param caption Pointer to caption string. Will be copied into widget. * \param command_data Custom data to put into a command event when "clicked". * * \return Pointer to button, or NULL if failed. */ struct wtk_button *wtk_button_create(struct win_window *parent, struct win_area const *area, char const *caption, win_command_t command_data) { struct win_attributes attr; struct wtk_button *button; Assert(area); Assert(caption); Assert(parent); /* Allocate memory for button control data. */ button = membag_alloc(sizeof(struct wtk_button)); if (!button) { goto outofmem_button; } button->state = WTK_BUTTON_NORMAL; button->command = command_data; /* Allocate memory for caption string, and copy text. */ button->caption = membag_alloc((strlen(caption) + 1) * sizeof(char)); if (!button->caption) { goto outofmem_caption; } wtk_copy_string(button->caption, caption); /* Handling information. */ attr.event_handler = wtk_button_handler; attr.custom = button; /* Prepare container frame. */ attr.area = *area; attr.background = NULL; attr.behavior = 0x00; button->container = win_create(parent, &attr); if (!button->container) { goto outofmem_container; } return button; outofmem_container: membag_free(button->caption); outofmem_caption: membag_free(button); outofmem_button: return NULL; }
/** Set new caption for label, return false if out of mem. */ bool wtk_label_change(struct wtk_label *label, const char *caption) { Assert(label); Assert(caption); uint8_t new_len = strlen(caption); uint8_t old_len = 0; if (caption) { old_len = strlen(label->caption); } /* Only free old memory if new length is longer than the * previous label. */ if (new_len > old_len) { /* Free old caption, if present. */ if (caption) { membag_free(label->caption); } /* Allocate memory for caption string, and copy text. */ label->caption = membag_alloc((new_len + 1) * sizeof(char)); if (!label->caption) { goto outofmem_caption; } } wtk_copy_string(label->caption, caption); /* Redraw if visible. */ win_redraw(label->container); return true; outofmem_caption: return false; }
/** * This function creates a new frame widget. It allocates required memory and * intializes necessary windows to create the widget. If there is not enough * memory, the function returns NULL. * * To destroy the widget and all its contents, and free its memory, call * win_destroy() on the frame's child reference, given by wtk_frame_as_child(), * like this: "win_destroy(wtk_frame_as_child(my_frame_ptr));". * The frame's internal area will equal the area parameter, but the total * extents will be slightly larger, to accommodate for titlebar, borders etc. * * \param parent Parent window. * \param area Area of the internal contents. * \param caption Pointer to caption string. Will be copied into widget. * \param allow_resize True if resize handle should be included on the frame. * \param frame_handler Optional command event handler, for applications. * \param custom_data Optional custom data link, for applications. * * \return Pointer to frame, or NULL if failed. */ struct wtk_frame *wtk_frame_create(struct win_window *parent, struct win_area const *area, char const *caption, bool allow_resize, wtk_frame_handler_t frame_handler, void *custom_data) { struct win_attributes attr; struct wtk_frame *frame; Assert(area); Assert(caption); Assert(parent); /* Allocate memory for frame control data. */ frame = membag_alloc(sizeof(struct wtk_frame)); if (!frame) { goto outofmem_frame; } frame->state = WTK_FRAME_NORMAL; frame->frame_handler = frame_handler; frame->custom_data = custom_data; /* Allocate memory for caption string, and copy text. */ frame->caption = membag_alloc((strlen(caption) + 1) * sizeof(char)); if (!frame->caption) { goto outofmem_caption; } wtk_copy_string(frame->caption, caption); /* Start with valid area info, but only contents frame will keep the * original area. The other frames will be resized properly at the end. * All windows have the same event handler, and the same link back to * the widget object. */ attr.area = *area; attr.event_handler = wtk_frame_handler; attr.custom = frame; /* Prepare container frame, which will contain title bar, border, size, * handle etc. */ attr.background = NULL; attr.behavior = WIN_BEHAVIOR_RAISE_ON_PRESS; /* Create the container window, the proper size will be set later. */ frame->container = win_create(parent, &attr); if (!frame->container) { goto outofmem_container; } /* Prepare the contents frame, which will contain whatever controls * owned by the frame. Size will be equal to the given area parameter. */ attr.area.pos.x = WTK_FRAME_LEFTBORDER; attr.area.pos.y = WTK_FRAME_TOPBORDER + WTK_FRAME_TITLEBAR_HEIGHT; attr.background = &wtk_frame_background; attr.behavior = 0; frame->contents = win_create(frame->container, &attr); if (!frame->contents) { goto outofmem_contents; } /* Only create resize handle window if resize is allowed. */ if (allow_resize) { /* Prepare resize handle. Proper position will be set later. * Size is set here, though. */ attr.area.size.x = WTK_FRAME_RESIZE_WIDTH; attr.area.size.y = WTK_FRAME_RESIZE_HEIGHT; attr.background = NULL; attr.behavior = 0; frame->resize = win_create(frame->container, &attr); if (!frame->resize) { goto outofmem_resize; } win_show(frame->resize); } else { frame->resize = NULL; } /* Now, resize and rearrange according to size of contents frame, which * is equal to the given area parameter. */ wtk_resize_frame(frame, area); /* Make sure internals are visible when frame is mapped. */ win_show(frame->contents); return frame; outofmem_resize: win_destroy(frame->contents); outofmem_contents: win_destroy(frame->container); outofmem_container: membag_free(frame->caption); outofmem_caption: membag_free(frame); outofmem_frame: return NULL; }
/** * This function creates a new radio button widget. It allocates required memory * and intializes necessary windows to create the widget. If there is not enough * memory, the function returns NULL. * To destroy the widget and all its contents, and free its memory, call * win_destroy() on the radio button's child reference, given by * wtk_radio_button_as_child(), like this: * "win_destroy(wtk_radio_button_as_child(myButtonPtr));". * Usually it will be destroyed automatically when it's parent is destroyed. * * \param parent Parent window, possibly wtk_frame_as_parent(myFramePtr). * \param area Area of the internal contents. * \param caption Pointer to caption string. Will be copied into widget. * \param selected Initial state of radio button, true if checked/selected. * \param group Radio button group to be a member of. * \param command Command to send to parent window. Must be non-zero to be * enabled. * * \return Pointer to radio button, or NULL if failed. */ struct wtk_radio_button *wtk_radio_button_create(struct win_window *parent, struct win_area const *area, char const *caption, bool selected, struct wtk_radio_group *group, win_command_t command) { struct wtk_radio_button *radio_button; struct win_attributes attr; Assert(group); Assert(area); Assert(caption); Assert(parent); /* Allocate memory for check box control data. */ radio_button = membag_alloc(sizeof(struct wtk_radio_button)); if (!radio_button) { goto outofmem_radio_button; } radio_button->state = WTK_RADIOBUTTON_NORMAL; radio_button->group = group; radio_button->command = command; /* Allocate memory for caption string, and copy text. */ radio_button->caption = membag_alloc( (strlen(caption) + 1) * sizeof(char)); if (!radio_button->caption) { goto outofmem_caption; } wtk_copy_string(radio_button->caption, caption); /* Handling information. */ attr.event_handler = wtk_radio_button_handler; attr.custom = radio_button; /* Prepare container frame. */ attr.area = *area; attr.background = NULL; attr.behavior = WIN_BEHAVIOR_REDRAW_PARENT; radio_button->container = win_create(parent, &attr); if (!radio_button->container) { goto outofmem_container; } /* Select the radio button in the group if either no radio button is * currently selected (empty group), or the user has requested it takes * over the selection */ if (selected || (group->selected == NULL)) { wtk_radio_button_select(radio_button); } /* Make sure we haven't filled up the group reference count, and * increment. */ Assert(group->num_references < (wtk_radio_group_size_t)-1L); ++(group->num_references); return radio_button; outofmem_container: membag_free(radio_button->caption); outofmem_caption: membag_free(radio_button); outofmem_radio_button: return NULL; }
/** * This function creates a new label widget. It allocates required memory * and intializes necessary windows to create the widget. If there is not enough * memory, the function returns NULL. * * To destroy the widget and all its contents, and free its memory, call * win_destroy() on the label's child reference, given by * wtk_label_as_child(), * like this: "win_destroy(wtk_label_as_child(myStaticTextPtr));". * Usually it will be destroyed automatically when it's parent is destroyed. * * \param parent Parent window, possibly wtk_frame_as_parent(myFramePtr). * \param area Area of the internal contents. * \param caption Pointer to caption string. Will be copied into widget. * \param text_color Foreground color of the text when drawn. * \param background Background of the label. * \param align_right True if caption is to be aligned to the right, * false otherwise. * \return Pointer to label, or NULL if failed. */ struct wtk_label *wtk_label_create(struct win_window *parent, struct win_area const *area, char const *caption, gfx_color_t text_color, struct gfx_bitmap *background, bool align_right) { struct win_attributes attr; struct wtk_label *label; Assert(area); Assert(caption); Assert(parent); /* Allocate memory for label control data. */ label = membag_alloc(sizeof(struct wtk_label)); if (!label) { goto outofmem_label; } label->text_color = text_color; label->align_right = align_right; /* Allocate memory for caption string, and copy text. */ label->caption = membag_alloc((strlen(caption) + 1) * sizeof(char)); if (!label->caption) { goto outofmem_caption; } wtk_copy_string(label->caption, caption); /* Handling information. */ attr.event_handler = wtk_label_handler; attr.custom = label; /* Prepare container frame. */ attr.area = *area; /* Set background for label. */ if (background) { attr.background = background; attr.behavior = 0; } else { attr.background = NULL; attr.behavior = WIN_BEHAVIOR_REDRAW_PARENT; } label->container = win_create(parent, &attr); if (!label->container) { goto outofmem_container; } return label; outofmem_container: membag_free(label->caption); outofmem_caption: membag_free(label); outofmem_label: return NULL; }