[MPlayer-cvslog] r37149 - in trunk: Changelog DOCS/xml/de/skin.xml DOCS/xml/en/skin.xml gui/app/app.c gui/app/app.h gui/app/gui.h gui/skin/skin.c gui/ui/main.c gui/ui/playbar.c gui/ui/render.c gui/ui/ui.h gui/win32...
ib
subversion at mplayerhq.hu
Sun Apr 13 01:29:30 CEST 2014
Author: ib
Date: Sun Apr 13 01:29:29 2014
New Revision: 37149
Log:
Add new item 'rpotmeter'.
This is the missing counterpart to hpotmeter and vpotmeter
allowing rotary control elements in a GUI skin now.
Based on an idea and a realization by Hans-Dieter Kosch,
hdkosch kabelbw de.
Additionally, update (and revise) documentation.
Modified:
trunk/Changelog
trunk/gui/app/app.c
trunk/gui/app/app.h
trunk/gui/app/gui.h
trunk/gui/skin/skin.c
trunk/gui/ui/main.c
trunk/gui/ui/playbar.c
trunk/gui/ui/render.c
trunk/gui/ui/ui.h
trunk/gui/win32/gui.c
trunk/gui/win32/gui.h
trunk/gui/win32/skinload.c
trunk/gui/win32/skinload.h
trunk/gui/win32/widgetrender.c
Changes in other areas also in this revision:
Modified:
trunk/DOCS/xml/de/skin.xml
trunk/DOCS/xml/en/skin.xml
Modified: trunk/Changelog
==============================================================================
--- trunk/Changelog Fri Apr 11 11:34:31 2014 (r37148)
+++ trunk/Changelog Sun Apr 13 01:29:29 2014 (r37149)
@@ -40,7 +40,7 @@ MPlayer
* Console message with information on deprecated (but still supported)
entries in the skin configuration file
* New symbol character (r) and new dynamic label variables ($D, $U, $P)
- * New item: pimage
+ * New items (pimage, rpotmeter)
1.1: "We gave up on 1.0"
Modified: trunk/gui/app/app.c
==============================================================================
--- trunk/gui/app/app.c Fri Apr 11 11:34:31 2014 (r37148)
+++ trunk/gui/app/app.c Sun Apr 13 01:29:29 2014 (r37149)
@@ -21,6 +21,8 @@
* @brief GUI application helpers
*/
+#include <math.h>
+
#include "app.h"
#include "gui.h"
#include "gui/skin/font.h"
@@ -180,6 +182,31 @@ guiItem *appFindItem(int event)
}
/**
+ * @brief Calculate the radian of a point inside the visual representation
+ * of an item.
+ *
+ * @param item pointer to the item
+ * @param x x position of the point
+ * @param y y position of the point
+ *
+ * @return radian of the point
+ *
+ * @note The return value is a @a clockwise radian.
+ */
+double appRadian(guiItem *item, int x, int y)
+{
+ double tx, ty;
+
+ // transform the center to (0,0)
+ tx = x - item->width / 2.0;
+ ty = y - item->height / 2.0;
+
+ // the y-axis is upside down and must be mirrored
+ // the x-axis is being mirrored for a clockwise radian
+ return (tx == 0.0 && ty == 0.0 ? 0.0 : atan2(-ty, -tx) + M_PI);
+}
+
+/**
* @brief Modify the value of the item belonging to an event.
*
* @param event event
Modified: trunk/gui/app/app.h
==============================================================================
--- trunk/gui/app/app.h Fri Apr 11 11:34:31 2014 (r37148)
+++ trunk/gui/app/app.h Sun Apr 13 01:29:29 2014 (r37149)
@@ -102,6 +102,7 @@ enum {
itDLabel,
itHPotmeter,
itVPotmeter,
+ itRPotmeter,
itPimage,
itMenu,
itPLMButton = 100,
@@ -132,6 +133,7 @@ typedef struct {
int pbwidth, pbheight;
int numphases;
float value;
+ double zeropoint, arclength;
int message;
@@ -180,6 +182,7 @@ extern guiItems guiApp;
guiItem *appFindItem(int event);
int appFindMessage(const char *name);
void appFreeStruct(void);
+double appRadian(guiItem *item, int x, int y);
void btnModify(int event, float value);
void btnSet(int event, int state);
void btnValue(int event, float *value);
Modified: trunk/gui/app/gui.h
==============================================================================
--- trunk/gui/app/gui.h Fri Apr 11 11:34:31 2014 (r37148)
+++ trunk/gui/app/gui.h Sun Apr 13 01:29:29 2014 (r37149)
@@ -48,9 +48,9 @@
#define isInside(x, y, tx, ty, bx, by) ((x) > (tx) && (y) > (ty) && (x) < (bx) && (y) < (by))
/// Check whether #guiItem @a item has a button (and thus a pressed state).
-#define hasButton(item) (item.type == itButton || item.type == itHPotmeter || item.type == itVPotmeter)
+#define hasButton(item) (item.type == itButton || item.type == itHPotmeter || item.type == itVPotmeter || item.type == itRPotmeter)
/// Check whether #guiItem @a item utilizes member 'value'
-#define hasValue(item) (item.type == itHPotmeter || item.type == itVPotmeter || item.type == itPimage)
+#define hasValue(item) (item.type == itHPotmeter || item.type == itVPotmeter || item.type == itRPotmeter || item.type == itPimage)
#endif /* MPLAYER_GUI_GUI_H */
Modified: trunk/gui/skin/skin.c
==============================================================================
--- trunk/gui/skin/skin.c Fri Apr 11 11:34:31 2014 (r37148)
+++ trunk/gui/skin/skin.c Sun Apr 13 01:29:29 2014 (r37149)
@@ -21,6 +21,7 @@
* @brief Skin parser
*/
+#include <math.h>
#include <stdio.h>
#include <string.h>
@@ -35,6 +36,7 @@
#include "help_mp.h"
#include "mp_msg.h"
+#include "libavutil/attributes.h"
#include "libavutil/avstring.h"
#include "libavutil/common.h"
@@ -589,13 +591,15 @@ static int item_menu(char *in)
}
/**
- * @brief Parse a hpotmeter or vpotmeter definition.
+ * @brief Parse a hpotmeter, vpotmeter or rpotmeter definition.
*
- * Parameters: button,bwidth,bheight,phases,numphases,default,x,y,width,height,message
+ * Parameters: button,bwidth,bheight,phases,numphases,[x0,y0,x1,y1,]default,x,y,width,height,message
*
* @param item pointer to item to store the parameters in
* @param in definition to be analyzed
*
+ * @note item->type is already available.
+ *
* @return 0 (ok) or 1 (error)
*/
static int parse_potmeter(guiItem *item, char *in)
@@ -603,6 +607,7 @@ static int parse_potmeter(guiItem *item,
unsigned char bfname[256];
unsigned char phfname[256];
unsigned char buf[512];
+ int i = 0, av_uninit(x0), av_uninit(y0), av_uninit(x1), av_uninit(y1);
int bwidth, bheight, num, d, x, y, w, h, message;
if (!window_item(currItem))
@@ -613,17 +618,25 @@ static int parse_potmeter(guiItem *item,
if (in_window("menu"))
return 1;
- cutStr(in, bfname, ',', 0);
- bwidth = cutInt(in, ',', 1);
- bheight = cutInt(in, ',', 2);
- cutStr(in, phfname, ',', 3);
- num = cutInt(in, ',', 4);
- d = cutInt(in, ',', 5);
- x = cutInt(in, ',', 6);
- y = cutInt(in, ',', 7);
- w = cutInt(in, ',', 8);
- h = cutInt(in, ',', 9);
- cutStr(in, buf, ',', 10);
+ cutStr(in, bfname, ',', i++);
+ bwidth = cutInt(in, ',', i++);
+ bheight = cutInt(in, ',', i++);
+ cutStr(in, phfname, ',', i++);
+ num = cutInt(in, ',', i++);
+
+ if (item->type == itRPotmeter) {
+ x0 = cutInt(in, ',', i++);
+ y0 = cutInt(in, ',', i++);
+ x1 = cutInt(in, ',', i++);
+ y1 = cutInt(in, ',', i++);
+ }
+
+ d = cutInt(in, ',', i++);
+ x = cutInt(in, ',', i++);
+ y = cutInt(in, ',', i++);
+ w = cutInt(in, ',', i++);
+ h = cutInt(in, ',', i++);
+ cutStr(in, buf, ',', i++);
message = appFindMessage(buf);
@@ -656,6 +669,19 @@ static int parse_potmeter(guiItem *item,
item->message = message;
item->pressed = btnReleased;
+ if (item->type == itRPotmeter) {
+ mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[skin] start: %d,%d / stop: %d,%d\n", x0, y0, x1, y1);
+
+ item->zeropoint = appRadian(item, x0, y0);
+ item->arclength = appRadian(item, x1, y1) - item->zeropoint;
+
+ if (item->arclength < 0.0)
+ item->arclength += 2 * M_PI;
+ // else check if radians of (x0,y0) and (x1,y1) only differ below threshold
+ else if (item->arclength < 0.05)
+ item->arclength = 2 * M_PI;
+ }
+
item->Bitmap.Image = NULL;
if (strcmp(phfname, "NULL") != 0) {
@@ -735,6 +761,29 @@ static int item_vpotmeter(char *in)
}
/**
+ * @brief Parse a @a rpotmeter definition.
+ *
+ * Syntax: rpotmeter=button,bwidth,bheight,phases,numphases,x0,y0,x1,y1,default,x,y,width,height,message
+ *
+ * @param in definition to be analyzed
+ *
+ * @return 0 (ok) or 1 (error)
+ */
+static int item_rpotmeter(char *in)
+{
+ guiItem *item;
+
+ item = next_item();
+
+ if (!item)
+ return 1;
+
+ item->type = itRPotmeter;
+
+ return parse_potmeter(item, in);
+}
+
+/**
* @brief Parse a @a potmeter definition.
*
* Syntax: potmeter=phases,numphases,default,x,y,width,height,message
@@ -1075,6 +1124,7 @@ static _item skinItem[] = {
{ "menu", item_menu },
{ "pimage", item_pimage },
{ "potmeter", item_potmeter }, // legacy
+ { "rpotmeter", item_rpotmeter },
{ "section", item_section },
{ "selected", item_selected },
{ "slabel", item_slabel },
Modified: trunk/gui/ui/main.c
==============================================================================
--- trunk/gui/ui/main.c Fri Apr 11 11:34:31 2014 (r37148)
+++ trunk/gui/ui/main.c Sun Apr 13 01:29:29 2014 (r37149)
@@ -18,6 +18,7 @@
/* main window */
+#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
@@ -95,10 +96,13 @@ static void uiMainMouse( int Button,int
static int itemtype = 0;
int i;
guiItem * item = NULL;
+ static double prev_point;
+ double point;
float value = 0.0f;
static int SelectedItem = -1;
int currentselected = -1;
+ static int endstop;
for ( i=0;i <= guiApp.IndexOfMainItems;i++ )
if ( ( guiApp.mainItems[i].pressed != btnDisabled )&&
@@ -135,6 +139,13 @@ static void uiMainMouse( int Button,int
{ item->pressed=btnDisabled; }
break;
}*/
+ if ( itemtype == itRPotmeter )
+ {
+ prev_point=appRadian( item, X - item->x, Y - item->y ) - item->zeropoint;
+ if ( prev_point < 0.0 ) prev_point+=2*M_PI;
+ if ( prev_point <= item->arclength ) endstop=False;
+ else endstop=STOPPED_AT_0 + STOPPED_AT_100; // block movement
+ }
break;
case wsRLMouseButton:
boxMoved=False;
@@ -154,6 +165,12 @@ static void uiMainMouse( int Button,int
case itVPotmeter:
value=100.0 - 100.0 * ( Y - item->y ) / item->height;
break;
+ case itRPotmeter:
+ if ( endstop ) { itemtype=0; return; }
+ point=appRadian( item, X - item->x, Y - item->y ) - item->zeropoint;
+ if ( point < 0.0 ) point+=2*M_PI;
+ value=100.0 * point / item->arclength;
+ break;
}
uiEvent( item->message,value );
itemtype=0;
@@ -170,7 +187,7 @@ rollerhandled:
if (currentselected != - 1)
{
item=&guiApp.mainItems[currentselected];
- if ( ( item->type == itHPotmeter )||( item->type == itVPotmeter ) )
+ if ( ( item->type == itHPotmeter )||( item->type == itVPotmeter )||( item->type == itRPotmeter ) )
{
item->value=constrain(item->value + value);
uiEvent( item->message,item->value );
@@ -189,6 +206,45 @@ rollerhandled:
case itPRMButton:
if (guiApp.menuIsPresent) guiApp.menuWindow.MouseHandler( 0,RX,RY,0,0 );
break;
+ case itRPotmeter:
+ point=appRadian( item, X - item->x, Y - item->y ) - item->zeropoint;
+ if ( point < 0.0 ) point+=2*M_PI;
+ if ( item->arclength < 2 * M_PI )
+ /* a potmeter with separated 0% and 100% positions */
+ {
+ value=item->value;
+ if ( point - prev_point > M_PI )
+ /* turned beyond the 0% position */
+ {
+ if ( !endstop )
+ {
+ endstop=STOPPED_AT_0;
+ value=0.0f;
+ }
+ }
+ else if ( prev_point - point > M_PI )
+ /* turned back from beyond the 0% position */
+ {
+ if ( endstop == STOPPED_AT_0 ) endstop=False;
+ }
+ else if ( prev_point <= item->arclength && point > item->arclength )
+ /* turned beyond the 100% position */
+ {
+ if ( !endstop )
+ {
+ endstop=STOPPED_AT_100;
+ value=100.0f;
+ }
+ }
+ else if ( prev_point > item->arclength && point <= item->arclength )
+ /* turned back from beyond the 100% position */
+ {
+ if ( endstop == STOPPED_AT_100 ) endstop=False;
+ }
+ }
+ if ( !endstop ) value=100.0 * point / item->arclength;
+ prev_point=point;
+ goto potihandled;
case itVPotmeter:
value=100.0 - 100.0 * ( Y - item->y ) / item->height;
goto potihandled;
Modified: trunk/gui/ui/playbar.c
==============================================================================
--- trunk/gui/ui/playbar.c Fri Apr 11 11:34:31 2014 (r37148)
+++ trunk/gui/ui/playbar.c Sun Apr 13 01:29:29 2014 (r37149)
@@ -18,6 +18,7 @@
/* playbar window */
+#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
@@ -123,10 +124,13 @@ static void uiPlaybarMouse( int Button,
static int itemtype = 0;
int i;
guiItem * item = NULL;
+ static double prev_point;
+ double point;
float value = 0.0f;
static int SelectedItem = -1;
int currentselected = -1;
+ static int endstop;
for ( i=0;i <= guiApp.IndexOfPlaybarItems;i++ )
if ( ( guiApp.playbarItems[i].pressed != btnDisabled )&&
@@ -162,6 +166,12 @@ static void uiPlaybarMouse( int Button,
( ( item->message == evPauseSwitchToPlay && item->message == evPlaySwitchToPause ) ) ) )
{ item->pressed=btnDisabled; }
break;
+ case itRPotmeter:
+ prev_point=appRadian( item, X - item->x, Y - item->y ) - item->zeropoint;
+ if ( prev_point < 0.0 ) prev_point+=2*M_PI;
+ if ( prev_point <= item->arclength ) endstop=False;
+ else endstop=STOPPED_AT_0 + STOPPED_AT_100; // block movement
+ break;
}
break;
@@ -183,6 +193,12 @@ static void uiPlaybarMouse( int Button,
case itVPotmeter:
value=100.0 - 100.0 * ( Y - item->y ) / item->height;
break;
+ case itRPotmeter:
+ if ( endstop ) { itemtype=0; return; }
+ point=appRadian( item, X - item->x, Y - item->y ) - item->zeropoint;
+ if ( point < 0.0 ) point+=2*M_PI;
+ value=100.0 * point / item->arclength;
+ break;
}
uiEvent( item->message,value );
@@ -195,7 +211,7 @@ rollerhandled:
if (currentselected != - 1)
{
item=&guiApp.playbarItems[currentselected];
- if ( ( item->type == itHPotmeter )||( item->type == itVPotmeter ) )
+ if ( ( item->type == itHPotmeter )||( item->type == itVPotmeter )||( item->type == itRPotmeter ) )
{
item->value=constrain(item->value + value);
uiEvent( item->message,item->value );
@@ -210,6 +226,45 @@ rollerhandled:
case itPRMButton:
if (guiApp.menuIsPresent) guiApp.menuWindow.MouseHandler( 0,RX,RY,0,0 );
break;
+ case itRPotmeter:
+ point=appRadian( item, X - item->x, Y - item->y ) - item->zeropoint;
+ if ( point < 0.0 ) point+=2*M_PI;
+ if ( item->arclength < 2 * M_PI )
+ /* a potmeter with separated 0% and 100% positions */
+ {
+ value=item->value;
+ if ( point - prev_point > M_PI )
+ /* turned beyond the 0% position */
+ {
+ if ( !endstop )
+ {
+ endstop=STOPPED_AT_0;
+ value=0.0f;
+ }
+ }
+ else if ( prev_point - point > M_PI )
+ /* turned back from beyond the 0% position */
+ {
+ if ( endstop == STOPPED_AT_0 ) endstop=False;
+ }
+ else if ( prev_point <= item->arclength && point > item->arclength )
+ /* turned beyond the 100% position */
+ {
+ if ( !endstop )
+ {
+ endstop=STOPPED_AT_100;
+ value=100.0f;
+ }
+ }
+ else if ( prev_point > item->arclength && point <= item->arclength )
+ /* turned back from beyond the 100% position */
+ {
+ if ( endstop == STOPPED_AT_100 ) endstop=False;
+ }
+ }
+ if ( !endstop ) value=100.0 * point / item->arclength;
+ prev_point=point;
+ goto potihandled;
case itVPotmeter:
value=100.0 - 100.0 * ( Y - item->y ) / item->height;
goto potihandled;
Modified: trunk/gui/ui/render.c
==============================================================================
--- trunk/gui/ui/render.c Fri Apr 11 11:34:31 2014 (r37148)
+++ trunk/gui/ui/render.c Sun Apr 13 01:29:29 2014 (r37149)
@@ -21,6 +21,7 @@
* @brief GUI rendering
*/
+#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -35,6 +36,7 @@
#include "access_mpcontext.h"
#include "help_mp.h"
#include "libavutil/avstring.h"
+#include "libavutil/common.h"
#include "osdep/timer.h"
#include "stream/stream.h"
@@ -479,6 +481,29 @@ void RenderAll(wsWindow *window, guiItem
PutImage(item->x, item->y + (item->height - item->pbheight) * (1.0 - item->value / 100.0), db, dw, &item->Mask, 3, index, True);
break;
+ case itRPotmeter:
+
+ PutImage(item->x, item->y, db, dw, &item->Bitmap, item->numphases, (item->numphases - 1) * item->value / 100.0, True);
+
+ if (item->Mask.Image) {
+ double radius, radian;
+ int y;
+
+ // keep the button inside the potmeter outline
+ radius = (FFMIN(item->width, item->height) - FFMAX(item->pbwidth, item->pbheight)) / 2.0;
+
+ radian = item->value / 100.0 * item->arclength + item->zeropoint;
+
+ // coordinates plus a correction for a non-square item
+ // (remember: both axes are mirrored, we have a clockwise radian)
+ x = radius * (1 + cos(radian)) + FFMAX(0, (item->width - item->height) / 2.0) + 0.5;
+ y = radius * (1 + sin(radian)) + FFMAX(0, (item->height - item->width) / 2.0) + 0.5;
+
+ PutImage(item->x + x, item->y + y, db, dw, &item->Mask, 3, index, True);
+ }
+
+ break;
+
case itSLabel:
if (item->width == -1)
Modified: trunk/gui/ui/ui.h
==============================================================================
--- trunk/gui/ui/ui.h Fri Apr 11 11:34:31 2014 (r37148)
+++ trunk/gui/ui/ui.h Sun Apr 13 01:29:29 2014 (r37149)
@@ -19,6 +19,14 @@
#ifndef MPLAYER_GUI_UI_H
#define MPLAYER_GUI_UI_H
+/// End stops of a rotary potentiometer (::itRPotmeter)
+enum
+{
+ NOT_STOPPED,
+ STOPPED_AT_0,
+ STOPPED_AT_100
+};
+
extern unsigned char * menuDrawBuffer;
extern int mainVisible;
Modified: trunk/gui/win32/gui.c
==============================================================================
--- trunk/gui/win32/gui.c Fri Apr 11 11:34:31 2014 (r37148)
+++ trunk/gui/win32/gui.c Sun Apr 13 01:29:29 2014 (r37149)
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
+#include <math.h>
#include <windows.h>
#include <windowsx.h>
#include <shlobj.h>
@@ -117,6 +118,19 @@ LPSTR acp (LPCSTR utf8)
return "?";
}
+double appRadian (widget *item, int x, int y)
+{
+ double tx, ty;
+
+ // transform the center to (0,0)
+ tx = x - item->wwidth / 2.0;
+ ty = y - item->wheight / 2.0;
+
+ // the y-axis is upside down and must be mirrored
+ // the x-axis is being mirrored for a clockwise radian
+ return (tx == 0.0 && ty == 0.0 ? 0.0 : atan2(-ty, -tx) + M_PI);
+}
+
static void console_toggle(gui_t *gui)
{
if (console_state)
@@ -304,10 +318,10 @@ static void updatedisplay(gui_t *gui, HW
if(!hwnd) return;
- /* load all hpotmeters vpotmeters pimages */
+ /* load all hpotmeters vpotmeters rpotmeters pimages */
for(i=0; i<gui->skin->widgetcount; i++)
{
- if(gui->skin->widgets[i]->type == tyHpotmeter || gui->skin->widgets[i]->type == tyVpotmeter || gui->skin->widgets[i]->type == tyPimage)
+ if(gui->skin->widgets[i]->type == tyHpotmeter || gui->skin->widgets[i]->type == tyVpotmeter || gui->skin->widgets[i]->type == tyRpotmeter || gui->skin->widgets[i]->type == tyPimage)
{
if(gui->skin->widgets[i]->msg == evSetVolume)
gui->skin->widgets[i]->value = guiInfo.Volume;
@@ -695,6 +709,8 @@ static LRESULT CALLBACK VideoProc(HWND h
/* Window Proc for the gui Window */
static LRESULT CALLBACK EventProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
+ static double prev_point;
+ static int endstop;
gui_t *gui = (gui_t *) GetWindowLongPtr(hWnd, GWLP_USERDATA);
/* Avoid processing when then window doesn't match gui mainwindow */
@@ -833,6 +849,14 @@ static LRESULT CALLBACK EventProc(HWND h
renderwidget(gui->skin, get_drawground(hWnd), gui->activewidget, 0);
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE);
handlemsg(hWnd, gui->activewidget->msg);
+
+ if(gui->activewidget->type == tyRpotmeter)
+ {
+ prev_point = appRadian(gui->activewidget, gui->mousewx, gui->mousewy) - gui->activewidget->zeropoint;
+ if(prev_point < 0.0) prev_point += 2 * M_PI;
+ if(prev_point <= gui->activewidget->arclength) endstop=FALSE;
+ else endstop=STOPPED_AT_0 + STOPPED_AT_100; // block movement
+ }
}
break;
}
@@ -942,8 +966,49 @@ static LRESULT CALLBACK EventProc(HWND h
item->y = GET_Y_LPARAM(lParam) - gui->mousewy;
item->value = 100.0 - 100.0 * (item->y - item->wy) / (item->wheight - item->height);
}
+ if(item->type == tyRpotmeter)
+ {
+ double point;
- if((item->type == tyHpotmeter) || (item->type == tyVpotmeter))
+ point = appRadian(item, GET_X_LPARAM(lParam) - gui->activewidget->x, GET_Y_LPARAM(lParam) - gui->activewidget->y) - item->zeropoint;
+ if(point < 0.0) point += 2 * M_PI;
+ if(item->arclength < 2 * M_PI)
+ /* a potmeter with separated 0% and 100% positions */
+ {
+ if(point - prev_point > M_PI)
+ /* turned beyond the 0% position */
+ {
+ if(!endstop)
+ {
+ endstop = STOPPED_AT_0;
+ item->value = 0.0f;
+ }
+ }
+ else if(prev_point - point > M_PI)
+ /* turned back from beyond the 0% position */
+ {
+ if(endstop == STOPPED_AT_0) endstop = FALSE;
+ }
+ else if(prev_point <= item->arclength && point > item->arclength)
+ /* turned beyond the 100% position */
+ {
+ if (!endstop)
+ {
+ endstop = STOPPED_AT_100;
+ item->value = 100.0f;
+ }
+ }
+ else if(prev_point > item->arclength && point <= item->arclength)
+ /* turned back from beyond the 100% position */
+ {
+ if(endstop == STOPPED_AT_100) endstop = FALSE;
+ }
+ }
+ if(!endstop) item->value = 100.0 * point / item->arclength;
+ prev_point = point;
+ }
+
+ if((item->type == tyHpotmeter) || (item->type == tyVpotmeter) || (item->type == tyRpotmeter))
{
/* Bound checks */
if(item->value > 100.0f)
Modified: trunk/gui/win32/gui.h
==============================================================================
--- trunk/gui/win32/gui.h Fri Apr 11 11:34:31 2014 (r37148)
+++ trunk/gui/win32/gui.h Sun Apr 13 01:29:29 2014 (r37149)
@@ -107,6 +107,7 @@ int create_videowindow(gui_t *gui);
int parse_filename(char *file, play_tree_t *playtree, m_config_t *mconfig, int clear);
void capitalize(char *fname);
LPSTR acp(LPCSTR utf8);
+double appRadian(widget *item, int x, int y);
void renderinfobox(skin_t *skin, window_priv_t *priv);
void renderwidget(skin_t *skin, image *dest, widget *item, int state);
Modified: trunk/gui/win32/skinload.c
==============================================================================
--- trunk/gui/win32/skinload.c Fri Apr 11 11:34:31 2014 (r37148)
+++ trunk/gui/win32/skinload.c Sun Apr 13 01:29:29 2014 (r37149)
@@ -25,12 +25,15 @@
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
+#include <math.h>
#include <windows.h>
#include "mp_msg.h"
#include "help_mp.h"
#include "cpudetect.h"
#include "libswscale/swscale.h"
+#include "libavutil/attributes.h"
+#include "libavutil/common.h"
#include "libavutil/imgutils.h"
#include "gui.h"
#include "gui/util/mem.h"
@@ -364,12 +367,13 @@ static void addwidget(skin_t *skin, wind
(mywidget->bitmap[0]) ? mywidget->bitmap[0]->name : NULL,
mywidget->x, mywidget->y, mywidget->width, mywidget->height, mywidget->msg);
}
- else if(!strncmp(desc, "hpotmeter", 9) || !strncmp(desc, "vpotmeter", 9) || /* legacy */ !strncmp(desc, "potmeter", 8))
+ else if(!strncmp(desc, "hpotmeter", 9) || !strncmp(desc, "vpotmeter", 9) || !strncmp(desc, "rpotmeter", 9) || /* legacy */ !strncmp(desc, "potmeter", 8))
{
int base = counttonextchar(desc, '=') + 1;
- int i;
+ int i, av_uninit(x0), av_uninit(y0), av_uninit(x1), av_uninit(y1);
/* hpotmeter = button, bwidth, bheight, phases, numphases, default, X, Y, width, height, message */
if(!strncmp(desc, "vpotmeter", 9)) mywidget->type = tyVpotmeter;
+ else if(!strncmp(desc, "rpotmeter", 9)) mywidget->type = tyRpotmeter;
else mywidget->type = tyHpotmeter;
if (*desc == 'p')
{
@@ -388,6 +392,15 @@ static void addwidget(skin_t *skin, wind
}
mywidget->bitmap[1] = pngRead(skin, findnextstring(temp, desc, &base));
mywidget->phases = atoi(findnextstring(temp, desc, &base));
+
+ if (*desc == 'r')
+ {
+ x0 = atoi(findnextstring(temp, desc, &base));
+ y0 = atoi(findnextstring(temp, desc, &base));
+ x1 = atoi(findnextstring(temp, desc, &base));
+ y1 = atoi(findnextstring(temp, desc, &base));
+ }
+
mywidget->value = atof(findnextstring(temp, desc, &base));
mywidget->x = mywidget->wx = atoi(findnextstring(temp, desc, &base));
mywidget->y = mywidget->wy = atoi(findnextstring(temp, desc, &base));
@@ -406,12 +419,24 @@ static void addwidget(skin_t *skin, wind
break;
}
}
- mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[SKIN] [ITEM] %s %s %i %i %s %i %f %i %i %i %i msg %i\n",
- (mywidget->type == tyHpotmeter) ? "[HPOTMETER]" : "[VPOTMETER]",
+ if (*desc == 'r')
+ {
+ mywidget->zeropoint = appRadian(mywidget, x0, y0);
+ mywidget->arclength = appRadian(mywidget, x1, y1) - mywidget->zeropoint;
+
+ if (mywidget->arclength < 0.0) mywidget->arclength += 2 * M_PI;
+ // else check if radians of (x0,y0) and (x1,y1) only differ below threshold
+ else if (mywidget->arclength < 0.05) mywidget->arclength = 2 * M_PI;
+ }
+ mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[SKIN] [ITEM] %s %s %i %i %s %i ",
+ (mywidget->type == tyHpotmeter) ? "[HPOTMETER]" : (mywidget->type == tyVpotmeter) ? "[VPOTMETER]" : "[RPOTMETER]",
(mywidget->bitmap[0]) ? mywidget->bitmap[0]->name : NULL,
mywidget->width, mywidget->height,
(mywidget->bitmap[1]) ? mywidget->bitmap[1]->name : NULL,
- mywidget->phases, mywidget->value,
+ mywidget->phases);
+ if (*desc == 'r')
+ mp_msg(MSGT_GPLAYER, MSGL_DBG2, "%i,%i %i,%i ", x0, y0, x1, y1);
+ mp_msg(MSGT_GPLAYER, MSGL_DBG2, "%f %i %i %i %i msg %i\n", mywidget->value,
mywidget->wx, mywidget->wy, mywidget->wwidth, mywidget->wwidth,
mywidget->msg);
if (mywidget->bitmap[0] == NULL || mywidget->width == 0 || mywidget->height == 0)
@@ -420,6 +445,14 @@ static void addwidget(skin_t *skin, wind
mywidget->width = mywidget->wwidth;
mywidget->height = mywidget->wheight;
}
+ if (*desc == 'r')
+ {
+ mywidget->maxwh = FFMAX(mywidget->width, mywidget->height);
+
+ // clickedinsidewidget() checks with width/height, so set it
+ mywidget->width = mywidget->wwidth;
+ mywidget->height = mywidget->wheight;
+ }
}
else if(!strncmp(desc, "pimage", 6))
{
Modified: trunk/gui/win32/skinload.h
==============================================================================
--- trunk/gui/win32/skinload.h Fri Apr 11 11:34:31 2014 (r37148)
+++ trunk/gui/win32/skinload.h Sun Apr 13 01:29:29 2014 (r37149)
@@ -61,12 +61,15 @@ typedef struct
int width, height; /* width and height of the button */
int wwidth, wheight; /* width and height of the widget */
// ---
+ int maxwh;
// ---
int msg, msg2;
int pressed, tmp;
int key, key2;
int phases;
float value;
+ double zeropoint;
+ double arclength;
image *bitmap[2]; /* Associated image(s) in imagepool */
// ---
font_t *font;
@@ -121,6 +124,7 @@ skin_t *loadskin(char *skindir, int desk
#define tyMenu 6
#define tySlabel 7
#define tyDlabel 8
+#define tyRpotmeter 9
/* --- Window types --- */
Modified: trunk/gui/win32/widgetrender.c
==============================================================================
--- trunk/gui/win32/widgetrender.c Fri Apr 11 11:34:31 2014 (r37148)
+++ trunk/gui/win32/widgetrender.c Sun Apr 13 01:29:29 2014 (r37149)
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
+#include <math.h>
#include <windows.h>
#include "gui/util/bitmap.h"
@@ -34,6 +35,7 @@
#include "access_mpcontext.h"
#include "help_mp.h"
#include "libavutil/avstring.h"
+#include "libavutil/common.h"
#include "stream/stream.h"
#define MAX_LABELSIZE 250
@@ -409,11 +411,13 @@ void renderwidget(skin_t *skin, image *d
if(!dest) return;
if((item->type == tyButton) || (item->type == tyHpotmeter) || (item->type == tyVpotmeter) || (item->type == tyPimage))
img = item->bitmap[0];
+ if(item->type == tyRpotmeter)
+ img = item->bitmap[1];
if(!img) return;
y = item->y;
- if(item->type == tyPimage || /* legacy (potmeter) */ (item->type == tyHpotmeter && item->width == item->wwidth))
+ if(item->type == tyPimage || /* legacy (potmeter) */ (item->type == tyHpotmeter && item->width == item->wwidth) || item->type == tyRpotmeter)
{
height = img->height / item->phases;
y = height * (int)(item->value * item->phases / 100);
@@ -430,7 +434,7 @@ void renderwidget(skin_t *skin, image *d
if(item->type == tyButton)
render(skin->desktopbpp, dest, find_background(skin,item), item->x, item->y, item->x, item->y, img->width, height, 1);
- if((item->type == tyHpotmeter) || (item->type == tyVpotmeter) || (item->type == tyPimage))
+ if((item->type == tyHpotmeter) || (item->type == tyVpotmeter) || (item->type == tyRpotmeter) || (item->type == tyPimage))
{
if(item->type == tyVpotmeter)
{
@@ -438,6 +442,13 @@ void renderwidget(skin_t *skin, image *d
render(skin->desktopbpp, dest, find_background(skin, item), item->wx, item->wy, item->wx, item->wy, item->width, item->wheight, 1);
item->y = (100 - item->value) * (item->wheight-item->height) / 100 + item->wy;
}
+ else if(item->type == tyRpotmeter)
+ {
+ /* repaint the area behind the rpotmeter */
+ render(skin->desktopbpp, dest, find_background(skin, item), item->wx, item->wy, item->wx, item->wy, item->wwidth, item->wheight, 1);
+ item->x = item->wx;
+ item->y = item->wy;
+ }
else
{
/* repaint the area behind the slider */
@@ -446,4 +457,31 @@ void renderwidget(skin_t *skin, image *d
}
}
render(skin->desktopbpp, dest, img, item->x, item->y, 0, y, img->width, height, 1);
+
+ /* rpotmeter button */
+ if(item->type == tyRpotmeter && item->bitmap[0] != item->bitmap[1])
+ {
+ img = item->bitmap[0];
+
+ if(img)
+ {
+ double radius, radian;
+ int ix, iy;
+
+ // keep the button inside the potmeter outline
+ radius = (FFMIN(item->wwidth, item->wheight) - item->maxwh) / 2.0;
+
+ radian = item->value / 100.0 * item->arclength + item->zeropoint;
+
+ // coordinates plus a correction for a non-square item
+ // (remember: both axes are mirrored, we have a clockwise radian)
+ ix = item->wx + radius * (1 + cos(radian)) + FFMAX(0, (item->wwidth - item->wheight) / 2.0) + 0.5;
+ iy = item->wy + radius * (1 + sin(radian)) + FFMAX(0, (item->wheight - item->wwidth) / 2.0) + 0.5;
+
+ height = img->height / 3;
+ y = state * height;
+
+ render(skin->desktopbpp, dest, img, ix, iy, 0, y, img->width, height, 1);
+ }
+ }
}
More information about the MPlayer-cvslog
mailing list