Пример #1
0
/**
 * This function starts the drag operation. It will allocate memory to store
 * the screen behind the drag handles and draw the handles themselves.
 * Do not call this function unless wtk_prepare_drag() has been called first
 * with the drag origin position.
 * If there is not enough memory, this function will no draw anything, but it
 * is still safe to call wtk_continue_drag() and wtk_stop_drag().
 *
 * \param pos Current position of drag target.
 */
static void wtk_start_drag(struct win_point const *pos)
{
	/* Allocate memory for bitmaps. */
	wtk_drag_origin_pixmap = membag_alloc(
			(WTK_DRAG_PIXMAP_SIZE * WTK_DRAG_PIXMAP_SIZE) *
			sizeof(gfx_color_t)
			);
	if (!wtk_drag_origin_pixmap) {
		goto outofmem_origin;
	}

	wtk_drag_target_pixmap = membag_alloc(
			(WTK_DRAG_PIXMAP_SIZE * WTK_DRAG_PIXMAP_SIZE) *
			sizeof(gfx_color_t)
			);
	if (!wtk_drag_target_pixmap) {
		goto outofmem_target;
	}

	/* Make sure we can draw on the entire screen, since dragging is not
	 * necessarily limited to within one window.
	 */
	gfx_set_clipping(0, 0, gfx_get_width() - 1, gfx_get_height() - 1);

	/* Store screen underneath and draw drag origin symbol. */
	gfx_get_pixmap(wtk_drag_origin_pixmap, WTK_DRAG_PIXMAP_SIZE, 0, 0,
			wtk_drag_origin.x - WTK_DRAG_HANDLE_RADIUS,
			wtk_drag_origin.y - WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_PIXMAP_SIZE, WTK_DRAG_PIXMAP_SIZE);

	gfx_draw_filled_circle(wtk_drag_origin.x, wtk_drag_origin.y,
			WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_ORIGIN_COLOR, GFX_WHOLE);

	/* Store screen underneath and draw drag target symbol. */
	gfx_get_pixmap(wtk_drag_target_pixmap, WTK_DRAG_PIXMAP_SIZE, 0, 0,
			pos->x - WTK_DRAG_HANDLE_RADIUS,
			pos->y - WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_PIXMAP_SIZE, WTK_DRAG_PIXMAP_SIZE);

	gfx_draw_filled_circle(pos->x, pos->y,
			WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_TARGET_COLOR, GFX_WHOLE);

	return;

outofmem_target:
	membag_free(wtk_drag_origin_pixmap);
	wtk_drag_origin_pixmap = NULL;

outofmem_origin:
	return;
}
Пример #2
0
/**
 * This function updated the drag target handle graphics. Call this function
 * from the MOVE event handler of the dragging widget. This function needs
 * both the current position and the last used position. The last position will
 * be either the position handed to wtk_start_drag() or the "pos" parameter of
 * the last call to wtk_continue_drag(). The pointer event struct will keep this
 * value for you. No need to store it yourself.
 *
 * \param last_pos Last position.
 * \param pos Current position.
 */
static void wtk_continue_drag(struct win_point const *last_pos,
		struct win_point const *pos)
{
	/* Don't do any graphics if we did not get memory when drag started. */
	if (!wtk_drag_origin_pixmap || !wtk_drag_target_pixmap) {
		return;
	}

	/* Make sure we can draw on the entire screen, since dragging is not
	 * necessarily limited to within one window.
	 */
	gfx_set_clipping(0, 0, gfx_get_width() - 1, gfx_get_height() - 1);

	/* Restore screen underneath drag target symbol. */
	gfx_put_pixmap(wtk_drag_target_pixmap, WTK_DRAG_PIXMAP_SIZE, 0, 0,
			last_pos->x - WTK_DRAG_HANDLE_RADIUS,
			last_pos->y - WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_PIXMAP_SIZE, WTK_DRAG_PIXMAP_SIZE);

	/* Store screen underneath and draw new drag target symbol. */
	gfx_get_pixmap(wtk_drag_target_pixmap, WTK_DRAG_PIXMAP_SIZE, 0, 0,
			pos->x - WTK_DRAG_HANDLE_RADIUS,
			pos->y - WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_PIXMAP_SIZE, WTK_DRAG_PIXMAP_SIZE);

	gfx_draw_filled_circle(pos->x, pos->y,
			WTK_DRAG_HANDLE_RADIUS,
			WTK_DRAG_TARGET_COLOR, GFX_WHOLE);
}
Пример #3
0
/**
 * \brief Handle maXTouch messages
 *
 * This function handles the maXTouch messages, triggering the drawing of
 * squares around new or moved touches, and removing the squares around
 * released touches.
 *
 * \param device Pointer to mxt_device struct
 */
static void mxt_handler(struct mxt_device *device)
{
	struct mxt_touch_event touch_event;
	gfx_coord_t screen_touch_x, screen_touch_y, screen_touch_size;

	do {
		/* Get the first touch event in queue */
		if (mxt_read_touch_event(device, &touch_event) != STATUS_OK) {
			continue;
		}

		/* Discard non press, movement or release events */
		if (!(touch_event.status &
				(MXT_PRESS_EVENT | MXT_MOVE_EVENT | MXT_RELEASE_EVENT))) {
			continue;
		}

		/* Rescale from 4k touch X-coordinate to the display width */
		screen_touch_x = ((uint32_t)(4096 - touch_event.x) * gfx_get_width()) / 4096;

		/* Rescale from 4k touch Y-coordinate to the display height */
		screen_touch_y = ((uint32_t)(4096 - touch_event.y) * gfx_get_height()) / 4096;

		/* Scale the touch size to a value suitable for the target display */
		screen_touch_size = touch_event.size;

		/* Check if the touch is within the drawing area */
		if (screen_touch_y < (gfx_get_height() - PALLET_HEIGHT)) {
			/* Obtain the color to draw from the pallet colors */
			gfx_color_t draw_color = pallet_colors[selected_pallet_color];

			/* Color pallet index 0 selects multi-color mode */
			if (selected_pallet_color == 0) {
				draw_color = get_next_rainbow_color();
			}

			/* Set clipping area */
			gfx_set_clipping(0, 0, gfx_get_width(),
					(gfx_get_height() - PALLET_HEIGHT - 2));

			/* Draw touch point on the screen in the selected color */
			gfx_draw_filled_circle(screen_touch_x, screen_touch_y,
					screen_touch_size, draw_color, GFX_WHOLE);

			/* Reset clipping area */
			gfx_set_clipping(0, 0, gfx_get_width(), gfx_get_height());

		} else if (touch_event.status & MXT_PRESS_EVENT) {
			/* Calculate the pressed pallet entry */
			uint8_t pallete_index = (screen_touch_x / PALLET_COLOR_WIDTH);

			/* The last entry in the pallet clears the screen */
			if (pallete_index == (NUM_PALLET_COLORS - 1)) {
				/* Indicate display is being cleared */
				draw_pallet_labels(true);

				/* Clear the display */
				gfx_draw_filled_rect(0, 0, gfx_get_width(),
						(gfx_get_height() - PALLET_HEIGHT - 1),
						GFX_COLOR_BLACK);

				/* Indicate display has been cleared */
				draw_pallet_labels(false);
			} else {
				/* Change color selection based on the color chosen */
				selected_pallet_color = pallete_index;

				/* Draw new selection box around chosen color */
				update_pallet_selection();
			}
		}

	} while (mxt_is_message_pending(device));
}
Пример #4
0
/**
 * This function is the window event handler for frame widgets.
 * It handles all events sent to the windows composing the widget.
 *
 * \param win Window receiving the event.
 * \param type The event type.
 * \param data Custom data, depending on event type.
 *
 * \return True if the event was recognized and accepted.
 */
static bool wtk_frame_handler(struct win_window *win,
		enum win_event_type type, void const *data)
{
	/* Custom data for windows of a widget points back to the widget itself. */
	struct wtk_frame *frame = (struct wtk_frame *)win_get_custom_data(win);

	switch (type) {
	case WIN_EVENT_DRAW:
	{
		/* For DRAW events, the data parameter points to the
		 * clipping region.
		 */
		struct win_clip_region const *clip
			= (struct win_clip_region const *)data;

		struct win_area const *area = win_get_area(win);

		/* Draw frame decorations if this is the container window. */
		if (win == frame->container) {
			/* Draw left border. */
			gfx_draw_filled_rect(clip->origin.x,
					clip->origin.y,
					WTK_FRAME_LEFTBORDER,
					area->size.y,
					WTK_FRAME_BORDER_COLOR);

			/* Draw right border. */
			gfx_draw_filled_rect(clip->origin.x +
					area->size.x -
					WTK_FRAME_RIGHTBORDER,
					clip->origin.y,
					WTK_FRAME_RIGHTBORDER,
					area->size.y,
					WTK_FRAME_BORDER_COLOR);

			/* Draw top border. */
			gfx_draw_filled_rect(clip->origin.x +
					WTK_FRAME_LEFTBORDER,
					clip->origin.y,
					area->size.x -
					WTK_FRAME_LEFTBORDER -
					WTK_FRAME_RIGHTBORDER,
					WTK_FRAME_TOPBORDER,
					WTK_FRAME_BORDER_COLOR);

			/* Draw bottom border. */
			gfx_draw_filled_rect(clip->origin.x +
					WTK_FRAME_LEFTBORDER,
					clip->origin.y + area->size.y -
					WTK_FRAME_BOTTOMBORDER,
					area->size.x -
					WTK_FRAME_LEFTBORDER -
					WTK_FRAME_RIGHTBORDER,
					WTK_FRAME_BOTTOMBORDER,
					WTK_FRAME_BORDER_COLOR);

			/* Draw title bar background. */
			gfx_draw_filled_rect(clip->origin.x +
					WTK_FRAME_LEFTBORDER,
					clip->origin.y +
					WTK_FRAME_TOPBORDER,
					area->size.x -
					WTK_FRAME_LEFTBORDER -
					WTK_FRAME_RIGHTBORDER,
					WTK_FRAME_TITLEBAR_HEIGHT,
					WTK_FRAME_TITLEBAR_COLOR);

			/* Draw caption string. */
			gfx_draw_string(frame->caption,
					clip->origin.x +
					WTK_FRAME_LEFTBORDER +
					WTK_FRAME_CAPTION_X,
					clip->origin.y +
					WTK_FRAME_TOPBORDER +
					WTK_FRAME_CAPTION_Y, &sysfont,
					GFX_COLOR_TRANSPARENT,
					WTK_FRAME_CAPTION_COLOR);
		}
		/* Draw resize handle if this is the resize window. */
		else if (win == frame->resize) {
			gfx_draw_filled_circle(clip->origin.x +
					area->size.x - 1,
					clip->origin.y + area->size.y -
					1, WTK_FRAME_RESIZE_RADIUS,
					WTK_FRAME_RESIZE_COLOR,
					GFX_QUADRANT1);
		}

		/* Always accept DRAW events, as the return value is
		 * ignored anyway for that event type.
		 */
		return true;
	}

	case WIN_EVENT_POINTER:
	{
		/* For POINTER events, the data parameter points to the
		 * pointer event information.
		 */
		struct win_pointer_event const *event
			= (struct win_pointer_event const *)data;

		/* Handle move if this is the container window. */
		if (win == frame->container) {
			switch (event->type) {
			case WIN_POINTER_PRESS:
				wtk_handle_frame_press(frame, event);
				break;

			case WIN_POINTER_MOVE:
				wtk_handle_frame_move(frame, event);
				break;

			case WIN_POINTER_RELEASE:
				wtk_handle_frame_release(frame, event);
				break;

			default:
				break;
			}
		}
		/* Handle resize if this is the resize handle. */
		else if (win == frame->resize) {
			switch (event->type) {
			case WIN_POINTER_PRESS:
				wtk_handle_resize_press(frame, event);
				break;

			case WIN_POINTER_MOVE:
				wtk_handle_resize_move(frame, event);
				break;

			case WIN_POINTER_RELEASE:
				wtk_handle_resize_release(frame, event);
				break;

			default:
				break;
			}
		}

		/* Accept all POINTER events so that it does not
		 * propagate up the window tree to our parent in case
		 * we did not click anything useful inside the frame.
		 */
		return true;
	}

	case WIN_EVENT_DESTROY:
	{
		/* When the container window is destroyed, also destroy
		 * the rest of the non-window frame allocations.
		 */
		if (win == frame->container) {
			/* Memory allocated for windows will be
			 * automatically destroyed by the window
			 * system. We must destroy other allocations.
			 */
			membag_free(frame->caption);
			membag_free(frame);
		}

		/* Always accept DESTROY events, as the return value is
		 * ignored anyway for that event type.
		 */
		return true;
	}

	case WIN_EVENT_COMMAND:
	{
		/* When commands are received either directly or
		 * propagated from child widgets and windows, send it
		 * to the frame handler.
		 */
		if (win == frame->container) {
			if (frame->frame_handler) {
				/* If the frame handler returns true,
				 * it wants us to destroy the frame.
				 * This is normally used by CLOSE
				 * buttons.
				 */
				bool shouldDestroy
					= frame->frame_handler(frame,
						(win_command_t)
						data);

				/* It is safe to destroy it here, since
				 * the event handling finished right
				 * after this handler returns, and no
				 * other references to this frame or
				 * its contents will be done.
				 */
				if (shouldDestroy) {
					win_destroy(frame->container);
				}

				/* Accept the event if there was a
				 * handler installed.
				 */
				return true;
			}
		}

		/* Reject the event if there was no handler, or this
		 * was not the container window at all.
		 */
		return false;
	}

	default:
		/* Reject unknown event types. */
		return false;
	}
}
Пример #5
0
/**
 * This function is the window event handler for radio button widgets.
 * It handles all events sent to the windows composing the widget.
 *
 * \param win Window receiving the event.
 * \param type The event type.
 * \param data Custom data, depending on event type.
 *
 * \return True if the event was recognized and accepted.
 */
static bool wtk_radio_button_handler(struct win_window *win,
		enum win_event_type type, void const *data)
{
	struct win_command_event command;

	/* Custom data for windows of a widget points back to the widget itself. */
	struct wtk_radio_button *radio_button
		= (struct wtk_radio_button *)win_get_custom_data(win);

	switch (type) {
	case WIN_EVENT_DRAW:
	{
		/* For DRAW events, the data parameter points to the
		 * clipping region.
		 */
		struct win_clip_region const *clip
			= (struct win_clip_region const *)data;

		/* There should not be other windows in this widget. */
		Assert(win == radio_button->container);

		/* Draw radio button circle. */
		gfx_draw_circle(clip->origin.x +
				WTK_RADIOBUTTON_BUTTON_X,
				clip->origin.y +
				WTK_RADIOBUTTON_BUTTON_Y,
				WTK_RADIOBUTTON_RADIUS,
				WTK_RADIOBUTTON_BUTTON_COLOR,
				GFX_WHOLE);

		/* Draw radio button filled circle background. */
		if (WTK_RADIOBUTTON_BACKGROUND_COLOR != GFX_COLOR_TRANSPARENT) {
			gfx_draw_filled_circle(clip->origin.x +
				WTK_RADIOBUTTON_BUTTON_X,
				clip->origin.y +
				WTK_RADIOBUTTON_BUTTON_Y,
				WTK_RADIOBUTTON_RADIUS - 1,
				WTK_RADIOBUTTON_BACKGROUND_COLOR,
				GFX_WHOLE);
		}	

		/* Draw radio button select marker if selected. */
		if (radio_button->group->selected == radio_button) {
			gfx_draw_filled_circle(clip->origin.x +
					WTK_RADIOBUTTON_BUTTON_X,
					clip->origin.y +
					WTK_RADIOBUTTON_BUTTON_Y,
					WTK_RADIOBUTTON_RADIUS - 2,
					WTK_RADIOBUTTON_SELECT_COLOR,
					GFX_WHOLE);
		}

		/* Draw caption. */
		gfx_draw_string(radio_button->caption,
				clip->origin.x +
				WTK_RADIOBUTTON_CAPTION_X,
				clip->origin.y +
				WTK_RADIOBUTTON_CAPTION_Y, &sysfont,
				GFX_COLOR_TRANSPARENT,
				WTK_RADIOBUTTON_CAPTION_COLOR);

		/* Always accept DRAW events, as the return value is
		 * ignored anyway for that event type.
		 */
		return true;
	}

	case WIN_EVENT_POINTER:
	{
		/* There should not be other windows in this widget. */
		Assert(win == radio_button->container);

		/* For POINTER events, the data parameter points to the
		 * pointer event information.
		 */
		struct win_pointer_event const *event
			= (struct win_pointer_event const *)data;

		switch (event->type) {
		case WIN_POINTER_PRESS:

			/* When radio button pressed, grab pointer and
			 * wait for release inside widget borders.
			 * Other widgets won't get pointer events
			 * before it is released, and the pointer
			 * ungrabbed by us.
			 */
			if (radio_button->state ==
					WTK_RADIOBUTTON_NORMAL) {
				win_grab_pointer(radio_button->
						container);
				radio_button->state
					= WTK_RADIOBUTTON_PRESSED;
				win_redraw(radio_button->container);
			}

			break;

		case WIN_POINTER_RELEASE:

			/* When button released, take action only if
			 * released inside widget extents.
			 */
			if (radio_button->state ==
					WTK_RADIOBUTTON_PRESSED) {
				bool is_inside;

				/* Ungrab pointer. */
				win_grab_pointer(NULL);
				radio_button->state
					= WTK_RADIOBUTTON_NORMAL;
				win_redraw(radio_button->container);

				/* Check release position. */
				is_inside = win_is_inside_window
							(radio_button->
							container,
							&(event->pos));

				/* Select this radio button if inside. */
				if (is_inside) {
					wtk_radio_button_select
						(radio_button);

					/* Send non-zero command. */
					if (radio_button->command) {
						command.sender
							= radio_button->
								container;
						command.recipient
							= radio_button->
								container;
						command.data
							= radio_button->command;
						win_queue_command_event
							(&command);
					}
				}
			}

			break;

		default:
			break;
		}

		/* Accept all POINTER events since all acitivity inside
		 * the widget extents is relevant to us.
		 */
		return true;
	}

	case WIN_EVENT_DESTROY:
		/* There should not be other windows in this widget. */
		Assert(win == radio_button->container);

		/* Memory allocated for windows will be automatically destroyed
		 * by the window system. We must destroy other allocations.
		 */
		membag_free(radio_button->caption);

		/* Destroy radio group as well if we are the last one in the
		 * group. If not, remove ourselves from the group.
		 */
		--(radio_button->group->num_references);
		if (!radio_button->group->num_references) {
			membag_free(radio_button->group);
		} else {
			if (radio_button->group->selected == radio_button) {
				radio_button->group->selected = NULL;
			}
		}

		membag_free(radio_button);

		/* Always accept DESTROY events, as the return value is ignored
		 * anyway for that event type.
		 */
		return true;

	default:
		/* Reject unknown event types. */
		return false;
	}
}
Пример #6
0
void battery_application() {
    draw_background();



    gfx_draw_string_aligned("Power Info", gfx_get_width() / 2, 2, &sysfont, GFX_COLOR_TRANSPARENT, GFX_COLOR_WHITE, TEXT_POS_CENTER_X, TEXT_ALIGN_LEFT);

    uint8_t battery = max1704x_bat();
    char batlvl[5];
    if (battery > 100) {
        battery = 100;
    }
    //battery = 19;
    uint16_t x =  75;
    uint16_t y = 40;

    gfx_draw_rect(x, y,  164, 54, GFX_COLOR_WHITE);
    gfx_draw_filled_rect(x+164, y+15, 3, 20, GFX_COLOR_WHITE);

    if (battery < 20) {
        gfx_draw_filled_rect(x+2, y+2, battery/6 * 10, 50, GFX_COLOR_RED);
    } else {
        gfx_draw_filled_rect(x+2, y+2, battery/6 * 10, 50, GFX_COLOR_GREEN);
    }


    snprintf(batlvl, sizeof(batlvl), "%d%%", battery);
    if (battery > 20) {
        gfx_draw_string_aligned(batlvl, gfx_get_width() /2, 50, &large_sysfont, GFX_COLOR_TRANSPARENT, GFX_COLOR_WHITE, TEXT_POS_CENTER_X, TEXT_ALIGN_LEFT);
    } else {
        gfx_draw_string_aligned(batlvl, gfx_get_width() /2, 50, &large_sysfont, GFX_COLOR_TRANSPARENT, GFX_COLOR_WHITE, TEXT_POS_CENTER_X, TEXT_ALIGN_LEFT);
    }

    char atime[32];
    snprintf(atime, sizeof(atime), "Seconds Awake:    %lu", get_time_awake());
    gfx_draw_string_aligned(atime, 70, 100, &sysfont, GFX_COLOR_TRANSPARENT, GFX_COLOR_WHITE, TEXT_POS_LEFT, TEXT_ALIGN_LEFT);

    char stime[32];
    snprintf(stime, sizeof(stime), "Seconds Sleeping: %lu", get_time_sleep());
    gfx_draw_string_aligned(stime, 70, 120, &sysfont, GFX_COLOR_TRANSPARENT, GFX_COLOR_WHITE, TEXT_POS_LEFT, TEXT_ALIGN_LEFT);

    gfx_draw_filled_circle(gfx_get_width() /2,  80+80+10+10, 25, GFX_COLOR_WHITE, GFX_WHOLE);
    gfx_draw_string_aligned(SYMFONT_MOON, gfx_get_width() /2, 152+10, &symbol_sysfont, GFX_COLOR_TRANSPARENT, GFX_COLOR(200, 101, 18), TEXT_POS_CENTER_X, TEXT_ALIGN_CENTER);
    gfx_draw_string_aligned("Enter Sleep Mode", gfx_get_width() / 2, 152+15+30+15, &sysfont, GFX_COLOR_TRANSPARENT, GFX_COLOR_WHITE, TEXT_POS_CENTER_X, TEXT_ALIGN_LEFT);


	struct keyboard_event input;
    while(mma8451_orientation() != 6) {
        esp8266_check_buffer();
        if(mma8451_clear_interrupt() && is_low_power()) {
            exit_low_power();
        }

        keyboard_get_key_state(&input);
        if (input.type == KEYBOARD_RELEASE) {
            if (input.keycode == KEYBOARD_B) {
                break;
            } else if (input.keycode == KEYBOARD_A) {
                esp8266_enter_standby();
                enter_low_power();
                break;
            }
        }
    }
}