📄 interface.c
字号:
/*****************************************************************************
*
* This program is free software ; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: interface.c 624 2006-02-01 17:48:42Z picard $
*
* The Core Pocket Media Player
* Copyright (c) 2004-2005 Gabor Kovacs
*
****************************************************************************/
#include "../../common/common.h"
#include "../win.h"
#include "interface.h"
#include "resource.h"
#include "openfile_win32.h"
#include "../about.h"
#include "../benchresult.h"
#include "../mediainfo.h"
#include "../settings.h"
#include "playlst.h"
#include "../skin.h"
#include "../../config.h"
#define CORETHEQUE_UI_ID FOURCC('C','T','Q','U')
#if defined(TARGET_WINCE) || defined(TARGET_WIN32)
#ifndef STRICT
#define STRICT
#endif
#include <windows.h>
#if _MSC_VER > 1000
#pragma warning(disable : 4201)
#endif
#include <commctrl.h>
#define REG_INITING 0x2400
#define TIMER_CLIPPING 500
#define TIMER_INITING 501
#define TIMER_SLEEP 502
#define TIMER_KEYINSEEK 503
#define TIMER_SLIDERINSEEK 504
#define TIMER_SLIDERINVOL 505
#define TIMER_CLIPPING2 506
#define TIMER_TITLESCROLL 507
#define SLIDERINSEEK_CYCLE 250
#define SLIDERINVOL_CYCLE 100
#define KEYINSEEK_START 1000
#define KEYINSEEK_REPEAT 500
#define CLIPPING_CYCLE 200
#define INITING_CYCLE 3000
#define SLEEP_CYCLE 5000
#define CLIPPING2_CYCLE 200
#define TITLESCROLL_CYCLE 150
#define TITLESCROLL_WAIT (4000/TITLESCROLL_CYCLE)
#define TRACKMAX 30000
#define TRACKHEIGHT 16
#define TRACKTHUMB 12
#define TITLEHEIGHT 16
#define TITLEFONT 11
#define VOLMINWIDTH 35
#define VOLTHUMB 12
#define IF_AUDIO 50000
#define IF_VIDEO 51000
#define IF_VIDEOACCEL 52000
#define IF_CHAPTER 53000
#define IF_STREAM_AUDIO 54000
#define IF_STREAM_VIDEO 55000
#define IF_STREAM_SUBTITLE 56000
static int HotKey[] =
{
IF_FILE_OPENFILE,
IF_FILE_PLAYLIST,
IF_PLAY,
IF_PLAYPAUSE,
IF_PLAY_FULLSCREEN,
IF_STOP,
IF_MOVE_FFWD,
IF_MOVE_BACK,
IF_NEXT,
IF_PREV,
IF_PREV_SMART,
IF_NEXT2,
IF_PREV_SMART2,
IF_FASTFORWARD,
IF_OPTIONS_VOLUME_UP,
IF_OPTIONS_VOLUME_DOWN,
IF_OPTIONS_VOLUME_UP_FINE,
IF_OPTIONS_VOLUME_DOWN_FINE,
IF_OPTIONS_MUTE,
IF_OPTIONS_EQUALIZER,
IF_OPTIONS_FULLSCREEN,
IF_OPTIONS_ZOOM_FIT,
IF_OPTIONS_ZOOM_IN,
IF_OPTIONS_ZOOM_OUT,
IF_OPTIONS_ROTATE,
IF_OPTIONS_BRIGHTNESS_UP,
IF_OPTIONS_BRIGHTNESS_DOWN,
IF_OPTIONS_CONTRAST_UP,
IF_OPTIONS_CONTRAST_DOWN,
IF_OPTIONS_SATURATION_UP,
IF_OPTIONS_SATURATION_DOWN,
IF_OPTIONS_TOGGLE_VIDEO,
IF_OPTIONS_TOGGLE_AUDIO,
//!SUBTITLE IF_OPTIONS_TOGGLE_SUBTITLE,
IF_OPTIONS_AUDIO_STEREO_TOGGLE,
IF_OPTIONS_SCREEN,
IF_FILE_EXIT,
};
#define HOTKEYCOUNT (sizeof(HotKey)/sizeof(int))
typedef struct intface
{
win Win;
DWORD ThreadId;
player* Player;
node* Color;
node* Equalizer;
WNDPROC DefTrackProc;
WNDPROC DefVolProc;
HWND WndTrack;
HWND WndTitle;
HWND WndVol;
HWND WndVolBack;
int TrackThumb;
RECT ClientRect;
rect SkinViewport;
rect SkinArea;
rect Viewport;
int InSkin;
bool_t InVol;
bool_t InSeek;
bool_t Capture;
bool_t ForceFullScreen;
bool_t TrackBar;
bool_t TitleBar;
bool_t TaskBar;
bool_t Buttons;
bool_t Focus;
bool_t Clipping;
bool_t Overlap;
bool_t VolResizeNeeded;
bool_t VolResizeNeeded2;
bool_t Exited;
POINT Offset;
bool_t Bench;
bool_t Wait;
bool_t CmdLineMode;
int Vol;
int HotKey[HOTKEYCOUNT];
// refresh states
int TrackSetPos;
int TrackPos;
bool_t Play;
bool_t FFwd;
bool_t FullScreen;
bool_t Mute;
HFONT TitleFont;
int TitleFontSize;
tick_t TitleTime;
int TitleTimeWidth;
int TitleNameWidth;
int TitleNameSize;
int TitleNameOffset;
int ScrollMode;
bool_t UpdateScroll;
int TitleDurWidth;
int TitleBorder;
int TitleTop;
int TitleWidth;
int TitleHeight;
HBRUSH TitleBrush;
rgbval_t TitleFace;
rgbval_t TitleText;
tchar_t TitleName[256];
tchar_t TitleDur[32];
int MenuPreAmp;
int MenuStreams;
int MenuAStream;
int MenuVStream;
int MenuSubStream;
array VOutput;
array AOutput;
bool_t AllKeys;
bool_t AllKeysWarning;
int SkinNo;
skin Skin[MAX_SKIN];
tchar_t SkinPath[MAXPATH];
} intface;
static void ResizeVolume(intface* p)
{
if (p->WndVolBack)
{
RECT rv;
RECT r;
POINT o;
int Width;
int i;
GetClientRect(p->Win.WndTB,&r);
if (r.left<r.right)
{
SendMessage(p->Win.WndTB,TB_GETRECT,IF_OPTIONS_MUTE,(LPARAM)&rv);
#if defined(TARGET_WINCE)
if (p->Win.ToolBarHeight) // decrease width by 'X' button on right
r.right = max(r.left,r.right-(rv.right-rv.left));
#endif
Width = r.right-rv.right;
if (Width < 16)
Width = 16;
i = WinUnitToPixelX(&p->Win,50);
if (Width > i)
Width = i;
o.x = o.y = 0;
if (!p->Win.ToolBarHeight)
ClientToScreen(p->Win.WndTB,&o);
MoveWindow(p->WndVolBack,rv.right+o.x,o.y+1,Width,r.bottom-1,TRUE);
GetClientRect(p->WndVolBack,&r);
i = WinUnitToPixelX(&p->Win,2);
MoveWindow(p->WndVol,-i,0,r.right+2*i,r.bottom,TRUE);
SendMessage(p->WndVol, TBM_SETTHUMBLENGTH,WinUnitToPixelY(&p->Win,VOLTHUMB),0);
}
}
}
static bool_t Toggle(intface* p,int Param,int Force);
static void UpdateVolume(intface* p);
static void UpdateClipping(intface* p,bool_t Suggest,bool_t HotKey);
static void ShowVol(intface* p,bool_t Show)
{
if (p->WndVolBack && !p->Win.ToolBarHeight)
{
if (Show)
SetWindowPos(p->WndVolBack,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_SHOWWINDOW);
else
ShowWindow(p->WndVolBack,SW_HIDE);
if (p->VolResizeNeeded2>1)
p->VolResizeNeeded2=1;
}
}
static void Resize(intface* p)
{
RECT r;
bool_t Rotated = IsOrientationChanged();
DEBUG_MSG(DEBUG_VIDEO,T("Resize begin"));
if (Rotated)
{
p->Player->Set(p->Player,PLAYER_ROTATEBEGIN,NULL,0);
p->Player->Set(p->Player,PLAYER_RESETVIDEO,NULL,0);
if (!p->Win.ToolBarHeight)
{
p->VolResizeNeeded2 = 1; // toolbar position may change later
if (p->WndVolBack && IsWindowVisible(p->WndVolBack))
{
ShowVol(p,0);
p->VolResizeNeeded2 = 2;
}
}
else
p->VolResizeNeeded = 1;
if (p->Win.FullScreen)
PostMessage(p->Win.Wnd,MSG_PLAYER,PLAYER_FULLSCREEN,0);
}
p->Offset.x = 0;
p->Offset.y = 0;
ClientToScreen(p->Win.Wnd,&p->Offset);
if (!p->Win.FullScreen)
{
#if !defined(TARGET_WINCE) && defined(MAXIMIZE_FULLSCREEN)
WINDOWPLACEMENT Place;
Place.length = sizeof(Place);
GetWindowPlacement(p->Win.Wnd,&Place);
if (Place.showCmd != SW_MAXIMIZE)
#endif
{
GetClientRect(p->Win.Wnd,&r);
if (r.right != p->ClientRect.right || r.bottom != p->ClientRect.bottom)
{
bool_t Skin = p->Skin[p->SkinNo].Valid;
int TrackThumb;
int TrackHeight = 0;
p->TitleHeight = 0;
p->ClientRect = r;
r.top += p->Win.ToolBarHeight;
if (p->WndTrack)
{
TrackHeight = WinUnitToPixelY(&p->Win,TRACKHEIGHT);
r.bottom -= TrackHeight;
MoveWindow(p->WndTrack,r.left,r.bottom,r.right,TrackHeight,TRUE);
TrackThumb = WinUnitToPixelY(&p->Win,TRACKTHUMB);
if (p->TrackThumb != TrackThumb)
{
p->TrackThumb = TrackThumb; // avoid calling this regulary because it shows the trackbar
SendMessage(p->WndTrack, TBM_SETTHUMBLENGTH,TrackThumb,0);
}
}
if (p->WndTitle)
{
p->TitleTimeWidth = 0;
p->TitleFontSize = TITLEFONT;
p->TitleFont = WinFont(&p->Win,&p->TitleFontSize,0);
p->TitleHeight = WinUnitToPixelY(&p->Win,TITLEHEIGHT);
p->TitleBorder = WinUnitToPixelX(&p->Win,3);
p->TitleWidth = r.right - r.left;
if (Skin)
{
skinitem* i = &p->Skin[p->SkinNo].Item[SKIN_TITLE];
p->TitleWidth = i->Rect.Width;
p->TitleHeight = i->Rect.Height;
MoveWindow(p->WndTitle,r.left + i->Rect.x,r.top + i->Rect.y,p->TitleWidth,p->TitleHeight,TRUE);
}
else
{
if (p->Win.ToolBarHeight)
{
r.bottom -= p->TitleHeight;
MoveWindow(p->WndTitle,r.left,r.bottom,p->TitleWidth,p->TitleHeight,TRUE);
}
else
{
MoveWindow(p->WndTitle,r.left,r.top,p->TitleWidth,p->TitleHeight,TRUE);
r.top += p->TitleHeight;
}
}
p->TitleTop = (p->TitleHeight-WinUnitToPixelY(&p->Win,p->TitleFontSize))/2;
}
p->SkinArea.x = r.left;
p->SkinArea.y = r.top;
p->SkinArea.Width = r.right - r.left;
p->SkinArea.Height = r.bottom - r.top;\
if (!Skin)
p->SkinViewport = p->SkinArea;
else
{
p->SkinViewport = p->Skin[p->SkinNo].Item[SKIN_VIEWPORT].Rect;
p->SkinViewport.x += p->SkinArea.x;
p->SkinViewport.y += p->SkinArea.y;
}
if (p->Win.ToolBarHeight && !p->VolResizeNeeded)
ResizeVolume(p);
}
p->Viewport = p->SkinViewport;
p->Viewport.x += p->Offset.x;
p->Viewport.y += p->Offset.y;
p->Player->Set(p->Player,PLAYER_SKIN_VIEWPORT,&p->Viewport,sizeof(rect));
p->Player->Set(p->Player,PLAYER_UPDATEVIDEO,NULL,0);
if (p->VolResizeNeeded)
{
ResizeVolume(p);
p->VolResizeNeeded = 0;
}
}
}
else
{
GetClientRect(p->Win.Wnd,&r);
p->Viewport.x = r.left + p->Offset.x;
p->Viewport.y = r.top + p->Offset.y;
p->Viewport.Width = r.right - r.left;
p->Viewport.Height = r.bottom - r.top;
}
if (Rotated)
p->Player->Set(p->Player,PLAYER_ROTATEEND,NULL,0);
DEBUG_MSG4(DEBUG_VIDEO,T("Resize end %d,%d,%d,%d"),p->Viewport.x,p->Viewport.y,p->Viewport.Width,p->Viewport.Height);
}
static BOOL CALLBACK EnumCheck(HWND Wnd, LPARAM lParam )
{
intface* p = (intface*) lParam;
RECT r;
if (Wnd == p->Win.Wnd)
return 0;
if (IsWindowVisible(Wnd))
{
GetWindowRect(Wnd,&r);
if (p->Viewport.x < r.right &&
p->Viewport.x + p->Viewport.Width > r.left &&
p->Viewport.y < r.bottom &&
p->Viewport.y + p->Viewport.Height > r.top)
{
p->Overlap = 1;
return 0;
}
}
return 1;
}
static void UpdateHotKey(intface* p,bool_t State,bool_t NoKeep)
{
int i;
if (!p->AllKeys)
{
for (i=0;i<HOTKEYCOUNT;++i)
if (p->HotKey[i])
{
if (State)
{
if (!WinEssentialKey(p->HotKey[i]))
WinRegisterHotKey(&p->Win,HotKey[i],p->HotKey[i]);
}
else
if (NoKeep || !(p->HotKey[i] & HOTKEY_KEEP))
WinUnRegisterHotKey(&p->Win,HotKey[i]);
else
if (WinEssentialKey(p->HotKey[i])) //essential keys -> register in the background
WinRegisterHotKey(&p->Win,HotKey[i],p->HotKey[i]);
}
}
else
{
WinAllKeys(State);
if (!State && !NoKeep)
for (i=0;i<HOTKEYCOUNT;++i)
if (p->HotKey[i] & HOTKEY_KEEP)
WinRegisterHotKey(&p->Win,HotKey[i],p->HotKey[i]);
}
}
static void UpdateSleepTimer(intface* p)
{
#if defined(TARGET_WINCE)
if (p->Play>0 || p->FFwd>0)
{
SleepTimerReset();
SetTimer(p->Win.Wnd,TIMER_SLEEP,SLEEP_CYCLE,NULL);
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -