summaryrefslogtreecommitdiffstats
path: root/noatun/modules/kaiman
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commite2de64d6f1beb9e492daf5b886e19933c1fa41dd (patch)
tree9047cf9e6b5c43878d5bf82660adae77ceee097a /noatun/modules/kaiman
downloadtdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.tar.gz
tdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'noatun/modules/kaiman')
-rw-r--r--noatun/modules/kaiman/Makefile.am23
-rw-r--r--noatun/modules/kaiman/README3
-rw-r--r--noatun/modules/kaiman/SKIN-SPECS518
-rw-r--r--noatun/modules/kaiman/kaiman.plugin132
-rw-r--r--noatun/modules/kaiman/kaimanui.rc45
-rw-r--r--noatun/modules/kaiman/noatunui.cpp9
-rw-r--r--noatun/modules/kaiman/pref.cpp122
-rw-r--r--noatun/modules/kaiman/pref.h48
-rw-r--r--noatun/modules/kaiman/skins/Makefile.am3
-rw-r--r--noatun/modules/kaiman/skins/car-preset/Makefile.am10
-rw-r--r--noatun/modules/kaiman/skins/car-preset/README22
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_exit.pngbin0 -> 674 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_iconify.pngbin0 -> 585 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_list.pngbin0 -> 762 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_next.pngbin0 -> 1055 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_p1.pngbin0 -> 691 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_p2.pngbin0 -> 679 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_p3.pngbin0 -> 689 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_p4.pngbin0 -> 641 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_p5.pngbin0 -> 668 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_p6.pngbin0 -> 741 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_play.pngbin0 -> 623 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_prev.pngbin0 -> 1006 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_sml.pngbin0 -> 454 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_stop.pngbin0 -> 603 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_voldn.pngbin0 -> 923 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/btn_volup.pngbin0 -> 1026 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/digbig.pngbin0 -> 359 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/digmed.pngbin0 -> 318 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/letters.pngbin0 -> 1240 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/main.pngbin0 -> 7191 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/monoster.pngbin0 -> 169 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/posbar.pngbin0 -> 519 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/random.pngbin0 -> 178 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/repeat.pngbin0 -> 172 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/skindata71
-rw-r--r--noatun/modules/kaiman/skins/car-preset/status.pngbin0 -> 133 bytes
-rw-r--r--noatun/modules/kaiman/skins/car-preset/volume.pngbin0 -> 664 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/Makefile.am13
-rw-r--r--noatun/modules/kaiman/skins/circle/README22
-rw-r--r--noatun/modules/kaiman/skins/circle/back.pngbin0 -> 20249 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/back_mask.pngbin0 -> 1519 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/back_sm.pngbin0 -> 2166 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/back_sm_mask.pngbin0 -> 217 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/bar_pos.pngbin0 -> 1188 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/bar_vol.pngbin0 -> 1156 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_exit.pngbin0 -> 2326 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_iconify.pngbin0 -> 1899 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_list.pngbin0 -> 2525 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_mode.pngbin0 -> 2026 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_next.pngbin0 -> 2527 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_play.pngbin0 -> 3081 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_pref.pngbin0 -> 2610 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_prev.pngbin0 -> 2411 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_repeat.pngbin0 -> 2488 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_shuffle.pngbin0 -> 2504 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_sm_exit.pngbin0 -> 680 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_sm_iconify.pngbin0 -> 627 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_sm_mode.pngbin0 -> 852 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_sm_next.pngbin0 -> 759 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_sm_play.pngbin0 -> 1004 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_sm_prev.pngbin0 -> 776 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_sm_stop.pngbin0 -> 1022 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/btn_stop.pngbin0 -> 3186 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/dig.pngbin0 -> 370 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/digsml.pngbin0 -> 201 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/letters.pngbin0 -> 1260 bytes
-rw-r--r--noatun/modules/kaiman/skins/circle/skindata58
-rw-r--r--noatun/modules/kaiman/skins/circle/skindata_alt44
-rw-r--r--noatun/modules/kaiman/skins/circle/status.pngbin0 -> 121 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/Makefile.am11
-rw-r--r--noatun/modules/kaiman/skins/k9/README24
-rw-r--r--noatun/modules/kaiman/skins/k9/conf.jpgbin0 -> 771 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/conf.pngbin0 -> 2436 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/eject.jpgbin0 -> 6065 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/icon.jpgbin0 -> 569 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/icon.pngbin0 -> 1427 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/kill.jpgbin0 -> 536 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/kill.pngbin0 -> 1221 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/knine-nfont.jpgbin0 -> 1747 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/knine-nfont.pngbin0 -> 1226 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/knine-nfont2.jpgbin0 -> 1721 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/knine-nfont2.pngbin0 -> 1320 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/knine-normal2.jpgbin0 -> 17471 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/knine-normal2.pngbin0 -> 72057 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/knine-vfont.jpgbin0 -> 730 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/knine-vfont.pngbin0 -> 351 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/long2.jpgbin0 -> 146555 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/mask.pngbin0 -> 3865 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/newtext.jpgbin0 -> 3196 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/newtext.pngbin0 -> 3135 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/next.jpgbin0 -> 6840 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/pause.jpgbin0 -> 7683 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/play.jpgbin0 -> 8850 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/pos_item.jpgbin0 -> 166210 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/repeat.jpgbin0 -> 756 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/repeat.pngbin0 -> 1299 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/reverse.jpgbin0 -> 6904 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/shuffle.jpgbin0 -> 719 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/shuffle.pngbin0 -> 1268 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/skindata73
-rw-r--r--noatun/modules/kaiman/skins/k9/small-k.jpgbin0 -> 516 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/small-k.pngbin0 -> 1009 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/square.jpgbin0 -> 720 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/square.pngbin0 -> 1894 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/status.jpgbin0 -> 461 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/status.pngbin0 -> 246 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/stop.jpgbin0 -> 7743 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/trans-pos.pngbin0 -> 99 bytes
-rw-r--r--noatun/modules/kaiman/skins/k9/trans-slide.pngbin0 -> 105 bytes
-rw-r--r--noatun/modules/kaiman/style.cpp1504
-rw-r--r--noatun/modules/kaiman/style.h356
-rw-r--r--noatun/modules/kaiman/userinterface.cpp562
-rw-r--r--noatun/modules/kaiman/userinterface.h85
114 files changed, 3758 insertions, 0 deletions
diff --git a/noatun/modules/kaiman/Makefile.am b/noatun/modules/kaiman/Makefile.am
new file mode 100644
index 00000000..a8205a59
--- /dev/null
+++ b/noatun/modules/kaiman/Makefile.am
@@ -0,0 +1,23 @@
+SUBDIRS = skins
+INCLUDES= -I$(top_srcdir)/noatun/library $(all_includes)
+kde_module_LTLIBRARIES = noatun_kaiman.la
+
+noatun_kaiman_la_SOURCES = \
+ noatunui.cpp \
+ style.cpp \
+ userinterface.cpp \
+ pref.cpp
+
+noatun_kaiman_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined
+noatun_kaiman_la_LIBADD = $(LIB_KFILE) $(top_builddir)/noatun/library/libnoatun.la \
+ -lqtmcop -lkmedia2_idl -lsoundserver_idl
+
+noatun_kaiman_la_METASOURCES = AUTO
+
+noinst_HEADERS = \
+ userinterface.h \
+ style.h \
+ pref.h
+
+noatun_modules_kaiman_DATA = kaiman.plugin kaimanui.rc
+noatun_modules_kaimandir = $(kde_datadir)/noatun
diff --git a/noatun/modules/kaiman/README b/noatun/modules/kaiman/README
new file mode 100644
index 00000000..4c24a3ae
--- /dev/null
+++ b/noatun/modules/kaiman/README
@@ -0,0 +1,3 @@
+kaiman - Media player for KDE2.0
+
+
diff --git a/noatun/modules/kaiman/SKIN-SPECS b/noatun/modules/kaiman/SKIN-SPECS
new file mode 100644
index 00000000..bc3533ad
--- /dev/null
+++ b/noatun/modules/kaiman/SKIN-SPECS
@@ -0,0 +1,518 @@
+ ############ GQmpeg skin specifications file. ############
+
+ (A quick reference of what is required in the image files
+ for each widget type is located at the end of this document )
+
+Skins are simply a directory which contain image files and
+a skindata file (named skindata).
+
+All skin features are configured in the skindata file.
+
+Note: when using an alternate skin, it's specs go into a file named
+skindata_alt, it uses the same format as the skindata file. Pressing
+the Alt_Skin_Button button switches between the two skins.
+(each skin must contain an Alt_Skin_Button if you want the alternate
+skin feature to work)
+
+Any line can be made into a comment by prefacing it with a '#' symbol.
+
+All image files can be any size, GQmpeg will calculate the drawing data
+for you. Skins can have any size buttons, display items, digits,
+fonts, etc. The files can be of any type supported by gdk-pixbuf (xpm, png,
+jpeg, gif, etc.) The recommended file format is png.
+
+Prelights are optional on all items that support them. A prelight is an
+alternate image that is displayed when the mouse is over a pressable
+item (button, slider, dial). For example, the default skin includes prelights
+for all buttons, notice the buttons 'brighten' when the mouse moves over
+them.
+
+Every image within a file must have the same width and height, for example
+if the play button was 30 by 20, the resulting image file would be
+180 by 20. (6 button states total, including status lights and prelights)
+
+ Addendum: If the above button was specified with the status light and
+ prelight options as false, the resulting image file would be
+ 60 by 20. (2 button states total, 1 for normal, 1 for pressed)
+
+Note that images for buttons and numbers contain the items horizontally,
+the images for items contain the items vertically, the image for a font
+contains 3 rows of 32 items, and the slider contains the background and
+handle horizontally or vertically (depending if a slider is horizontal
+or verticle, respectivley).
+
+Only the background image is required, all other elements are optional
+(although it would be nice to always have a play button :)
+If you do not want an item displayed, comment out the line with
+a '#' symbol.
+
+IMPORTANT:
+Slots enclosed in "[]" are optional, but are so only to retain backward
+compatibility of skins. Please specify all options for each type as in the
+future the options enclosed in "[]" may no longer be "optional". Please
+separate each option with a single space, and do not add extra characters
+at the end of the line, as the extra info may be mistaken for expanded
+options in the event that options are added to the skin spec in the future.
+
+PROPER TRANSPARENCY:
+The main background image uses a threshold of 1 (out of 256 levels) for the
+window shape, the rest is used for partially overwiting the background when
+the Transparency option is true.
+
+Portions of items, buttons, sliders, numbers, and text that never change and
+are the same as the background image should be set transparent so that the
+'force transparent' option works properly.
+
+ ############# skindata file format #################
+
+Note: For an example skindata file see the file skindata-template.
+
+x and y are always the position in the window (use the -skinhelp command line
+option to have GQmpeg print out the mouse coordinates as the mouse moves)
+
+And finally, to what is available:
+
+==========================
+ Main options
+==========================
+
+Background: filename
+
+ filename
+ The background image file, the window will be the same size as this image.
+ Add transparency to this image for shaped skins, the cutoff threshold for
+ transparency is 1 on images with muli-level alpha (like in png).
+
+Transparency: flag
+
+ flag
+ True or False, this specifies if the background image (above) has a multiple
+ level alpha channel (as in png files) to apply when overwriting the root
+ window's background.
+
+Mask: filename
+
+(this is DEPRECATED!, for transparent skins just add transparency to the
+ Background image, Mask remains merely for backwards compatibility)
+ filename
+ The mask image file, only needed for skins which are shaped windows (not
+ rectangular). Contains a transparency mask for the main window.
+
+==========================
+ Text display
+==========================
+
+Title/Album/Artist/Genre: filename length [extended] x y
+
+ filename
+ Should contain a fixed font. With 3 or 6 lines of 32 characters each,
+ these are the characters, they are listed in three rows so you can copy
+ and past them into you graphics program. (first character in the top line
+ is a space)
+
+ !"#$%&'()*+,-./0123456789:;<=>?
+ @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
+ `abcdefghijklmnopqrstuvwxyz{|}~
+
+ When extended is TRUE these are the 3 addition lines of international chars
+
+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ XXXXXXX FIXME! TO DO! XXXXXXXXXX
+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+
+ length
+ Maximum number of characters to display in window.
+
+ extended
+ (optional, absence defaults to FALSE)
+ When TRUE, the image contains 3 additional lines for internation
+ characters. The result is 6 lines of 32 characters each.
+
+==========================
+ Buttons (that optionally include an 'active' mode)
+==========================
+
+Play/Pause/Stop/Shuffle/Repeat/
+ Time_Remaining/Time_Total_Button: filename prelight status_light x y [clip_filename]
+
+ filename
+ Image file. Contains the buttons horizontally in this order:
+ normal, normal pressed, normal active, normal active pressed, prelit, prelit active
+ (the actual number of images may vary, see next two options)
+
+ prelight
+ TRUE or FALSE, specifies whether or not prelight buttons are available, If
+ FALSE, do not include the last two prelight buttons in the image file.
+
+ status_light
+ TRUE or FALSE, specifies whether or not button lights are available. If FALSE,
+ do not include the 'lit up', 'lit down', and 'prelight lit up' buttons in the
+ image file.
+
+ clip_filename (optional)
+ When specified, defines an image with transparency to be used as the button's
+ draw clip mask. The clip mask is placed at location x, y The transparency is used to
+ indicate the portions of the button that should be visible (drawn) and respond to
+ mouse clicks. If the image contains a multiple level alpha channel, the mask is reduced
+ such that levels above 50% are visible and those below 50% are not visible.
+
+==========================
+ Buttons (standard)
+==========================
+
+Next/Prev/FF/RW/Playlist/Config/Iconify/Mixer/Exit/Alt_Skin/Volume_Up/Volume_Down/
+ Balance_Left/Balance_Right_Button: filename prelight x y [clip_filename]
+Preset_1_/.../Preset_10_Button: filename prelight x y [clip_filename]
+
+ filename
+ Image file. Contains the buttons horizontally in this order:
+ normal, normal pressed, prelit
+ (the actual number of images may vary, see next option)
+
+ prelight
+ TRUE or FALSE, specifies whether or not prelight buttons are available. If
+ FALSE, do not include the last prelight button in the image file.
+
+ clip_filename (optional)
+ When specified, defines an image with transparency to be used as the button's
+ draw clip mask. The clip mask is placed at location x, y The transparency is used to
+ indicate the portions of the button that should be visible (drawn) and respond to
+ mouse clicks. If the image contains a multiple level alpha channel, the mask is reduced
+ such that levels above 50% are visible and those below 50% are not visible.
+
+
+==========================
+ Items (with fixed number sections)
+==========================
+
+Stereo/Shuffle/Repeat/Mpegversion/Mpeglayer/Mpegmode/Status/
+ Minus/Total_Item: filename x y
+
+ filename
+ Image file. Contains the items vertically in the order below:
+
+ Stereo_Item: blank, mono , stereo
+ Shuffle_Item: off, on
+ Repeat_Item: off, on
+ Mpegversion_Item: blank, 1, 2
+ Mpeglayer_Item: blank, 1, 2, 3
+ Mpegmode_Item: blank, stereo, joint-stereo, dual-channel, single-channel
+ Status_Item: stop, pause, play
+ Minus_Item: time counts up, time counts down
+ Total_Item: time refers to current song only, to total playlist, to live
+
+==========================
+ Items (animation oriented)
+==========================
+
+Load_Item: filename sections x y
+
+ filename
+ Image file. Contains animations for the following items:
+
+ Load_Item: Animation for loading playlist in background.
+
+ sections
+ The total number of sections in the image file. The first section is always
+ blank (animation is off), the subsequent images are cycled through to create
+ the animation. This number is a total count, so it will be 1 (first is always
+ blank) plus the number of animation frames.
+
+==========================
+ Items (value oriented)
+==========================
+
+Position/Volume/Balance_Item: filename sections x y
+
+ filename
+ Image file. Contains images vertically in the order representing the lowest to
+ highest values.
+
+ sections
+ The number of images within the file, recommended number of images is 16 to 32.
+ The most possible usable images is 101 for volume and blance (from volume=0%
+ to volume = 100%).
+
+ Note:
+ These items must be listed before their respective sliders:
+ (see Position/Volume/Balance_Slider).
+
+==========================
+ Digit placeholder (for convenience, less memory usage with many similar numbers)
+==========================
+
+Digit_Large/Digit_Small_Default: filename
+
+ filename
+ Image file. Contains digits horizontally from 0 to 9, and a blank space.
+
+ These two digits are a convenience function, if you want to use a digit more than
+ once it is quicker to load it into on of these two slots. Then when using the digit
+ in the number item type below, use the words 'Large' or 'Small' in place of the
+ filename.
+
+==========================
+ Numbers
+==========================
+
+Hour/Minute/Second/Song/Total/In_Rate/In_Hz/Out_Bits/Out_Hz/
+ Song_Minute/Song_Second/Frame/Frame_Total/CPU/
+ Hour_Total/Minute_Total/Second_Total_Number: filename [length center] x y
+
+ filename
+ Image file for the number's digit, or the word 'Large' or 'Small' (see above).
+ If a filename is specified, the image should contain the digits horizontally
+ from 0 to 9, and a blank space.
+
+ length (optional)
+ The number of digits to display, if not present the default is assumed.
+
+ center (optional, but if specified length is required too)
+ TRUE or FALSE, specify to center the number.
+
+==========================
+ Sliders
+==========================
+
+Position/Volume/Balance_Slider: filename prelight [verticle reversed] length x y
+
+ filename
+ Image file. Contains images horizontally in this order:
+ slider background, handle normal, handle pressed, handle prelit
+ (handles must have the same dimensions)
+
+ prelight
+ TRUE or FALSE, specifies whether or not a prelight handle is available, if FALSE,
+ do not include a 'handle prelit' in the image file.
+
+ verticle
+ TRUE or FALSE. If false the slider is horizontal, if true, verticle.
+
+ reversed
+ TRUE or FALSE. If true, the slider works opposite than normal. For example
+ when false the slider moves from left to right, when true the slider moves
+ from right to left. On a verticle slider and reversed is false, the slider
+ moves from top to bottom.
+
+ length
+ The width of the slider's background, this is the complete width the slider will
+ be in the window, and must match the length of the 'slider background' in the
+ image file.
+
+==========================
+ Dials (AKA knobs)
+==========================
+
+Position/Volume/Balance_Dial: filename has_press_image has_prelight_image reversed
+ angle_start angle_end handle_offset_x handle_offset_y center_x center_y
+ x y w h [clip_filename]
+
+ filename
+ Image file. Contains images for the dial's handle vertically in this order:
+ normal
+ pressed (being dragged with mouse, optional)
+ prelit (mouse over highlight, optional)
+
+ has_press_image
+ TRUE or FALSE, specifies whether or not handle has a pressed image (above)
+
+ has_prelight_image
+ TRUE or FALSE, specifies whether or not handle has a pressed image (above)
+
+ reversed
+ TRUE of FALSE, normally a dial works clockwise with angle_start being the
+ lowest (zero) value and angle_end being the highest value. When TRUE the dial
+ works counter-clockwise with angle_end being the lowest (zero) value to
+ angle_start being the highest position.
+
+ angle_start
+ angle_end
+ The start and end angles define the end points of the dial's rotation in integer
+ degrees, the degrees count from 0 located right of center axis increasing clockwise
+ to a value of 359. (360 is equivelent to 0, but the only accepted numbers are 0 - 359.
+ This (admittedly poor) figure might help:
+
+
+ 270 ____ center axis
+ _|_ /
+ / /
+ / / \
+ 180 -| + |- 0 (360)
+ \ /
+ \_ _/
+ |
+ 90
+
+ handle_offset_x
+ handle_offset_y
+ The x and y coordinates into the handle image that represents the handle center
+ of rotation (pivot point), this does not have to actually be within the image size.
+
+ center_x
+ center_y
+ The x and y coordinates on the skin image for the handle center of rotation.
+
+ x, y, width, height:
+ Marks the clipping region to draw the dial, basically the handle is not drawn
+ outside this region. (width and height will be ignored if a clip mask image
+ is specified (see next option).
+
+ clip_filename (optional)
+ When specified, defines an image with transparency to be used as the dial's
+ draw clip mask. The clip mask is placed at x, y (above) and the image's dimensions
+ are used in place of width, height (above). The transparency is used to indicate the
+ portions of the dial that should be visible (drawn) and respond to mouse clicks.
+ If the image contains a multiple level alpha channel, the mask is reduced such that
+ levels above 50% are visible and those below 50% are not visible.
+
+==============================================================================
+ ************ Quick reference tables **************
+==============================================================================
+
+Note: All example values below set (*)coordinates x=1 and y=1, and filename to fn.png.
+ (*) Except Dials.
+
+--------------------------
+ Buttons (all button images contained horizontally)
+--------------------------
+
+Play/Pause/Stop/Shuffle/Repeat_Button: filename prelight status_light x y
+Time_Remaining/Time_Total_Button: filename prelight status_light x y
+
+Option line: | # images | Normal | Pressed | Lit | Lit | Prelit | Prelit |
+ | total | | | Normal | Pressed | Normal | Lit Normal |
+-----------------------+----------+--------+---------+--------+---------+--------+------------+
+ fn.png TRUE TRUE 1 1 | 6 | X | X | X | X | X | X |
+ fn.png TRUE FALSE 1 1 | 3 | X | X | | | X | |
+ fn.png FALSE TRUE 1 1 | 4 | X | X | X | X | | |
+ fn.png FALSE FALSE 1 1| 2 | X | X | | | | |
+
+Next/Prev/FF/RW/Playlist/Config/Iconify/Mixer/Exit/Alt_Skin_Button: filename prelight x y
+Volume_Up/Volume_Down/Balance_Left/Balance_Right_Button: filename prelight x y
+
+Option line: | # images | Normal | Pressed | Prelit |
+ | total | | | Normal |
+-----------------------+----------+--------+---------+--------+
+ fn.png TRUE 1 1 | 3 | X | X | X |
+ fn.png FALSE 1 1 | 2 | X | X | |
+
+
+--------------------------
+ Items (all item images contained vertically)
+--------------------------
+
+Stereo/Shuffle/Repeat/Mpegversion/Mpeglayer/Mpegmode/Status/Minus/Total_Item: filename x y
+
+Item: | # images | Image 1 | Image 2 | Image 3 | Image 4 | Image 5 |
+ | total | | | | | |
+-----------------------+----------+---------+---------+---------+---------+---------+
+ Stereo_Item | 3 | blank | mono | stereo | | |
+ Shuffle_Item | 2 | off | on | | | |
+ Repeat_Item | 2 | off | on | | | |
+ Mpegversion_Item | 3 | blank | ver 1 | ver 2 | | |
+ Mpeglayer_Item | 4 | blank | layer 1 | layer 2 | layer 3 | |
+ Mpegmode_Item | 5 | blank | stereo | j-stereo| dual-ch |single-ch|
+ Status_Item | 3 | stop | pause | play | | |
+ Minus_Item | 2 | normal |remaining| | | |
+ Total_Item | 2 | normal | total | live | | |
+
+
+Load_Item: filename section_count x y
+
+(These are special Animation items, any number of sections can be included)
+
+Option line: | # images | Image 1 | Image 2 | ....... | Last Image |
+ | total | | | | |
+-------------------+----------+---------+---------+---------+------------+
+ fn.png 8 1 1 | 8 | blank | Frame 1 | F2...F6 | Frame 7 |
+ fn.png 4 1 1 | 4 | blank | Frame 1 | Frame 2 | Frame 3 |
+
+
+Position/Volume/Balance_Item: filename sections x y
+
+Option Line: (*) | # images | 1st Image | middle Image | Last Image |
+ | total | | | |
+----------------------------+----------+-----------+--------------+---------------+
+ Volume_Item fn.png 17 1 1 | 17 | 1 - 0% vol| 9 - 50 % vol | 17 - 100% vol |
+ Volume_Item fn.png 31 1 1 | 31 | 1 - 0% vol| 16 - 50 % vol| 31 - 100% vol |
+ Balance_Item fn.png 17 1 1 | 17 | 1 - Left | 9 - middle | 17 - Right |
+ Balance_Item fn.png 13 1 1 | 13 | 1 - Left | 6 - middle | 13 - Right |
+
+ (*)note: The values (17, 31, 17, 13) above are only examples, any number of images
+ can be specified.
+
+
+--------------------------
+ Sliders (all slider images contained horizontally)
+--------------------------
+
+Position/Volume/Balance_Slider: filename prelight [verticle reversed] length x y
+
+Option line: | # images | Background | Normal | Pressed | Prelit |
+ | total | width | | | Normal |
+-----------------------------------+----------+-------------+--------+---------+--------+
+ fn.png TRUE FALSE FALSE 32 1 1 | 4 | 32 pixels | X | X | X |
+ fn.png FALSE FALSE FALSE 250 1 1 | 3 | 250 pixels | X | X | |
+
+
+--------------------------
+ Dials (can be confusing, see detailed description, above)
+--------------------------
+
+Position/Volume/Balance_Dial: filename has_press_image has_prelight_image reversed
+ angle_start angle_end handle_offset_x handle_offset_y center_x center_y
+ x y w h [clip_filename]
+
+Option line: | # images | Normal | Pressed | Prelit |
+ | total | | | Normal |
+----------------------------------------------------------+----------+--------+---------+--------+
+ fn.png TRUE TRUE TRUE 0 180 16 16 200 100 140 40 80 80 | 3 | X | X | X |
+ fn.png FALSE TRUE TRUE 0 180 16 16 200 100 140 40 80 80 | 2 | X | | X |
+ fn.png FALSE FALSE TRUE 0 180 16 16 200 100 140 40 80 80 | 1 | X | | |
+
+--------------------------
+ Numbers (all number images contained horizontally)
+--------------------------
+
+*_Number: filename [length centered] x y
+
+Option line: | # images | Images in order (left to right) |
+ | total | |
+---------------------+----------+------------------------------------------------+
+ fn.png 1 1 | 11 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " "(blank space) |
+ fn.png 3 FALSE 1 1 | 11 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " "(blank space) |
+
+
+--------------------------
+ Fonts (all font images contained in 3 or 6 rows of 32 columns)
+--------------------------
+
+Title/Album/Artist/Genre: filename length [extended] x y
+
+Option line: | # images | Images in order |
+ | total | |
+------------------------+----------+--------------------+
+ fn.png 16 1 1 | 96 | see grid 1 (below) |
+ fn.png 16 FALSE 1 1 | 96 | see grid 1 (below) |
+ fn.png 16 TRUE 1 1 | 192 | see grid 2 (below) |
+
+ +------------------------------------+
+character grid 1: | |
+(standard) | !"#$%&'()*+,-./0123456789:;<=>? |
+ | @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ |
+ | `abcdefghijklmnopqrstuvwxyz{|}~ |
+ | |
+ +------------------------------------+
+
+ +------------------------------------+
+character grid 2: | |
+(international | !"#$%&'()*+,-./0123456789:;<=>? |
+ extended) | @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ |
+ | `abcdefghijklmnopqrstuvwxyz{|}~ |
+ | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
+ | XXXXXXX FIXME! TO DO! XXXXXXXXXX |
+ | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
+ | |
+ +------------------------------------+
+
+#################################
diff --git a/noatun/modules/kaiman/kaiman.plugin b/noatun/modules/kaiman/kaiman.plugin
new file mode 100644
index 00000000..1b345de3
--- /dev/null
+++ b/noatun/modules/kaiman/kaiman.plugin
@@ -0,0 +1,132 @@
+Filename=noatun_kaiman.la
+Author=Stefan Schimanski
+Site=http://www.derkarl.org/noatun
+Type=userinterface
+License=GPL
+Name=Kaiman Interface
+Name[af]=Kaiman Koppelvlak
+Name[ar]=واجهة Kaiman
+Name[az]=Kaiman Ara üzü
+Name[bn]=কাইমান ইন্টারফেস
+Name[br]=Etrefas Kaiman
+Name[ca]=Interfície Kaiman
+Name[cs]=Rozhraní Kaimana
+Name[cy]=Rhyngwyneb Kaiman
+Name[da]=Kaiman-grænseflade
+Name[de]=Kaiman-Oberfläche
+Name[el]=Περιβάλλον Kaiman
+Name[eo]=Kajmaninterfaco
+Name[es]=Interfaz de Kaiman
+Name[et]=Kaiman kasutajaliides
+Name[eu]=Kaiman interfazea
+Name[fa]=واسط Kaiman
+Name[fi]=Kaiman-käyttöliittymä
+Name[fr]=Interface de Kaiman
+Name[ga]=Comhéadan Kaiman
+Name[gl]=Interface Kayman
+Name[he]=ממשק Kaiman
+Name[hi]= काईमेन इंटरफेस
+Name[hr]=Kaiman sučelje
+Name[hu]=Kaiman felület
+Name[is]=Kaiman aðgangur
+Name[it]=Interfaccia Kaiman
+Name[ja]=Kaiman インターフェース
+Name[kk]=Kaiman интерфейсі
+Name[km]=ចំណុច​ប្រទាក់ Kaiman
+Name[ko]=Kaiman 인터페이스
+Name[lt]=Kaiman sąsaja
+Name[lv]=Kaiman Starpseja
+Name[mk]=Интерфејс Kaiman
+Name[mt]=Interfaċċja Kaiman
+Name[nb]=Kaiman grensesnitt
+Name[nds]=Kaiman-Böversiet
+Name[ne]=काइम्यान इन्टरफेस
+Name[nl]=Kaiman interface
+Name[nn]=Kaiman-grensesnitt
+Name[pl]=Motyw Kaimana
+Name[pt]=Interface do Kaiman
+Name[pt_BR]=Interface do Kaiman
+Name[ro]=Interfaţă Kaiman
+Name[ru]=Интерфейс Кайман
+Name[se]=Kaiman-lakta
+Name[sk]=Rozhranie Kaimana
+Name[sl]=Vmesnik Kaiman
+Name[sr]=Kaiman интерфејс
+Name[sr@Latn]=Kaiman interfejs
+Name[sv]=Kaiman-gränssnitt
+Name[ta]=Kaiman இடைமுகம்
+Name[tg]=Интерфейси Kaiman
+Name[th]=ส่วนติดต่อ Kaiman
+Name[tr]=Kaiman Arayüzü
+Name[uk]=Інтерфейс Kaiman
+Name[uz]=Kaiman interfeysi
+Name[uz@cyrillic]=Kaiman интерфейси
+Name[ven]=Interface ya Kaiman
+Name[xh]=Ujongano lwe Kaiman
+Name[zh_CN]=Kaiman 接口
+Name[zh_HK]=Kaiman 介面
+Name[zh_TW]=Kaiman 介面
+Name[zu]=Uxhumano olubhekeneyo lwe Kaiman
+Comment=A GQMpeg skin interface ported from Kaiman
+Comment[af]='n Gqmpeg vel koppelvlak oorgedra van Kaiman
+Comment[ar]=واجهة GQMpeg مأخوذة من Kaiman
+Comment[az]=Kaiman'dan alınan GQMpeg dekorsiya axtar üzü
+Comment[bg]=Интерфейс за GQMpeg прехвърлен за Kaiman
+Comment[bs]=GQMpeg skin interface prebačen sa Kaiman-a
+Comment[ca]=Una aparença d'interfície GQMpeg portada de Kaiman
+Comment[cs]=Motiv rozhraní GQMpegu přenesený z Kaimana
+Comment[cy]=Rhyngwyneb croen GQMpeg wedi'i droi o Kaiman
+Comment[da]=En GQMpeg-forsidegrænseflade overført fra Kaiman
+Comment[de]=Eine Schnittstelle zur GQMpeg-Optik, aus Kaiman übernommen
+Comment[el]=Μια διασύνδεση βασισμένη στο θέμα GQMpeg προσαρμοσμένο από το Kaiman
+Comment[eo]=GQMpeg-etosinterfaco portita de Kajmano
+Comment[es]=Una interfaz de pieles GQMpeg portado de Kaiman
+Comment[et]=Kaimanist porditud GQMpeg skinnide toetus
+Comment[eu]=GQMpeg azal interfazea Kaiman-etik ekarria
+Comment[fa]=یک واسط GQMpeg skin که از Kaiman آورده شده است
+Comment[fi]=GQMpeg-käyttöliittymärajapinta Kaimanille
+Comment[fr]=Un revêtement à la GQMpeg importé de Kaiman
+Comment[gl]=Unha pel para a interface GQMPeg importada de Kaiman
+Comment[he]=ממשק Skin של GQMpeg שיובא מתוך Kaiman
+Comment[hi]=काईमेन से पोर्टेड जीक्यू-एमपीईजी इंटरफेस
+Comment[hr]=GQMpeg sučelje za kože uvezeno iz Kaiman-a
+Comment[hu]=A Kaimanban használt GQMpeg kinézet átültetett változata
+Comment[is]=GQMpeg skinn frá Kaiman
+Comment[it]=Una skin per GQMpeg convertita da Kaiman
+Comment[ja]=Kaiman から移植した GQMpeg スキンインターフェース
+Comment[kk]=Kaiman-нан аударылған GQMpeg тыстарының интерфейсі
+Comment[km]=ចំណុច​ប្រទាក់​ស្បែក GQMpeg ដែល​បាន​បញ្ចូល​ពី Kaiman
+Comment[ko]=Kaiman에서 이식된 GQMpeg 스킨
+Comment[lt]=GQMpeg pavidalų sąsaja, pritaikyta nuo Kaiman
+Comment[lv]=GQMpeg ādu starpseja pārcelta no Kaimana
+Comment[mk]=Интерфејс GQMpeg за маски пренесен од Kaiman
+Comment[ms]=Kulit antaramuka GQMpeg dari Kaiman
+Comment[mt]=Interfaċċja għal faċċati GQMpeg portata minn Kaiman
+Comment[nb]=Et GQMpeg ham-grensesnitt tatt fra Kaiman
+Comment[nds]=En GQMpeg-Böversiet, vun Kaiman överdragen
+Comment[ne]=काइम्यानबाट परिमार्जन गरिएको GQMpeg स्किन इन्टरफेस
+Comment[nl]=Een GQMpeg-skin-interface, overgedragen van Kaiman
+Comment[nn]=Eit GQMpeg-skalgrensesnitt porta frå Kaiman
+Comment[pl]=Motyw skór GQMpeg przeniesiony z Kaimana
+Comment[pt]=A interface de aspectos do GQMpeg transposta para o Kaiman
+Comment[pt_BR]=Uma interface de aparência (skin) GQMpeg portada do Kaiman
+Comment[ro]=O interfaţă GQMpeg portată de la Kaiman
+Comment[ru]=Интерфейс образов GQMpeg, перенесенный из Каймана
+Comment[se]=GQMpeg-náhkkelakta portejuvvon Kaimanas
+Comment[sk]=Téma rozhrania GQMpeq prenesená z Kaimana
+Comment[sl]=Vmesnik preobleke GQMpeg, prenesen iz Kaimana
+Comment[sr]=GQMpeg интерфејс скинова пренесен са из Kaiman-а
+Comment[sr@Latn]=GQMpeg interfejs skinova prenesen sa iz Kaiman-a
+Comment[sv]=Gqmpeg-skalgränssnitt överfört från Kaiman
+Comment[ta]=GQMpeg தோல் இடைமுகம் காய்மானில் இருந்து இறக்கப்பட்டது
+Comment[tg]=Намуди интерфейси GQMpeg, ки аз Kaiman даргоҳбандӣ шудааст
+Comment[th]=ส่วนติดต่อหน้ากาก GQMpeg ที่ข้ามระบบมาให้ใช้กับ Kaiman
+Comment[tr]=Kaiman'dan alınan GQMpeg dekor arayüzü
+Comment[uk]=Інтерфейс жупанів GQMpeg, перенесено з Kaiman
+Comment[ven]=Lukanda lwa GQMpeg lu vhonwaho kha Kaiman
+Comment[xh]=GQMpeg wojongano nolusu olunezibuko olusuka kwi Kaiman
+Comment[zh_CN]=从 Kaiman 移植的 GQMpeg 外观
+Comment[zh_HK]=從 Kaiman 移植的 GQMpeg 外貌主題
+Comment[zh_TW]=從 Kaiman 移植的 GQMpeg 外表
+Comment[zu]=A GQMpeg uxhumano lwesikhumba ported from Kaiman
diff --git a/noatun/modules/kaiman/kaimanui.rc b/noatun/modules/kaiman/kaimanui.rc
new file mode 100644
index 00000000..fb2696ff
--- /dev/null
+++ b/noatun/modules/kaiman/kaimanui.rc
@@ -0,0 +1,45 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="noatunkaiman" version="1">
+<ActionProperties>
+ <Action name="play" icon="noatunplay"/>
+ <Action name="stop" icon="noatunstop"/>
+ <Action name="back" icon="noatunback"/>
+ <Action name="forward" icon="noatunforward"/>
+ <Action name="show_playlist" icon="noatunplaylist"/>
+</ActionProperties>
+<MenuBar>
+ <Menu name="file" noMerge="1"><text>&amp;File</text>
+ <Action name="file_open"/>
+ <Separator lineSeparator="true"/>
+ <Action name="file_quit"/>
+ </Menu>
+ <Menu name="go_music" noMerge="1"><text>&amp;Go</text>
+ <Action name="back"/>
+ <Action name="stop"/>
+ <Action name="play"/>
+ <Action name="forward"/>
+ </Menu>
+ <Menu name="settings" noMerge="1"><text>&amp;Settings</text>
+ <Action name="options_show_toolbar"/>
+ <Action name="show_playlist"/>
+ <Separator lineSeparator="true"/>
+ <Action name="options_configure"/>
+ <Action name="effects"/>
+ <Separator lineSeparator="true"/>
+ <Action name="loop_style"/>
+ </Menu>
+</MenuBar>
+<Toolbar name="main"><text>Main Toolbar</text>
+ <Action name="file_quit"/>
+ <Separator lineSeparator="true"/>
+ <Action name="back"/>
+ <Action name="stop"/>
+ <Action name="play"/>
+ <Action name="forward"/>
+ <Separator lineSeparator="true"/>
+ <Action name="file_open"/>
+ <Action name="show_playlist"/>
+ <Separator lineSeparator="true"/>
+ <Action name="loop_style"/>
+</Toolbar>
+</kpartgui>
diff --git a/noatun/modules/kaiman/noatunui.cpp b/noatun/modules/kaiman/noatunui.cpp
new file mode 100644
index 00000000..bc1bceb0
--- /dev/null
+++ b/noatun/modules/kaiman/noatunui.cpp
@@ -0,0 +1,9 @@
+#include "userinterface.h"
+
+extern "C"
+{
+ KDE_EXPORT Plugin *create_plugin()
+ {
+ return new Kaiman();
+ }
+}
diff --git a/noatun/modules/kaiman/pref.cpp b/noatun/modules/kaiman/pref.cpp
new file mode 100644
index 00000000..892435fc
--- /dev/null
+++ b/noatun/modules/kaiman/pref.cpp
@@ -0,0 +1,122 @@
+/*
+ Copyright (c) 1999-2000 Stefan Schimanski <[email protected]>
+
+ 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, 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.
+*/
+
+#include <klocale.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <klistbox.h>
+#include <qdir.h>
+#include <qfileinfo.h>
+#include <kglobal.h>
+#include <kdebug.h>
+#include <kstandarddirs.h>
+#include <kconfig.h>
+
+#include "pref.h"
+#include "userinterface.h"
+
+
+KaimanPrefDlg::KaimanPrefDlg(QObject *parent )
+ : CModule(i18n("Kaiman Skins"), i18n("Skin Selection for the Kaiman Plugin"), "style", parent)
+{
+ // create widgets
+ QVBoxLayout *topLayout = new QVBoxLayout( this, 6, 11 );
+ QLabel *label = new QLabel( i18n("Kaiman Skins"), this, "label" );
+ topLayout->addWidget( label );
+
+ _skinList = new KListBox( this, "skinList" );
+ topLayout->addWidget( _skinList, 1 );
+ reopen();
+}
+
+
+KaimanPrefDlg::~KaimanPrefDlg()
+{
+}
+
+
+void KaimanPrefDlg::save()
+{
+ KConfig *config=KGlobal::config();
+ config->setGroup("Kaiman");
+ config->writeEntry("SkinResource", skin() );
+ config->sync();
+
+ Kaiman *l=Kaiman::kaiman;
+ if ( l ) {
+ l->changeStyle( skin() );
+ }
+}
+
+void KaimanPrefDlg::reopen()
+{
+ _skinList->clear();
+ // fill with available skins
+ KGlobal::dirs()->addResourceType("skins", KStandardDirs::kde_default("data") + "noatun/skins/kaiman/");
+ QStringList list = KGlobal::dirs()->resourceDirs("skins");
+ for (QStringList::ConstIterator it = list.begin(); it != list.end(); it++)
+ readSkinDir(*it);
+
+ // load current config
+ KConfig *config=KGlobal::config();
+ config->setGroup("Kaiman");
+ QString skin = config->readEntry( "SkinResource", Kaiman::DEFAULT_SKIN );
+ QListBoxItem *item = _skinList->findItem( skin );
+ if ( item )
+ _skinList->setCurrentItem( item );
+ else
+ _skinList->setCurrentItem( 0 );
+}
+
+
+void KaimanPrefDlg::setSkin( QString skin )
+{
+ _skinList->setCurrentItem( _skinList->findItem( skin ) );
+}
+
+
+QString KaimanPrefDlg::skin()
+{
+ return _skinList->currentText();
+}
+
+
+void KaimanPrefDlg::readSkinDir( const QString &dir )
+{
+ kdDebug() << "readSkinDir " << dir << endl;
+
+ QDir directory( dir );
+ if (!directory.exists())
+ return;
+
+ const QFileInfoList *list = directory.entryInfoList();
+ QFileInfoListIterator it(*list);
+
+ while ( it.current() ) {
+ kdDebug() << it.current()->absFilePath() << endl;
+ QFileInfo skindata( it.current()->absFilePath()+"/skindata" );
+
+ if ( skindata.exists() ) {
+ _skinList->insertItem( it.current()->baseName() );
+ }
+
+ ++it;
+ }
+}
+
+#include "pref.moc"
diff --git a/noatun/modules/kaiman/pref.h b/noatun/modules/kaiman/pref.h
new file mode 100644
index 00000000..551dd16a
--- /dev/null
+++ b/noatun/modules/kaiman/pref.h
@@ -0,0 +1,48 @@
+/*
+ Copyright (c) 1999-2000 Stefan Schimanski <[email protected]>
+
+ 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, 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.
+*/
+
+#ifndef PREF_H_INCLUDED
+#define PREF_H_INCLUDED
+
+#include <noatun/pref.h>
+
+class KListBox;
+class QLabel;
+
+class KaimanPrefDlg : public CModule
+{
+ Q_OBJECT
+ public:
+ KaimanPrefDlg( QObject *parent );
+ virtual ~KaimanPrefDlg();
+
+ virtual void save();
+ virtual void reopen();
+
+ public slots:
+ void setSkin( QString skin );
+ QString skin();
+
+ private:
+ void readSkinDir( const QString &dir );
+
+ KListBox *_skinList;
+};
+
+#endif
+
diff --git a/noatun/modules/kaiman/skins/Makefile.am b/noatun/modules/kaiman/skins/Makefile.am
new file mode 100644
index 00000000..0d3d6687
--- /dev/null
+++ b/noatun/modules/kaiman/skins/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = k9 car-preset circle
+
+skinsdir = $(kde_datadir)/Skins
diff --git a/noatun/modules/kaiman/skins/car-preset/Makefile.am b/noatun/modules/kaiman/skins/car-preset/Makefile.am
new file mode 100644
index 00000000..646898d0
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/Makefile.am
@@ -0,0 +1,10 @@
+skin_DATA = btn_p1.png btn_play.png digbig.png random.png \
+ btn_p2.png btn_prev.png digmed.png repeat.png \
+btn_exit.png btn_p3.png btn_sml.png letters.png skindata \
+btn_iconify.png btn_p4.png btn_stop.png main.png status.png \
+btn_list.png btn_p5.png btn_voldn.png monoster.png volume.png \
+btn_next.png btn_p6.png btn_volup.png posbar.png
+
+skindir = $(kde_datadir)/noatun/skins/kaiman/car-preset
+
+EXTRA_DIST = $(skin_DATA)
diff --git a/noatun/modules/kaiman/skins/car-preset/README b/noatun/modules/kaiman/skins/car-preset/README
new file mode 100644
index 00000000..fedefaaa
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/README
@@ -0,0 +1,22 @@
+GQmpeg skin directory: car-preset
+Author: Johne Ellis <[email protected]>
+Released: October 25, 1998
+Version: 1.0
+URL:
+Comment: Skin similar to an automotive stereo, complete
+ with presets.
+Note: For the presets and volume controls to work, GQmpeg
+ 0.3.6 is required. Previous versions will work,
+ except for these functions.
+
+To use this skin with GQmpeg, use the command line:
+
+ gqmpeg -skin:car-preset
+
+Or when editing skin data, point GQmpeg to this skin with:
+
+ gqmpeg -skin:../car-preset
+
+or to allow the skin to be the default skin copy this directory
+to 'HOME/.gqmpeg/skins/car-preset' and specify 'car-preset' as the
+skin on the skin tab of the config dialog.
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_exit.png b/noatun/modules/kaiman/skins/car-preset/btn_exit.png
new file mode 100644
index 00000000..5bac9d23
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_exit.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_iconify.png b/noatun/modules/kaiman/skins/car-preset/btn_iconify.png
new file mode 100644
index 00000000..81b2859a
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_iconify.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_list.png b/noatun/modules/kaiman/skins/car-preset/btn_list.png
new file mode 100644
index 00000000..1bea110e
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_list.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_next.png b/noatun/modules/kaiman/skins/car-preset/btn_next.png
new file mode 100644
index 00000000..67a3db2a
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_next.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_p1.png b/noatun/modules/kaiman/skins/car-preset/btn_p1.png
new file mode 100644
index 00000000..4877b86e
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_p1.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_p2.png b/noatun/modules/kaiman/skins/car-preset/btn_p2.png
new file mode 100644
index 00000000..1f6b1f41
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_p2.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_p3.png b/noatun/modules/kaiman/skins/car-preset/btn_p3.png
new file mode 100644
index 00000000..d3ec7ab5
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_p3.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_p4.png b/noatun/modules/kaiman/skins/car-preset/btn_p4.png
new file mode 100644
index 00000000..16b57b7c
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_p4.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_p5.png b/noatun/modules/kaiman/skins/car-preset/btn_p5.png
new file mode 100644
index 00000000..18d65172
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_p5.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_p6.png b/noatun/modules/kaiman/skins/car-preset/btn_p6.png
new file mode 100644
index 00000000..2b0eba96
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_p6.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_play.png b/noatun/modules/kaiman/skins/car-preset/btn_play.png
new file mode 100644
index 00000000..814cbbf9
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_play.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_prev.png b/noatun/modules/kaiman/skins/car-preset/btn_prev.png
new file mode 100644
index 00000000..ffdc59a5
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_prev.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_sml.png b/noatun/modules/kaiman/skins/car-preset/btn_sml.png
new file mode 100644
index 00000000..a2acff28
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_sml.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_stop.png b/noatun/modules/kaiman/skins/car-preset/btn_stop.png
new file mode 100644
index 00000000..faca588f
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_stop.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_voldn.png b/noatun/modules/kaiman/skins/car-preset/btn_voldn.png
new file mode 100644
index 00000000..15e40697
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_voldn.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/btn_volup.png b/noatun/modules/kaiman/skins/car-preset/btn_volup.png
new file mode 100644
index 00000000..9e6c8964
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/btn_volup.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/digbig.png b/noatun/modules/kaiman/skins/car-preset/digbig.png
new file mode 100644
index 00000000..44ea6a9d
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/digbig.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/digmed.png b/noatun/modules/kaiman/skins/car-preset/digmed.png
new file mode 100644
index 00000000..55a43732
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/digmed.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/letters.png b/noatun/modules/kaiman/skins/car-preset/letters.png
new file mode 100644
index 00000000..7f59af69
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/letters.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/main.png b/noatun/modules/kaiman/skins/car-preset/main.png
new file mode 100644
index 00000000..2601e03b
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/main.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/monoster.png b/noatun/modules/kaiman/skins/car-preset/monoster.png
new file mode 100644
index 00000000..fe8129b7
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/monoster.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/posbar.png b/noatun/modules/kaiman/skins/car-preset/posbar.png
new file mode 100644
index 00000000..3d6eb8e8
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/posbar.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/random.png b/noatun/modules/kaiman/skins/car-preset/random.png
new file mode 100644
index 00000000..30b99726
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/random.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/repeat.png b/noatun/modules/kaiman/skins/car-preset/repeat.png
new file mode 100644
index 00000000..022648fd
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/repeat.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/skindata b/noatun/modules/kaiman/skins/car-preset/skindata
new file mode 100644
index 00000000..7a9651e0
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/skindata
@@ -0,0 +1,71 @@
+#GQmpeg skin data file
+
+#Title: Car faceplate with presets
+#Version: 1
+#Released: October 25, 1998
+#Author: John Ellis <[email protected]>
+#URL:
+#Comments: Skin similar to an automotive stereo, complete
+# with presets.
+
+#run 'gqmpeg -skinhelp' for help with coordinates.
+#simply comment out items you do not want to display
+#only Background is required.
+Background: main.png
+
+#Title: filename length x y
+Title: letters.png 16 60 18
+
+#Play/Pause/Stop/Shuffle/Repeat_Button: filename prelight status_light x y
+Play_Button: btn_play.png FALSE FALSE 25 32
+Stop_Button: btn_stop.png FALSE FALSE 4 32
+Shuffle_Button: btn_sml.png FALSE FALSE 265 41
+Repeat_Button: btn_sml.png FALSE FALSE 283 41
+
+#Next/Prev/FF/RW/Playlist/Config/
+# Iconify/Mixer/Exit/Alt_Skin_Button: prelight x y
+Next_Button: btn_next.png FALSE 7 18
+Prev_Button: btn_prev.png FALSE 7 51
+Playlist_Button: btn_list.png FALSE 11 66
+Config_Button: btn_sml.png FALSE 283 23
+Iconify_Button: btn_iconify.png FALSE 263 4
+Exit_Button: btn_exit.png FALSE 280 4
+
+#Stereo/Shuffle/Repeat/Mpegver/Mpeglayer/Mpegmode/Status_Item: filename x y
+Stereo_Item: monoster.png 161 49
+Shuffle_Item: random.png 161 38
+Repeat_Item: repeat.png 205 38
+Status_Item: status.png 57 39
+
+#you can define one or both of these first:
+Digit_Large_Default: digbig.png
+Digit_Small_Default: digmed.png
+#then use Large or Small as the filename in *_Number below (convenience feature)
+
+#Minute/Second/Song/Total/In_Rate/In_Hz/Out_Bits/Out_Hz/Frame/CPU_Number: filename x y
+Minute_Number: Large 65 38
+Second_Number: Large 97 38
+Song_Number: Small 129 44
+CPU_Number: Small 236 44
+
+#Volume/Balance_Item: filename sections x y
+# (these 2 items must be before their respective Volume/Balance_Sliders)
+Volume_Item: volume.png 17 181 48
+
+#Volume_Up/Volume_Down/Balance_Left/Balance_Right_Button: filename prelight x y
+Volume_Up_Button: btn_volup.png FALSE 261 60
+Volume_Down_Button: btn_voldn.png FALSE 279 60
+
+#Position/Volume/Balance_Slider: filename prelight length x y
+Position_Slider: posbar.png FALSE 195 58 5
+
+#Preset_1_ ... Preset_10_Button: filename prelight x y
+Preset_1_Button: btn_p1.png FALSE 58 66
+Preset_2_Button: btn_p2.png FALSE 91 66
+Preset_3_Button: btn_p3.png FALSE 124 66
+Preset_4_Button: btn_p4.png FALSE 157 66
+Preset_5_Button: btn_p5.png FALSE 190 66
+Preset_6_Button: btn_p6.png FALSE 223 66
+
+# end
+
diff --git a/noatun/modules/kaiman/skins/car-preset/status.png b/noatun/modules/kaiman/skins/car-preset/status.png
new file mode 100644
index 00000000..05ceed86
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/status.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/car-preset/volume.png b/noatun/modules/kaiman/skins/car-preset/volume.png
new file mode 100644
index 00000000..f690e79d
--- /dev/null
+++ b/noatun/modules/kaiman/skins/car-preset/volume.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/Makefile.am b/noatun/modules/kaiman/skins/circle/Makefile.am
new file mode 100644
index 00000000..6c8ae5f2
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/Makefile.am
@@ -0,0 +1,13 @@
+skin_DATA = btn_exit.png btn_repeat.png btn_sm_stop.png \
+ btn_iconify.png btn_shuffle.png btn_stop.png \
+back.png btn_list.png btn_sm_exit.png dig.png \
+back_mask.png btn_mode.png btn_sm_iconify.png digsml.png \
+back_sm.png btn_next.png btn_sm_mode.png letters.png \
+back_sm_mask.png btn_play.png btn_sm_next.png skindata \
+bar_pos.png btn_pref.png btn_sm_play.png \
+bar_vol.png btn_prev.png btn_sm_prev.png status.png
+
+
+skindir = $(kde_datadir)/noatun/skins/kaiman/circle
+
+EXTRA_DIST = $(skin_DATA)
diff --git a/noatun/modules/kaiman/skins/circle/README b/noatun/modules/kaiman/skins/circle/README
new file mode 100644
index 00000000..d80082af
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/README
@@ -0,0 +1,22 @@
+GQmpeg skin directory: circle
+Author: Johne Ellis <[email protected]>
+Released: November 25, 1998
+Version: 1.0
+URL: http://www.geocities.com/SiliconValley/Haven/5235
+Comments: Skin with a doughnut shape to test shaped windows.
+ (skins with a shape mask)
+
+Note: For transparency to work, GQmpeg 0.4.2 is required.
+ Previous versions will work, but will be _ugly_.
+
+To use this skin with GQmpeg, use the command line:
+
+ gqmpeg -skin:circle
+
+Or when editing skin data, point GQmpeg to this skin with:
+
+ gqmpeg -skin:../circle
+
+or to allow the skin to be the default skin copy this directory
+to 'HOME/.gqmpeg/skins/circle' and specify 'circle' as the
+skin on the skin tab of the config dialog.
diff --git a/noatun/modules/kaiman/skins/circle/back.png b/noatun/modules/kaiman/skins/circle/back.png
new file mode 100644
index 00000000..83758a14
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/back.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/back_mask.png b/noatun/modules/kaiman/skins/circle/back_mask.png
new file mode 100644
index 00000000..de54ddef
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/back_mask.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/back_sm.png b/noatun/modules/kaiman/skins/circle/back_sm.png
new file mode 100644
index 00000000..3263c2db
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/back_sm.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/back_sm_mask.png b/noatun/modules/kaiman/skins/circle/back_sm_mask.png
new file mode 100644
index 00000000..315d88bf
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/back_sm_mask.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/bar_pos.png b/noatun/modules/kaiman/skins/circle/bar_pos.png
new file mode 100644
index 00000000..e6ac85a3
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/bar_pos.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/bar_vol.png b/noatun/modules/kaiman/skins/circle/bar_vol.png
new file mode 100644
index 00000000..88f88651
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/bar_vol.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_exit.png b/noatun/modules/kaiman/skins/circle/btn_exit.png
new file mode 100644
index 00000000..cd36d2fd
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_exit.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_iconify.png b/noatun/modules/kaiman/skins/circle/btn_iconify.png
new file mode 100644
index 00000000..20647819
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_iconify.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_list.png b/noatun/modules/kaiman/skins/circle/btn_list.png
new file mode 100644
index 00000000..f51e322b
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_list.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_mode.png b/noatun/modules/kaiman/skins/circle/btn_mode.png
new file mode 100644
index 00000000..4c6db0e1
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_mode.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_next.png b/noatun/modules/kaiman/skins/circle/btn_next.png
new file mode 100644
index 00000000..4ae8ee71
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_next.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_play.png b/noatun/modules/kaiman/skins/circle/btn_play.png
new file mode 100644
index 00000000..f21d287e
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_play.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_pref.png b/noatun/modules/kaiman/skins/circle/btn_pref.png
new file mode 100644
index 00000000..9337e704
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_pref.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_prev.png b/noatun/modules/kaiman/skins/circle/btn_prev.png
new file mode 100644
index 00000000..c65a9298
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_prev.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_repeat.png b/noatun/modules/kaiman/skins/circle/btn_repeat.png
new file mode 100644
index 00000000..48b12a90
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_repeat.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_shuffle.png b/noatun/modules/kaiman/skins/circle/btn_shuffle.png
new file mode 100644
index 00000000..75ad39f9
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_shuffle.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_sm_exit.png b/noatun/modules/kaiman/skins/circle/btn_sm_exit.png
new file mode 100644
index 00000000..f14752f8
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_sm_exit.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_sm_iconify.png b/noatun/modules/kaiman/skins/circle/btn_sm_iconify.png
new file mode 100644
index 00000000..69b9332c
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_sm_iconify.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_sm_mode.png b/noatun/modules/kaiman/skins/circle/btn_sm_mode.png
new file mode 100644
index 00000000..79b4c5a0
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_sm_mode.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_sm_next.png b/noatun/modules/kaiman/skins/circle/btn_sm_next.png
new file mode 100644
index 00000000..66c01ddb
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_sm_next.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_sm_play.png b/noatun/modules/kaiman/skins/circle/btn_sm_play.png
new file mode 100644
index 00000000..191551eb
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_sm_play.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_sm_prev.png b/noatun/modules/kaiman/skins/circle/btn_sm_prev.png
new file mode 100644
index 00000000..d70dbb53
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_sm_prev.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_sm_stop.png b/noatun/modules/kaiman/skins/circle/btn_sm_stop.png
new file mode 100644
index 00000000..0d0841d7
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_sm_stop.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/btn_stop.png b/noatun/modules/kaiman/skins/circle/btn_stop.png
new file mode 100644
index 00000000..2563dbc0
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/btn_stop.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/dig.png b/noatun/modules/kaiman/skins/circle/dig.png
new file mode 100644
index 00000000..c417de15
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/dig.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/digsml.png b/noatun/modules/kaiman/skins/circle/digsml.png
new file mode 100644
index 00000000..29f2ed43
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/digsml.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/letters.png b/noatun/modules/kaiman/skins/circle/letters.png
new file mode 100644
index 00000000..b4322d62
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/letters.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/circle/skindata b/noatun/modules/kaiman/skins/circle/skindata
new file mode 100644
index 00000000..25268d22
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/skindata
@@ -0,0 +1,58 @@
+#GQmpeg skin data file
+#tested on version 0.4.2
+
+#Title: circle
+#Version: 1
+#Released: November 25, 1998
+#Author: John Ellis <[email protected]>
+#URL: http://www.geocities.com/SiliconValley/Haven/5235/
+#Comments: Skin with a doughnut shape to test shaped windows.
+# (skins with a shape mask)
+
+#run 'gqmpeg -skinhelp' for help with coordinates.
+#simply comment out items you do not want to display
+#only Background is required.
+Background: back.png
+
+#Mask is an image with transparency used to define a shaped window
+Mask: back_mask.png
+
+#Title: filename length x y
+Title: letters.png 23 32 86
+
+#Play/Pause/Stop/Shuffle/Repeat_Button: filename prelight status_light x y
+Play_Button: btn_play.png TRUE TRUE 125 160
+Stop_Button: btn_stop.png TRUE TRUE 44 160
+Shuffle_Button: btn_shuffle.png TRUE TRUE 151 29
+Repeat_Button: btn_repeat.png TRUE TRUE 164 49
+
+#Next/Prev/FF/RW/Playlist/Config/
+# Iconify/Mixer/Exit/Alt_Skin_Button: prelight x y
+Next_Button: btn_next.png TRUE 125 10
+Prev_Button: btn_prev.png TRUE 44 10
+Playlist_Button: btn_list.png TRUE 158 130
+Config_Button: btn_pref.png TRUE 13 130
+Iconify_Button: btn_iconify.png TRUE 3 69
+Exit_Button: btn_exit.png TRUE 13 40
+Alt_Skin_Button: btn_mode.png TRUE 3 103
+
+#Stereo/Shuffle/Repeat/Mpegver/Mpeglayer/Mpegmode/Status_Item: filename x y
+#Stereo_Item: stereo.png 280 26
+Status_Item: status.png 82 20
+
+#you can define one or both of these first:
+Digit_Large_Default: dig.png
+#then use Large or Small as the filename in *_Number below (convenience feature)
+
+#Minute/Second/Song/Total/In_Rate/In_Hz/Out_Bits/Out_Hz/Frame/CPU_Number: filename x y
+Minute_Number: Large 79 176
+Second_Number: Large 102 176
+Song_Number: Large 91 7
+CPU_Number: digsml.png 78 8
+
+#Position/Volume/Balance_Slider: filename prelight verticle reversed length x y
+Position_Slider: bar_pos.png TRUE FALSE FALSE 142 30 103
+Volume_Slider: bar_vol.png TRUE TRUE TRUE 46 175 77
+
+# end
+
diff --git a/noatun/modules/kaiman/skins/circle/skindata_alt b/noatun/modules/kaiman/skins/circle/skindata_alt
new file mode 100644
index 00000000..fb3e97f5
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/skindata_alt
@@ -0,0 +1,44 @@
+#GQmpeg skin data file
+#tested on version 0.4.2
+
+#Title: circle
+#Version: 1
+#Released: November 25, 1998
+#Author: John Ellis <[email protected]>
+#URL: http://www.geocities.com/SiliconValley/Haven/5235/
+#Comments: Skin with a doughnut shape to test shaped windows.
+# (skins with a shape mask)
+
+#run 'gqmpeg -skinhelp' for help with coordinates.
+#simply comment out items you do not want to display
+#only Background is required.
+Background: back_sm.png
+
+#Mask is an image with transparency used to define a shaped window
+Mask: back_sm_mask.png
+
+#Title: filename length x y
+Title: letters.png 21 8 4
+
+#Play/Pause/Stop/Shuffle/Repeat_Button: filename prelight status_light x y
+Play_Button: btn_sm_play.png TRUE TRUE 21 21
+Stop_Button: btn_sm_stop.png TRUE TRUE 4 21
+
+#Next/Prev/FF/RW/Playlist/Config/
+# Iconify/Mixer/Exit/Alt_Skin_Button: prelight x y
+Next_Button: btn_sm_next.png TRUE 87 21
+Prev_Button: btn_sm_prev.png TRUE 70 21
+Iconify_Button: btn_sm_iconify.png TRUE 120 29
+Exit_Button: btn_sm_exit.png TRUE 120 21
+Alt_Skin_Button: btn_sm_mode.png TRUE 104 21
+
+#you can define one or both of these first:
+Digit_Small_Default: digsml.png
+#then use Large or Small as the filename in *_Number below (convenience feature)
+
+#Minute/Second/Song/Total/In_Rate/In_Hz/Out_Bits/Out_Hz/Frame/CPU_Number: filename x y
+Minute_Number: Small 41 24
+Second_Number: Small 55 24
+
+# end
+
diff --git a/noatun/modules/kaiman/skins/circle/status.png b/noatun/modules/kaiman/skins/circle/status.png
new file mode 100644
index 00000000..b29e075c
--- /dev/null
+++ b/noatun/modules/kaiman/skins/circle/status.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/Makefile.am b/noatun/modules/kaiman/skins/k9/Makefile.am
new file mode 100644
index 00000000..bac3bd84
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/Makefile.am
@@ -0,0 +1,11 @@
+skin_DATA = README skindata conf.jpg conf.png eject.jpg icon.jpg icon.png \
+ kill.jpg kill.png knine-nfont.jpg knine-nfont.png knine-nfont2.jpg \
+ knine-nfont2.png knine-normal2.jpg knine-normal2.png knine-vfont.jpg \
+ knine-vfont.png long2.jpg mask.png newtext.jpg newtext.png next.jpg \
+ pause.jpg play.jpg pos_item.jpg repeat.jpg repeat.png reverse.jpg \
+ shuffle.jpg shuffle.png small-k.jpg small-k.png square.jpg square.png \
+ status.jpg status.png stop.jpg trans-pos.png trans-slide.png
+
+skindir = $(kde_datadir)/noatun/skins/kaiman/k9
+
+EXTRA_DIST = $(skin_DATA)
diff --git a/noatun/modules/kaiman/skins/k9/README b/noatun/modules/kaiman/skins/k9/README
new file mode 100644
index 00000000..8425d0c3
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/README
@@ -0,0 +1,24 @@
+
+This skin is totally (c) 1999 to Morgan aka."Splif" Thomas /
+the Aegis Corporation. Please don't rip, sell, use in public
+without the author's acceptation. Thanks. But you are
+totally free to distribute it all around the universe.
+_____________________________________________________________
+Ported by Me, 'cuz "A skin like this belongs under
+Enlightenment, not windows."
+ DNAspark99
+check out: http://www3.bc.sympatico.ca/desperados
+
+Notes: I reversed the iris, so it "closes" as volume increases.
+If ya wanna try it the default way, edit the "Volume_Item" line in
+the skindata file and change it to "long" instead of "long2"
+
+ & Too bad GQmpeg doesn't have fancy playlist customization like those
+"other" mp3 players......this skin has a "kill" one of those too...
+----------------------------------------------------- --- --
+origional artist:
+Home: http://www.Aegis-Corp.org/Splif/
+
+____________________________________________________________
diff --git a/noatun/modules/kaiman/skins/k9/conf.jpg b/noatun/modules/kaiman/skins/k9/conf.jpg
new file mode 100644
index 00000000..91be54d1
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/conf.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/conf.png b/noatun/modules/kaiman/skins/k9/conf.png
new file mode 100644
index 00000000..56860e00
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/conf.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/eject.jpg b/noatun/modules/kaiman/skins/k9/eject.jpg
new file mode 100644
index 00000000..f1d00f09
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/eject.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/icon.jpg b/noatun/modules/kaiman/skins/k9/icon.jpg
new file mode 100644
index 00000000..3740549b
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/icon.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/icon.png b/noatun/modules/kaiman/skins/k9/icon.png
new file mode 100644
index 00000000..e9057671
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/icon.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/kill.jpg b/noatun/modules/kaiman/skins/k9/kill.jpg
new file mode 100644
index 00000000..8d52aa86
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/kill.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/kill.png b/noatun/modules/kaiman/skins/k9/kill.png
new file mode 100644
index 00000000..8ec851dd
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/kill.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/knine-nfont.jpg b/noatun/modules/kaiman/skins/k9/knine-nfont.jpg
new file mode 100644
index 00000000..5010b881
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/knine-nfont.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/knine-nfont.png b/noatun/modules/kaiman/skins/k9/knine-nfont.png
new file mode 100644
index 00000000..2e166ee1
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/knine-nfont.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/knine-nfont2.jpg b/noatun/modules/kaiman/skins/k9/knine-nfont2.jpg
new file mode 100644
index 00000000..7511230a
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/knine-nfont2.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/knine-nfont2.png b/noatun/modules/kaiman/skins/k9/knine-nfont2.png
new file mode 100644
index 00000000..63e45974
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/knine-nfont2.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/knine-normal2.jpg b/noatun/modules/kaiman/skins/k9/knine-normal2.jpg
new file mode 100644
index 00000000..b744ac82
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/knine-normal2.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/knine-normal2.png b/noatun/modules/kaiman/skins/k9/knine-normal2.png
new file mode 100644
index 00000000..e0d95dc8
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/knine-normal2.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/knine-vfont.jpg b/noatun/modules/kaiman/skins/k9/knine-vfont.jpg
new file mode 100644
index 00000000..a7c27bbf
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/knine-vfont.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/knine-vfont.png b/noatun/modules/kaiman/skins/k9/knine-vfont.png
new file mode 100644
index 00000000..e8692e80
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/knine-vfont.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/long2.jpg b/noatun/modules/kaiman/skins/k9/long2.jpg
new file mode 100644
index 00000000..321c121a
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/long2.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/mask.png b/noatun/modules/kaiman/skins/k9/mask.png
new file mode 100644
index 00000000..9ea57d2b
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/mask.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/newtext.jpg b/noatun/modules/kaiman/skins/k9/newtext.jpg
new file mode 100644
index 00000000..69c437f2
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/newtext.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/newtext.png b/noatun/modules/kaiman/skins/k9/newtext.png
new file mode 100644
index 00000000..e8f25356
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/newtext.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/next.jpg b/noatun/modules/kaiman/skins/k9/next.jpg
new file mode 100644
index 00000000..0a0e5267
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/next.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/pause.jpg b/noatun/modules/kaiman/skins/k9/pause.jpg
new file mode 100644
index 00000000..1144e70d
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/pause.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/play.jpg b/noatun/modules/kaiman/skins/k9/play.jpg
new file mode 100644
index 00000000..dbfe446f
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/play.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/pos_item.jpg b/noatun/modules/kaiman/skins/k9/pos_item.jpg
new file mode 100644
index 00000000..0ba2f333
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/pos_item.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/repeat.jpg b/noatun/modules/kaiman/skins/k9/repeat.jpg
new file mode 100644
index 00000000..774e0804
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/repeat.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/repeat.png b/noatun/modules/kaiman/skins/k9/repeat.png
new file mode 100644
index 00000000..84810e5b
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/repeat.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/reverse.jpg b/noatun/modules/kaiman/skins/k9/reverse.jpg
new file mode 100644
index 00000000..a9b74366
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/reverse.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/shuffle.jpg b/noatun/modules/kaiman/skins/k9/shuffle.jpg
new file mode 100644
index 00000000..1d52ac9b
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/shuffle.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/shuffle.png b/noatun/modules/kaiman/skins/k9/shuffle.png
new file mode 100644
index 00000000..a3e22250
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/shuffle.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/skindata b/noatun/modules/kaiman/skins/k9/skindata
new file mode 100644
index 00000000..1fdc4320
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/skindata
@@ -0,0 +1,73 @@
+#
+# port of K-Nine skin for K-Jofol
+# original art done by Morgan aka. "Splif" Thomas / the Aegis Corp.
+#
+# "'cuz a skin like this belongs under Enlightenment"
+#
+# DNAspark99
+#
+#
+######################################################
+
+Background: knine-normal2.jpg
+Mask: mask.png
+
+Play_Button: play.jpg FALSE FALSE 55 133 89 166
+Stop_Button: stop.jpg FALSE FALSE 28 124 52 145
+Pause_Button: pause.jpg FALSE 91 148 116 173
+Prev_Button: reverse.jpg FALSE 13 108 32 127
+Next_Button: next.jpg FALSE 122 154 141 173
+Repeat_Button: repeat.jpg FALSE TRUE 50 114 63 128
+Shuffle_Button: shuffle.jpg FALSE TRUE 102 134 118 147
+Playlist_Button: eject.jpg FALSE 78 106 104
+Mixer_Button: square.jpg FALSE 294 110 310 126
+Exit_Button: kill.jpg FALSE 282 57 295 69
+Iconify_Button: icon.jpg FALSE 292 85 304 96
+
+Config_Button: conf.jpg FALSE 222 163 242 181
+
+Alt_Skin_Button: small-k.jpg FALSE 287 138 299 153
+
+
+Minute_Number: knine-nfont2.jpg 69 64
+Second_Number: knine-nfont2.jpg 91 64
+
+In_Rate_Number: knine-vfont.jpg 123 59
+In_Hz_Number: knine-vfont.jpg 132 50
+
+Song_Number: knine-vfont.jpg 113 50
+
+Status_Item: status.jpg 113 68
+
+CPU_Number: knine-vfont.jpg 80 50
+
+Digit_Large: knine-vfont.jpg 113 40
+Digit_Small_Default: knine-vfont.jpg
+
+Title: newtext.jpg 26 19 87
+
+#RW_Button: back.jpg FALSE 35 192
+#FF_Button: ff.jpg FALSE 51 214
+
+#Preset_1_Button: list_1.jpg TRUE 70 70
+#Preset_2_Button: list_2.jpg TRUE 77 70
+#Preset_3_Button: list_3.jpg TRUE 84 70
+#Preset_4_Button: list_4.jpg TRUE 91 70
+#Preset_5_Button: list_5.jpg TRUE 98 70
+#Preset_6_Button: list_6.jpg TRUE 70 80
+#Preset_7_Button: list_7.jpg TRUE 77 80
+#Preset_8_Button: list_8.jpg TRUE 84 80
+#Preset_9_Button: list_9.jpg TRUE 91 80
+#Preset_10_Button: list_10.jpg TRUE 98 80
+
+
+Volume_Item: long2.jpg 27 199 76
+Volume_Slider: trans-slide.png FALSE FALSE FALSE 71 205 76 210
+
+Position_Item: pos_item.jpg 32 128 2 30
+Position_Slider: trans-pos.png FALSE FALSE FALSE 140 128 2 70
+
+#Balance_Item: balance.jpg FALSE FALSE FALSE 10 156 95
+#Balance_Slider: knine-pitchbtn.jpg 57 156 95
+
+# END
diff --git a/noatun/modules/kaiman/skins/k9/small-k.jpg b/noatun/modules/kaiman/skins/k9/small-k.jpg
new file mode 100644
index 00000000..219ebb05
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/small-k.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/small-k.png b/noatun/modules/kaiman/skins/k9/small-k.png
new file mode 100644
index 00000000..2a43a4a8
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/small-k.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/square.jpg b/noatun/modules/kaiman/skins/k9/square.jpg
new file mode 100644
index 00000000..c13b1644
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/square.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/square.png b/noatun/modules/kaiman/skins/k9/square.png
new file mode 100644
index 00000000..d77de4ef
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/square.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/status.jpg b/noatun/modules/kaiman/skins/k9/status.jpg
new file mode 100644
index 00000000..db6c61a1
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/status.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/status.png b/noatun/modules/kaiman/skins/k9/status.png
new file mode 100644
index 00000000..682d01b4
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/status.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/stop.jpg b/noatun/modules/kaiman/skins/k9/stop.jpg
new file mode 100644
index 00000000..0ca261e3
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/stop.jpg
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/trans-pos.png b/noatun/modules/kaiman/skins/k9/trans-pos.png
new file mode 100644
index 00000000..0eecf3bb
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/trans-pos.png
Binary files differ
diff --git a/noatun/modules/kaiman/skins/k9/trans-slide.png b/noatun/modules/kaiman/skins/k9/trans-slide.png
new file mode 100644
index 00000000..76aa00d7
--- /dev/null
+++ b/noatun/modules/kaiman/skins/k9/trans-slide.png
Binary files differ
diff --git a/noatun/modules/kaiman/style.cpp b/noatun/modules/kaiman/style.cpp
new file mode 100644
index 00000000..d42ed45f
--- /dev/null
+++ b/noatun/modules/kaiman/style.cpp
@@ -0,0 +1,1504 @@
+/*
+ Copyright (c) 2000 Stefan Schimanski ([email protected])
+ 1999-2000 Christian Esken ([email protected])
+
+ 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, 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.
+*/
+
+
+#include <kapplication.h>
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qpainter.h>
+#include <qdropsite.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kurldrag.h>
+#include <qtimer.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "style.h"
+#include "userinterface.h"
+#include <noatun/app.h>
+#include <noatun/stdaction.h>
+
+const bool KaimanStyleSlider::optionVertical = 1;
+const bool KaimanStyleSlider::optionReversed = 2;
+const bool KaimanStyleText::optionExtended = 1;
+
+KaimanStyleElement::KaimanStyleElement(QWidget *parent, const char *name)
+ : QWidget(parent, name)
+{
+ // Initialize everything to default values
+ filename = "";
+ element = "";
+ upperLeft.setX(0);
+ upperLeft.setY(0);
+ dimension.setWidth(0);
+ dimension.setHeight(0);
+ optionPrelight = optionStatuslight = false;
+ options[0] = options[1] = options[2] = false;
+ _currentPixmap = 0;
+ digits = -1;
+ pixmapLines = 1;
+ pixmapColumns = 1;
+
+ setAcceptDrops(true);
+ pixmaps.setAutoDelete(true);
+
+ setBackgroundMode( NoBackground );
+}
+
+
+KaimanStyleElement::~KaimanStyleElement()
+{
+}
+
+
+void KaimanStyleElement::loadPixmaps(QString &val_s_filename)
+{
+ QPixmap pixmap;
+
+ bool i_b_ret = pixmap.load(val_s_filename);
+ pixmapNum = pixmapLines*pixmapColumns;
+
+ pixmaps.resize(pixmapNum);
+
+ if ( i_b_ret ) {
+ if(pixmapNum) {
+ int firstWidth, firstHeight, width, height, sourcex = 0, sourcey = 0;
+
+ // first bitmap may be with different size
+ if ( dimension.width()!=0 )
+ {
+ firstWidth = dimension.width();
+ if ( pixmapColumns>1 )
+ width = (pixmap.width()-firstWidth) / (pixmapColumns-1);
+ else
+ width = 0;
+ } else
+ firstWidth = width = pixmap.width() / pixmapColumns;
+
+ if ( dimension.height()!=0 )
+ {
+ firstHeight = dimension.height();
+ if ( pixmapLines>1 )
+ height = (pixmap.height()-firstHeight) / (pixmapLines-1);
+ else
+ height = 0;
+ } else
+ firstHeight = height = pixmap.height() / pixmapLines;
+
+ // create single pixmaps
+ int i=0;
+ sourcey = 0;
+ for( int y=0; y<pixmapLines; y++ )
+ {
+ int h = (y==0) ? firstHeight : height;
+ sourcex = 0;
+
+ for( int x=0; x<pixmapColumns; x++ )
+ {
+ int w = (x==0) ? firstWidth : width;
+
+ QPixmap *part = new QPixmap(w,h,pixmap.depth());
+ part->fill(Qt::black);
+ bitBlt(part,0,0,&pixmap,sourcex,sourcey,w,h);
+ pixmaps.insert(i,part);
+
+ if(pixmap.mask())
+ {
+ QBitmap maskpart(w,h);
+ bitBlt(&maskpart,0,0,pixmap.mask(),sourcex,sourcey,w,h);
+ part->setMask(maskpart);
+ }
+
+ i++;
+ sourcex += w;
+ }
+
+ sourcey += h;
+ }
+ }
+ } else {
+ kdDebug() << "Cannot load pixmap " << val_s_filename << endl;
+
+ for ( int i=0; i<pixmapNum; i++ )
+ {
+ QPixmap *pm = new QPixmap(10, 10);
+ pm->fill(Qt::black);
+ pixmaps.insert( i, pm );
+ }
+ }
+
+ if ( dimension.width()==0 ) dimension.setWidth( pixmaps[0]->width() );
+ if ( dimension.height()==0 ) dimension.setHeight( pixmaps[0]->height() );
+ setGeometry( QRect(upperLeft, dimension) );
+}
+
+void KaimanStyleElement::setPixmap( int num )
+{
+ if ( num!=_currentPixmap )
+ {
+ if ( num>pixmapNum-1 ) num = pixmapNum-1;
+ if ( num<0 ) num = 0;
+
+ _currentPixmap = num;
+ repaint( FALSE );
+ }
+}
+
+void KaimanStyleElement::paintEvent ( QPaintEvent */*qpe*/ )
+{
+ QPixmap *pm = pixmaps[_currentPixmap];
+ if ( pm )
+ bitBlt(this, 0, 0, pm );
+ else
+ kdDebug() << "Invalid pixmap" << endl;
+
+/* QPainter p( this );
+ p.setBrush( NoBrush );
+ p.setPen( QColor(255,255,255) );
+ p.drawRect( 0, 0, width(), height() );
+ p.drawText( 2, 16, name() ); */
+}
+
+void KaimanStyleElement::dragEnterEvent( QDragEnterEvent *event )
+{
+ event->accept( KURLDrag::canDecode(event) );
+}
+
+void KaimanStyleElement::dropEvent( QDropEvent *event )
+{
+ ((Kaiman*)(parentWidget()->parentWidget()))->doDropEvent(event);
+}
+
+/***************************************************************************/
+
+
+KaimanStyleButton::KaimanStyleButton(QWidget *parent, const char *name)
+ : KaimanStyleMasked(parent, name)
+{
+ i_b_lit = i_b_prelit = i_b_down = false;
+ i_i_currentState = NormalUp;
+
+ I_pmIndex.resize( StateListEND );
+
+ for (int i=0; i<StateListEND; i++) {
+ // Set pixmap index of all states to 0 (the default pixmap)
+ I_pmIndex.insert( i, new int(0));
+ }
+}
+
+KaimanStyleButton::~KaimanStyleButton()
+{
+}
+
+void KaimanStyleButton::mousePressEvent(QMouseEvent *qme)
+{
+ // We deactivate prelight, because the user presses the button.
+ // So it is now down, but there is no PrelitDown icon (BTW: would
+ // make no real sense anyhow).
+ setPrelight(false);
+ setDown(true);
+ grabMouse();
+
+ KaimanStyleMasked::mousePressEvent( qme );
+}
+
+void KaimanStyleButton::mouseReleaseEvent(QMouseEvent *qme)
+{
+ releaseMouse ();
+
+ if (down())
+ {
+ setDown(false);
+ emit clicked();
+ }
+
+ KaimanStyleMasked::mouseReleaseEvent( qme );
+}
+
+
+/* paint prelight */
+void KaimanStyleButton::enterEvent ( QEvent * e )
+{
+ if ( !down() )
+ setPrelight(true);
+
+ KaimanStyleMasked::enterEvent( e );
+}
+
+/* unpaint prelight */
+void KaimanStyleButton::leaveEvent ( QEvent * e )
+{
+ if (!down())
+ setPrelight(false);
+
+ KaimanStyleMasked::leaveEvent( e );
+}
+
+bool KaimanStyleButton::lit()
+{
+ return i_b_lit;
+}
+
+void KaimanStyleButton::setLit(bool val_b_lit)
+{
+ i_b_lit = val_b_lit;
+ updateButtonState();
+}
+
+bool KaimanStyleButton::prelit()
+{
+ return i_b_prelit;
+}
+
+void KaimanStyleButton::setPrelight(bool val_b_prelit)
+{
+ i_b_prelit = val_b_prelit;
+ updateButtonState();
+}
+
+bool KaimanStyleButton::down()
+{
+ return i_b_down;
+}
+
+void KaimanStyleButton::setDown(bool val_b_down)
+{
+ i_b_down = val_b_down;
+ updateButtonState();
+}
+
+void KaimanStyleButton::updateButtonState() {
+
+ if ( i_b_prelit ) {
+ if ( i_b_lit ) {
+ // Prelit and Lit
+ i_i_currentState = PrelightLitUp;
+ }
+ else {
+ // Prelit and not Lit
+ i_i_currentState = PrelightUp;
+ }
+ }
+
+ else if ( i_b_lit ) {
+ if ( i_b_down ) {
+ // Lit and Down
+ i_i_currentState = LitDown;
+ } else {
+ // Lit and not Down
+ i_i_currentState = LitUp;
+ }
+ }
+ else {
+ if ( i_b_down ) {
+ // Normal and Down
+ i_i_currentState = NormalDown;
+ }
+ else {
+ // Normal and not Down
+ i_i_currentState = NormalUp;
+ }
+ }
+
+ setPixmap( *I_pmIndex[i_i_currentState] );
+ repaint();
+}
+
+
+/***********************************************************************/
+
+KaimanStyleSlider::KaimanStyleSlider(int min, int max, QWidget *parent, const char *name)
+ : KaimanStyleMasked( parent, name )
+{
+ _min = min;
+ _max = max;
+ _down = false;
+ _lit = false;
+
+ setValue( _min );
+}
+
+
+KaimanStyleSlider::~KaimanStyleSlider()
+{
+}
+
+
+void KaimanStyleSlider::setValue( int value )
+{
+ if (value>_max) value=_max;
+ if (value<_min) value=_min;
+ _value = value;
+ repaint();
+}
+
+
+void KaimanStyleSlider::setValue( int value, int min, int max )
+{
+ if ( value!=_value || min!=_min || max!=_max ) {
+ _min = min;
+ _max = max;
+ setValue( value );
+ repaint();
+ }
+}
+
+int KaimanStyleSlider::pos2value( int x, int y )
+{
+ int p;
+ int v;
+ if ( options[optionVertical] ) {
+ p = y;
+ v = p*(_max-_min)/height();
+ } else {
+ p = x;
+ v = p*(_max-_min)/width();
+ }
+
+ if ( options[optionReversed] ) v = (_max-_min) - v;
+ return _min + v;
+}
+
+
+void KaimanStyleSlider::mouseMoveEvent(QMouseEvent *qme)
+{
+ KaimanStyleMasked::mouseMoveEvent( qme );
+
+ if ( _down )
+ {
+ setValue( pos2value(qme->x(), qme->y()) );
+ emit newValue( value() );
+ }
+}
+
+void KaimanStyleSlider::mousePressEvent(QMouseEvent *qme)
+{
+ if ( !_down )
+ {
+ grabMouse();
+ _down = true;
+
+ setValue( pos2value(qme->x(), qme->y()) );
+ emit newValueDrag( value() );
+ emit newValue( value() );
+ }
+
+ KaimanStyleMasked::mousePressEvent( qme );
+}
+
+
+void KaimanStyleSlider::mouseReleaseEvent(QMouseEvent *qme)
+{
+ if ( _down )
+ {
+ _down = false;
+ releaseMouse();
+ repaint();
+
+ setValue( pos2value(qme->x(), qme->y()) );
+ emit newValue( value() );
+ emit newValueDrop( value() );
+ }
+
+ KaimanStyleMasked::mouseReleaseEvent( qme );
+}
+
+
+void KaimanStyleSlider::paintEvent(QPaintEvent */*qpe*/)
+{
+ // draw background
+ bitBlt( this, 0, 0, pixmaps[0] );
+
+ // draw optional handle
+ QPixmap *handle;
+ if ( _down )
+ handle = pixmaps[2];
+ else
+ {
+ if ( _lit && optionPrelight )
+ handle = pixmaps[3];
+ else
+ handle = pixmaps[1];
+ }
+
+ if ( handle && handle->width() )
+ {
+ int x = 0;
+ int y = 0;
+
+ if ( _max-_min ) {
+ int v = _value-_min;
+ if ( options[optionReversed] ) v = (_max-_min) - v;
+
+ if ( options[optionVertical] )
+ y = ( height()-handle->height() ) * v / (_max-_min);
+ else
+ x = ( width()-handle->width() ) * v / (_max-_min);
+ }
+
+ bitBlt( this, x, y, handle );
+ }
+}
+
+void KaimanStyleSlider::enterEvent ( QEvent * e )
+{
+ if ( !_lit && optionPrelight )
+ {
+ _lit = true;
+ repaint();
+ }
+
+ KaimanStyleMasked::enterEvent( e );
+}
+
+void KaimanStyleSlider::leaveEvent ( QEvent * e )
+{
+ if ( _lit )
+ {
+ _lit = false;
+ repaint();
+ }
+
+ KaimanStyleMasked::leaveEvent( e );
+}
+
+
+/***********************************************************************/
+
+
+KaimanStyleBackground::KaimanStyleBackground(QWidget *parent, const char *name)
+ : KaimanStyleMasked( parent, name )
+{
+ i_b_move = false;
+}
+
+KaimanStyleBackground::~KaimanStyleBackground()
+{
+}
+
+void KaimanStyleBackground::mouseReleaseEvent(QMouseEvent *qme)
+{
+ i_b_move = false;
+ KaimanStyleMasked::mouseReleaseEvent( qme );
+}
+
+void KaimanStyleBackground::mouseMoveEvent(QMouseEvent *qme)
+{
+ QPoint diff = qme->globalPos() - i_point_lastPos;
+ if ( abs(diff.x()) > 10 || abs(diff.y()) > 10) {
+ // Moving starts only, when passing a drag border
+ i_b_move = true;
+ }
+
+ if ( i_b_move ) {
+ QWidget *p = parentWidget()->parentWidget();
+ if ( !p ) p = parentWidget();
+
+ p->move( qme->globalPos() - i_point_dragStart );
+ }
+
+ KaimanStyleMasked::mouseMoveEvent( qme );
+}
+
+void KaimanStyleBackground::mousePressEvent(QMouseEvent *qme)
+{
+ // On the background we move the shaped toplevel around
+ if (!i_b_move) {
+ i_point_dragStart = qme->pos();
+ i_point_lastPos = qme->globalPos();
+ }
+
+ KaimanStyleMasked::mousePressEvent( qme );
+}
+
+/***********************************************************************/
+
+KaimanStyleValue::KaimanStyleValue(int min, int max, QWidget *parent, const char *name)
+ : KaimanStyleMasked( parent, name )
+{
+ _min = min;
+ _max = max;
+ _value = _min;
+
+ setPixmap( 0 );
+}
+
+KaimanStyleValue::~KaimanStyleValue()
+{
+}
+
+void KaimanStyleValue::setValue( int value )
+{
+ if (value>_max) value=_max;
+ if (value<_min) value=_min;
+ _value = value;
+
+ int len = _max-_min;
+ if ( len )
+ setPixmap( (_value-_min)*pixmapNum/len );
+ else
+ setPixmap( 0 );
+}
+
+void KaimanStyleValue::setValue( int value, int min, int max )
+{
+ _min = min;
+ _max = max;
+
+ setValue( value );
+}
+
+
+/***********************************************************************/
+
+KaimanStyleNumber::KaimanStyleNumber(QWidget *parent, const char *name)
+ : KaimanStyleElement( parent, name )
+{
+ //kdDebug(66666) << k_funcinfo << "name = '" << name << "'" << endl;
+ _value = 0;
+ if (QCString(name) == "In_Rate_Number")
+ digits = 3;
+ else
+ digits = 2;
+}
+
+KaimanStyleNumber::~KaimanStyleNumber()
+{
+}
+
+
+void KaimanStyleNumber::loadPixmaps(QString &val_s_filename)
+{
+ KaimanStyleElement::loadPixmaps( val_s_filename );
+ resize( digits*pixmaps[0]->width(),pixmaps[0]->height() );
+}
+
+
+void KaimanStyleNumber::setValue( int value )
+{
+ if ( _value!=value )
+ {
+ _value = value;
+ repaint();
+ }
+}
+
+void KaimanStyleNumber::paintEvent(QPaintEvent */*qpe*/)
+{
+ // check for overflow
+ int v = _value;
+ for ( int i=digits; i>0 && v>0; i-- )
+ v /= 10;
+
+ if ( v!=0 )
+ v = 999999999; // overflow
+ else
+ v = _value;
+
+ // draw number
+ int x = width();
+ do {
+ x -= pixmaps[0]->width();
+ bitBlt(this, x, 0, pixmaps[v%10] );
+
+ v /= 10;
+ } while ( v>0 );
+
+ // draw right free space
+ while ( x>0 )
+ {
+ x -= pixmaps[0]->width();
+ bitBlt(this, x, 0, pixmaps[0] );
+ }
+/*
+ QPainter p( this );
+ p.setBrush( NoBrush );
+ p.setPen( QColor(255,255,255) );
+ p.drawRect( 0, 0, width(), height() );
+ p.drawText( 2, 16, name() );*/
+}
+
+/***********************************************************************/
+
+KaimanStyleText::KaimanStyleText(QWidget *parent, const char *name)
+ : KaimanStyleElement( parent, name )
+{
+ _pos = 0;
+ _timer = new QTimer( this );
+ _delay = 500;
+ connect( _timer, SIGNAL(timeout()), this, SLOT(timeout()) );
+}
+
+KaimanStyleText::~KaimanStyleText()
+{
+}
+
+
+void KaimanStyleText::loadPixmaps(QString &val_s_filename)
+{
+ KaimanStyleElement::loadPixmaps( val_s_filename );
+ resize( digits*pixmaps[0]->width(), pixmaps[0]->height() );
+}
+
+
+void KaimanStyleText::setValue( QString value )
+{
+ if ( value!=_value ) {
+ _pos = 0;
+ _direction = 1;
+ _value = value;
+ repaint();
+ }
+}
+
+
+void KaimanStyleText::startAnimation( int delay )
+{
+ _pos = 0;
+ _direction = 1;
+ _delay = delay;
+ _timer->start( _delay, TRUE );
+}
+
+
+void KaimanStyleText::stopAnimation()
+{
+ _pos = 0;
+ _timer->stop();
+}
+
+
+void KaimanStyleText::timeout()
+{
+ // reflect
+ if ( _pos+_direction<0 || (int)_value.length()-(_pos+_direction)<digits ) {
+ _direction = -_direction;
+ _timer->start( _delay*5, TRUE );
+ } else {
+ // check new position
+ if ( _pos+_direction>=0 && (int)_value.length()-(_pos+_direction)>=digits ) {
+ _pos += _direction;
+ repaint();
+ }
+
+ _timer->start( _delay, TRUE );
+ }
+
+
+}
+
+
+void KaimanStyleText::paintEvent(QPaintEvent */*qpe*/)
+{
+ // draw number
+ int p;
+ for (p=0; p<digits && p<(int)_value.length()-_pos; p++ )
+ {
+ int pmNum = _value[p+_pos].latin1() - ' ' ;
+ if ( pmNum>=96 ) pmNum = '?' - ' ';
+ if ( pmNum<0 ) pmNum = '?' - ' ';
+
+ QPixmap *pm = pixmaps[pmNum];
+ if ( pm ) bitBlt(this, p*pixmaps[0]->width(), 0, pm );
+ }
+
+ QPixmap *pm = pixmaps[0];
+ for ( ; p<digits; p++ )
+ bitBlt(this, p*pixmaps[0]->width(), 0, pm );
+
+/* QPainter pnt( this );
+ pnt.setBrush( NoBrush );
+ pnt.setPen( QColor(255,255,255) );
+ pnt.drawRect( 0, 0, width(), height() );
+ pnt.drawText( 2, 16, name() );*/
+}
+
+/***********************************************************************/
+
+KaimanStyleAnimation::KaimanStyleAnimation(int delay, QWidget *parent, const char *name)
+ : KaimanStyleMasked( parent, name )
+{
+ _delay = delay;
+ _frame = 0;
+ _timer = new QTimer( this );
+ connect( _timer, SIGNAL(timeout()), this, SLOT(timeout()) );
+}
+
+KaimanStyleAnimation::~KaimanStyleAnimation()
+{
+}
+
+void KaimanStyleAnimation::start()
+{
+ _timer->start( _delay, FALSE );
+}
+
+void KaimanStyleAnimation::pause()
+{
+ _timer->stop();
+}
+
+void KaimanStyleAnimation::stop()
+{
+ _timer->stop();
+ _frame = 0;
+ setPixmap( _frame );
+}
+
+void KaimanStyleAnimation::timeout()
+{
+ _frame++;
+ if ( _frame>=pixmapNum ) _frame = 1;
+ setPixmap( _frame );
+}
+
+/***********************************************************************/
+
+KaimanStyleState::KaimanStyleState(QWidget *parent, const char *name)
+ : KaimanStyleMasked( parent, name )
+{
+ _value = 0;
+}
+
+KaimanStyleState::~KaimanStyleState()
+{
+}
+
+void KaimanStyleState::setValue( int value )
+{
+ _value = value;
+ setPixmap( _value );
+}
+
+void KaimanStyleState::mousePressEvent(QMouseEvent *qme)
+{
+ emit clicked();
+ KaimanStyleMasked::mouseReleaseEvent( qme );
+}
+
+/***********************************************************************/
+
+
+KaimanStyle::KaimanStyle( QWidget *parent, const char *name )
+ : QWidget( parent, name )
+{
+ i_qw_parent = parent;
+ i_eventSemaphore = false;
+}
+
+
+KaimanStyle::~KaimanStyle()
+{
+}
+
+
+int KaimanStyle::parseStyleFile(QString &l_s_tmpName)
+{
+ int l_i_ret = false;
+
+ QStringList l_s_tokens;
+
+ QFile l_fd(l_s_tmpName);
+ if ( l_fd.open(IO_ReadOnly) ) {
+ // file opened successfully
+ QTextStream l_ts_line( &l_fd );
+ QString l_s_textLine, l_s_token;
+ while ( !l_ts_line.eof() ) {
+ // Clear list of tokens (we are going to fill them now)
+ l_s_tokens.clear();
+
+ // Read a line
+ l_s_textLine = l_ts_line.readLine();
+ l_s_textLine = l_s_textLine.simplifyWhiteSpace();
+
+ if ( l_s_textLine.left(1) != "#" ) {
+ // OK, this is not a comment line
+ if ( l_s_textLine.isNull())
+ l_s_textLine = "";
+ while ( !l_s_textLine.isEmpty() ) {
+ l_s_token = getToken(l_s_textLine, ' ');
+ if ( ! l_s_token.isEmpty() ) {
+ // OK. There is a useful token. It is not NULL
+ if ( l_s_token.right(1) == ":" )
+ l_s_tokens.append(l_s_token.left(l_s_token.length() -1 ));
+ else
+ l_s_tokens.append(l_s_token);
+ } // -<- if it is a not-empty token
+ } // -<- while there are tokens available
+
+ interpretTokens(l_s_tokens);
+
+ } // -<- if is not comment line
+ } // -<- While not EOF on file
+
+ l_i_ret = 0;
+ } // -<- if file could be opened
+
+ else {
+ l_i_ret = KaimanStyle::FileNotFound;
+ }
+ return l_i_ret;
+}
+
+
+
+/*
+ This function gets a list of tokens and inserts a new
+ KaimanStyleElement in I_styleElem. */
+void KaimanStyle::interpretTokens(QStringList& ref_s_tokens)
+{
+ if ( ref_s_tokens.count() < 1 ) {
+ // A list with less than 1 item is useless to us
+ return;
+ }
+
+ QString l_s_tokenTypes;
+ const QString &l_s_elem = ref_s_tokens.first();
+ bool l_vertPixmaps = false;
+ int l_i_pmIndex[KaimanStyleButton::StateListEND];
+ for (int i=0; i<KaimanStyleButton::StateListEND; i++) l_i_pmIndex[i]=0;
+
+ enum { UnknownElement, BackgroundElement, MaskElement, ButtonElement, SliderElement,
+ ValueElement, AnimationElement, StateElement, DigitElement, NumberElement,
+ TextElement } l_elementType = UnknownElement;
+
+ // Now determine the meaning of the following tokens
+ // l_s_tokenTypes stores the meaning (e.g. x-Position, filename, ...)
+ if ( l_s_elem == "Background" ) {
+ l_s_tokenTypes = "f";
+ l_elementType = BackgroundElement;
+ }
+ // ---
+ else if ( l_s_elem == "Mask" ) {
+ l_s_tokenTypes = "f";
+ l_elementType = MaskElement;
+ } else if ( l_s_elem=="Digit_Small" || l_s_elem=="Digit_Small_Default" ) {
+ i_smallFont = ref_s_tokens[1];
+ return;
+ } else if ( l_s_elem=="Digit_Large" || l_s_elem=="Digit_Large_Default" ) {
+ i_largeFont = ref_s_tokens[1];
+ return;
+ }
+ // ---
+ else if ( l_s_elem == "Title" ||
+ l_s_elem == "Album" ||
+ l_s_elem == "Artist" ||
+ l_s_elem == "Genre" ) {
+ // You can have an OPTIONAL argument, so lets see if it is there.
+ if (ref_s_tokens.count() == 6 )
+ l_s_tokenTypes = "fd1xy";
+ else
+ l_s_tokenTypes = "fdxy";
+ l_elementType = TextElement;
+ }
+ // ---
+ else if ( l_s_elem == "Play_Button" ||
+ l_s_elem == "Pause_Button" ||
+ l_s_elem == "Stop_Button" ||
+ l_s_elem == "Shuffle_Button" ||
+ l_s_elem == "Repeat_Button" ) {
+ l_s_tokenTypes = "fPSxy";
+ l_i_pmIndex[KaimanStyleButton::NormalUp] = 0;
+ l_i_pmIndex[KaimanStyleButton::NormalDown] = 1;
+ l_i_pmIndex[KaimanStyleButton::LitUp] = 2;
+ l_i_pmIndex[KaimanStyleButton::LitDown] = 3;
+ l_i_pmIndex[KaimanStyleButton::PrelightUp] = 4;
+ l_i_pmIndex[KaimanStyleButton::PrelightLitUp] = 5;
+ l_elementType = ButtonElement;
+ }
+ // ---
+ else if ( l_s_elem == "Next_Button" ||
+ l_s_elem == "Prev_Button" ||
+ l_s_elem == "FF" ||
+ l_s_elem == "RW" ||
+ l_s_elem == "Playlist_Button" ||
+ l_s_elem == "Config_Button" ||
+ l_s_elem == "Iconify_Button" ||
+ l_s_elem == "Mixer_Button" ||
+ l_s_elem == "Exit_Button" ||
+ l_s_elem == "Alt_Skin_Button" ||
+ l_s_elem == "Volume_Up_Button" ||
+ l_s_elem == "Volume_Down_Button" ||
+ l_s_elem == "Balance_Left_Button" ||
+ l_s_elem == "Balance_Right_Button" ) {
+ l_i_pmIndex[KaimanStyleButton::NormalUp] = 0;
+ l_i_pmIndex[KaimanStyleButton::NormalDown] = 1;
+ l_i_pmIndex[KaimanStyleButton::PrelightUp] = 2;
+ l_s_tokenTypes = "fPxy";
+ l_elementType = ButtonElement;
+ }
+ // ---
+ else if ( l_s_elem == "Stereo_Item" ||
+ l_s_elem == "Shuffle_Item" ||
+ l_s_elem == "Repeat_Item" ||
+ l_s_elem == "Mpegversion_Item" ||
+ l_s_elem == "Mpeglayer_Item" ||
+ l_s_elem == "Mpegmode_Item" ||
+ l_s_elem == "Status_Item" ) {
+ l_s_tokenTypes = "Vfxy";
+ l_elementType = StateElement;
+ }
+ // ---
+ else if ( l_s_elem == "Hour_Number" ||
+ l_s_elem == "Minute_Number" ||
+ l_s_elem == "Second_Number" ||
+ l_s_elem == "Song_Number" ||
+ l_s_elem == "Total_Number" ||
+ l_s_elem == "In_Rate_Number" ||
+ l_s_elem == "In_Hz_Number" ||
+ l_s_elem == "Out_Bits" ||
+ l_s_elem == "Out_Hz" ||
+ l_s_elem == "Song_Minute" ||
+ l_s_elem == "Song_Second" ||
+ l_s_elem == "Frame" ||
+ l_s_elem == "Frame_Total" ||
+ l_s_elem == "CPU_Number" ||
+ l_s_elem == "Hour_Total" ||
+ l_s_elem == "Minute_Total" ||
+ l_s_elem == "Second_Total_Number" ) {
+ // You can have an OPTIONAL argument, so lets see if it is there.
+ if (ref_s_tokens.count() == 6 )
+ l_s_tokenTypes = "fd1xy";
+ else if (ref_s_tokens.count() == 5 )
+ l_s_tokenTypes = "fdxy";
+ else
+ l_s_tokenTypes = "fxy";
+
+ l_elementType = NumberElement;
+ }
+ // ---
+ else if ( l_s_elem == "Position_Item" ||
+ l_s_elem == "Volume_Item" ||
+ l_s_elem == "Balance_Item" ) {
+ l_s_tokenTypes = "Vflxy";
+ l_elementType = ValueElement;
+ }
+ // ---
+ else if ( l_s_elem == "Load_Item" ) {
+ l_s_tokenTypes = "Vflxy";
+ l_elementType = AnimationElement;
+ }
+ // ---
+ else if ( l_s_elem == "Position_Slider" ||
+ l_s_elem == "Volume_Slider" ||
+ l_s_elem == "Balance_Slider" ) {
+
+ if ( ref_s_tokens.count()==10 )
+ l_s_tokenTypes = "VfP12wxyh";
+ else
+ l_s_tokenTypes = "VfP12sxy";
+ l_elementType = SliderElement;
+ }
+ else {
+ kdDebug() << l_s_elem << " not handled yet." << endl;
+ l_s_tokenTypes = "f";
+ }
+
+ /* The above lines decode the meanings of the tokens. The rules for
+ this are the SKIN-SPECS. So the decoder implements a syntactic
+ analyser (parser).
+
+ I now do know the type of each tokens, whether it represents a
+ filename, the prelight parameter, the x position or what else. This
+ information resides in l_s_tokenTypes, and will help in creating
+ the kaiman style elements.
+
+ I will now do two things:
+ 1) Create a new KaimanStyle*, that is inserted into I_styleElem.
+ 2) Fill the KaimanStyleElement structure, by interpreting the tokens.
+ */
+ QStringList::Iterator li_s_tokens = ref_s_tokens.begin();
+ ++ li_s_tokens; // Skip the name of the element
+
+ // 1) Create a new KaimanStyleElement, that is inserted into I_styleElem.
+ KaimanStyleElement *l_kse_elem = 0;
+ KaimanStyleButton *but = 0;
+
+ switch ( l_elementType )
+ {
+ case BackgroundElement:
+ l_kse_elem = new KaimanStyleBackground(this, l_s_elem.latin1());
+ l_kse_elem->show();
+ break;
+
+ case MaskElement:
+ l_kse_elem = new KaimanStyleElement(this, l_s_elem.latin1());
+ l_kse_elem->hide();
+ break;
+
+ case ButtonElement:
+ l_kse_elem = new KaimanStyleButton(this, l_s_elem.latin1());
+ but = static_cast<KaimanStyleButton*>(l_kse_elem);
+ l_kse_elem->show();
+ break;
+
+ case SliderElement:
+ l_kse_elem = new KaimanStyleSlider(0, 100, this, l_s_elem.latin1());
+ i_sliders.append(l_kse_elem);
+ l_kse_elem->show();
+ break;
+
+ case ValueElement:
+ l_kse_elem = new KaimanStyleValue(0, 100, this, l_s_elem.latin1());
+ break;
+
+ case AnimationElement:
+ l_kse_elem = new KaimanStyleAnimation(30, this, l_s_elem.latin1());
+ break;
+
+ case StateElement:
+ l_kse_elem = new KaimanStyleState(this, l_s_elem.latin1());
+ break;
+
+ case NumberElement:
+ l_kse_elem = new KaimanStyleNumber(this, l_s_elem.latin1());
+ break;
+
+ case TextElement:
+ l_kse_elem = new KaimanStyleText(this, l_s_elem.latin1());
+ break;
+
+ default:
+ break;
+ }
+
+ if ( !l_kse_elem )
+ {
+ kdDebug() << "Ignoring style element " << l_s_elem << endl;
+ return;
+ }
+
+ // insert element into element list
+ uint l_i_size = I_styleElem.size();
+ I_styleElem.resize(l_i_size + 1);
+ I_styleElem.insert(l_i_size, l_kse_elem);
+ l_kse_elem->installEventFilter( this );
+
+ // initialize element parameters
+ l_kse_elem->element = l_s_elem;
+
+ if ( l_s_tokenTypes.left(1) == "V" ) {
+ // Vertical flag
+ l_vertPixmaps = true;
+ l_s_tokenTypes = l_s_tokenTypes.mid(1);
+ }
+
+ // initialize button parameters
+ if ( but )
+ {
+ for (int i=0; i<KaimanStyleButton::StateListEND; i++)
+ but->I_pmIndex.insert(i, new int(l_i_pmIndex[i]) );
+ }
+
+ // 2) Fill the KaimanStyleElement structure, by interpreting the tokens.
+ while ( l_s_tokenTypes.length() != 0 ) {
+ /* The skindata format allows omitting arguments if the parser
+ can reconstruct without problems what you mean. This is taken
+ into account when writing the l_s_tokenTypes sting.
+
+ Unfortunately, several skins do ship with a broken skindata file.
+ Most common problem is that width and height is also given.
+
+ Even worse examples leave out specified parametes and add others.
+ For instance, the pause line is specified as "fPSxy". But in k9
+
+
+ the line looks like
+
+ Pause_Button: pause.jpg FALSE 91 148 116 173
+
+ So the actual parameters are fPxywh. The parser has to be pretty
+ smart now. It should "see" that S (status light) is not present,
+ since that should be either TRUE or FALSE, and distribute the
+ others accordingly. */
+
+ bool skipOne;
+
+ do {
+ skipOne = false;
+
+ // Take the first item from the l_s_tokenTypes;
+ char l_c_type = (l_s_tokenTypes[0]).latin1();
+ l_s_tokenTypes = l_s_tokenTypes.mid(1);
+ QString l_s_token = *li_s_tokens;
+ switch(l_c_type) {
+ case 'f':
+ // filename
+ l_kse_elem->filename = l_s_token;
+ break;
+ case 'P':
+ // Prelight
+ if ( l_s_token.upper() == "TRUE" )
+ l_kse_elem->optionPrelight = true;
+ else
+ {
+ l_kse_elem->optionPrelight = false;
+
+ // was that token really there?
+ skipOne = ( l_s_token.upper() != "FALSE" );
+ }
+ break;
+ case 'S':
+ // Statuslight
+ if ( l_s_token.upper() == "TRUE" )
+ l_kse_elem->optionStatuslight = true;
+ else
+ {
+ l_kse_elem->optionStatuslight = false;
+
+ // was that token really there?
+ skipOne = ( l_s_token.upper() != "FALSE" );
+ }
+ break;
+ case '1':
+ // parameter 1
+ if ( l_s_token.upper() == "TRUE" )
+ l_kse_elem->options[0] = true;
+ else
+ {
+ l_kse_elem->options[0] = false;
+
+ // was that token really there?
+ skipOne = ( l_s_token.upper() != "FALSE" );
+ }
+ break;
+ case '2':
+ // parameter 2
+ if ( l_s_token.upper() == "TRUE" )
+ l_kse_elem->options[1] = true;
+ else
+ {
+ l_kse_elem->options[1] = false;
+
+ // was that token really there?
+ skipOne = ( l_s_token.upper() != "FALSE" );
+ }
+ break;
+ case '3':
+ // parameter 3
+ if ( l_s_token.upper() == "TRUE" )
+ l_kse_elem->options[2] = true;
+ else
+ {
+ l_kse_elem->options[2] = false;
+
+ // was that token really there?
+ skipOne = ( l_s_token.upper() != "FALSE" );
+ }
+ break;
+ case 'l':
+ // length
+ if ( l_vertPixmaps )
+ l_kse_elem->pixmapLines = l_s_token.toInt();
+ else
+ l_kse_elem->pixmapColumns = l_s_token.toInt();
+ break;
+ case 'x':
+ // x Position
+ l_kse_elem->upperLeft.setX(l_s_token.toInt());
+ break;
+ case 'y':
+ // y Position
+ l_kse_elem->upperLeft.setY(l_s_token.toInt());
+ break;
+ case 's':
+ // dimension
+ if ( l_kse_elem->options[KaimanStyleSlider::optionVertical] )
+ l_kse_elem->dimension.setHeight(l_s_token.toInt());
+ else
+ l_kse_elem->dimension.setWidth(l_s_token.toInt());
+ break;
+ case 'w':
+ // width
+ l_kse_elem->dimension.setWidth(l_s_token.toInt());
+ break;
+ case 'h':
+ // height
+ l_kse_elem->dimension.setHeight(l_s_token.toInt());
+ break;
+ case 'd':
+ // number of digits
+ l_kse_elem->digits = l_s_token.toInt();
+ break;
+
+ default:
+ kdDebug() << "Element type '" << l_c_type << "' unknown" << endl;
+ }
+
+ if(skipOne) {
+ kdDebug() << "Skipped one element '" << l_c_type << "'" << endl;
+ }
+ } while(skipOne && l_s_tokenTypes.length() != 0);
+
+ // Next token.
+ ++li_s_tokens;
+ if (li_s_tokens == ref_s_tokens.end() ) {
+ // End of token list
+ break;
+ }
+ }
+
+ /* Do some post-processing */
+
+ if( l_elementType==ButtonElement ) {
+ // <Normal button>
+ if(but->optionPrelight) {
+ // --- Has Prelight ---
+ if(but->optionStatuslight)
+ but->pixmapColumns = 6;
+ else {
+ but->pixmapColumns = 3;
+ but->I_pmIndex.insert( KaimanStyleButton::LitUp,
+ new int( *(but->I_pmIndex[KaimanStyleButton::NormalUp])));
+ but->I_pmIndex.insert( KaimanStyleButton::LitDown,
+ new int( *(but->I_pmIndex[KaimanStyleButton::NormalDown])));
+ }
+ } else {
+ // --- Has No Prelight ---
+ but->I_pmIndex.insert( KaimanStyleButton::PrelightUp,
+ new int( *(but->I_pmIndex[KaimanStyleButton::NormalUp])));
+ but->I_pmIndex.insert( KaimanStyleButton::PrelightLitUp,
+ new int( *(but->I_pmIndex[KaimanStyleButton::LitUp])));
+ if(l_kse_elem->optionStatuslight)
+ but->pixmapColumns = 4;
+ else {
+ but->pixmapColumns = 2;
+ but->I_pmIndex.insert( KaimanStyleButton::LitUp,
+ new int( *(but->I_pmIndex[KaimanStyleButton::NormalUp])));
+ but->I_pmIndex.insert( KaimanStyleButton::LitDown,
+ new int( *(but->I_pmIndex[KaimanStyleButton::NormalDown])));
+ but->I_pmIndex.insert( KaimanStyleButton::PrelightLitUp,
+ new int( *(but->I_pmIndex[KaimanStyleButton::NormalUp])));
+ }
+ }
+ } else if( l_elementType==NumberElement ) {
+ // number items
+ l_kse_elem->pixmapColumns = 11;
+ if ( l_kse_elem->filename=="Small" ) l_kse_elem->filename = i_smallFont;
+ else if ( l_kse_elem->filename=="Large" ) l_kse_elem->filename = i_largeFont;
+ } else if( l_elementType==SliderElement ) {
+ // slider items
+ if ( l_kse_elem->options[KaimanStyleSlider::optionVertical] )
+ l_kse_elem->pixmapLines = l_kse_elem->optionPrelight ? 4 : 3;
+ else
+ l_kse_elem->pixmapColumns = l_kse_elem->optionPrelight ? 4 : 3;
+ } else if( l_elementType==TextElement ) {
+ // text items
+ l_kse_elem->pixmapColumns = 32;
+ l_kse_elem->pixmapLines = l_kse_elem->options[KaimanStyleText::optionExtended] ? 6 : 3;
+ } else {
+ // <Not standard element>
+ if(l_s_elem == "Stereo_Item")
+ l_kse_elem->pixmapLines = 3;
+ else if(l_s_elem == "Shuffle_Item")
+ l_kse_elem->pixmapLines = 2;
+ else if(l_s_elem == "Repeat_Item")
+ l_kse_elem->pixmapLines = 2;
+ else if(l_s_elem == "Mpegversion_Item")
+ l_kse_elem->pixmapLines = 3;
+ else if(l_s_elem == "Mpegversion_Item")
+ l_kse_elem->pixmapLines = 4;
+ else if(l_s_elem == "Mpegmode_Item")
+ l_kse_elem->pixmapLines = 5;
+ else if(l_s_elem == "Status_Item")
+ l_kse_elem->pixmapLines = 3;
+ } // </Not normal button>
+}
+
+
+QString KaimanStyle::getToken(QString &val_s_string, char val_c_separator)
+{
+ int l_i_pos;
+ QString l_s_token;
+
+ // Find the first occurrence of the separator
+ l_i_pos = val_s_string.find(val_c_separator, 0, false);
+ if ( l_i_pos == -1 ) {
+ // No sparator! Then the whole string is the token
+ l_s_token = val_s_string;
+ val_s_string = "";
+ }
+ else {
+ // Separator found: Split the string at the separator position
+ l_s_token = val_s_string.left(l_i_pos);
+ val_s_string.remove(0,l_i_pos);
+ }
+ val_s_string = val_s_string.simplifyWhiteSpace();
+
+ // Return the first token
+ return l_s_token;
+}
+
+
+
+bool KaimanStyle::loadStyle(const QString &styleName, const QString &descFile)
+{
+ bool l_b_ret = true;
+ int l_i_ret = 0;
+ QString l_s_tmpName;
+
+ i_skinName = styleName;
+ this->i_s_styleName = styleName;
+ i_s_styleBase = QString("skins/kaiman/") + i_s_styleName + QString("/");
+
+ l_s_tmpName = locate("appdata", i_s_styleBase + descFile );
+ if ( l_s_tmpName.isNull() ) {
+ l_b_ret = false;
+ }
+
+ if ( l_b_ret) {
+ // Skin description found. Now parse StyleFile.
+ l_i_ret = parseStyleFile(l_s_tmpName);
+ if (l_i_ret == 0) {
+ // If parsiing OK, load the referenced pixmaps
+ l_b_ret = loadPixmaps();
+
+ kdDebug(66666) << "Found " << I_styleElem.count() << " elements." << endl;
+ }
+ else {
+ if ( l_i_ret == KaimanStyle::FileNotFound ) {
+ // File not found
+ KMessageBox::error( 0, i18n("Cannot load style. Style not installed.") );
+ }
+ else {
+ // Parsing not OK: Notify user
+ KMessageBox::error( 0, i18n("Cannot load style. Unsupported or faulty style description.") );
+ }
+ }
+ }
+
+ return l_b_ret;
+}
+
+bool KaimanStyle::eventFilter( QObject *o, QEvent *e )
+{
+ /* HACK! HACK! HACK! */
+ if ( !i_eventSemaphore )
+ if ( e->type()==QEvent::MouseMove || e->type()==QEvent::MouseButtonPress ||
+ e->type()==QEvent::MouseButtonRelease )
+ {
+ QMouseEvent *m = (QMouseEvent*)e;
+
+ // handle noatun context menu
+ if (m->button()==RightButton) {
+ NoatunStdAction::ContextMenu::showContextMenu();
+ return true;
+ }
+
+ QPoint mousePos( m->x()+static_cast<QWidget *>(o)->x(),
+ m->y()+static_cast<QWidget *>(o)->y() );
+ QWidget *slider = 0;
+
+ /* find slider that is under the mouse position */
+ for ( QWidget *s = i_sliders.first(); s!=0; s=i_sliders.next() )
+ {
+ QRect sliderRect( s->pos(), s->size() );
+ if ( sliderRect.contains(mousePos) ) slider = s;
+ }
+
+ /* the slider the mouse events instead of the visible widget */
+ if ( slider )
+ {
+ QMouseEvent newMouseEvent( m->type(), mousePos-slider->pos(),
+ m->globalPos(), m->button(), m->state() );
+
+ i_eventSemaphore = true;
+ bool ret = QApplication::sendEvent( slider, &newMouseEvent );
+ i_eventSemaphore = false;
+ return ret;
+ }
+ }
+
+ return QWidget::eventFilter( o, e ); // standard event processing
+}
+
+bool KaimanStyle::loadPixmaps()
+{
+ QString l_s_tmpName;
+ QPixmap *l_pixmap_Background = 0, *l_pixmap_Mask = 0;
+ KaimanStyleElement *l_kse_elem;
+
+ for ( uint l_i_elem = 0; l_i_elem<I_styleElem.count(); l_i_elem++) {
+ l_kse_elem = I_styleElem[l_i_elem];
+
+ l_s_tmpName = locate("appdata", i_s_styleBase + l_kse_elem->filename );
+ l_kse_elem->loadPixmaps(l_s_tmpName);
+ }
+
+ l_kse_elem = this->find("Background");
+ if ( l_kse_elem != 0 ) {
+ l_pixmap_Background = l_kse_elem->pixmaps[0];
+ }
+ l_kse_elem = this->find("Mask");
+ if ( l_kse_elem != 0 ) {
+ l_pixmap_Mask = l_kse_elem->pixmaps[0];
+ }
+
+ if ( (l_pixmap_Background != 0) && (l_pixmap_Mask != 0) ) {
+
+ // OK, background and mask are defined. So now I can calculate the shape
+ int l_i_width_Mask = l_pixmap_Mask->width();
+ int l_i_height_Mask = l_pixmap_Mask->height();
+
+ QImage l_image_MaskOrig = l_pixmap_Mask->convertToImage();
+
+ QImage l_image_Mask(l_i_width_Mask,l_i_height_Mask, 1, 2, QImage::LittleEndian);
+ l_image_Mask.setColor( 0, 0x00ffffff );
+ l_image_Mask.setColor( 1, 0 );
+ l_image_Mask.fill( 0xff );
+
+ uchar *l_c_pixel;
+ uint l_qcol_white = qRgb(255,255,255);
+
+ for (int l_i_x=0; l_i_x<l_i_width_Mask; l_i_x++) {
+ for (int l_i_y=0; l_i_y < l_i_height_Mask; l_i_y++) {
+ if ( ((*((QRgb*) l_image_MaskOrig.scanLine(l_i_y)+l_i_x) & 0x00ffffff)) != (l_qcol_white & 0x00ffffff) ) {
+ l_c_pixel = (uchar *)l_image_Mask.scanLine(l_i_y);
+ *(l_c_pixel + (l_i_x>>3) ) &= ~(1 << (l_i_x & 7));
+ }
+ }
+ }
+
+ i_bitmap_Mask.convertFromImage(l_image_Mask);
+ // l_pixmap_Background.setMask(i_bitmap_Mask);
+ }
+
+ return true;
+}
+
+
+QBitmap* KaimanStyle::Mask()
+{
+ return &i_bitmap_Mask;
+}
+
+KaimanStyleElement* KaimanStyle::find(const char *val_s_elemName)
+{
+ for (uint i=0; i< I_styleElem.count(); i++) {
+ if ( I_styleElem[i]->element == QString(val_s_elemName)) {
+ return I_styleElem[i];
+ }
+ }
+ return 0;
+}
+#include "style.moc"
diff --git a/noatun/modules/kaiman/style.h b/noatun/modules/kaiman/style.h
new file mode 100644
index 00000000..0c1a6d81
--- /dev/null
+++ b/noatun/modules/kaiman/style.h
@@ -0,0 +1,356 @@
+// -*- C++ -*-
+/*
+ Copyright (c) 2000 Stefan Schimanski ([email protected])
+ 1999-2000 Christian Esken ([email protected])
+
+ 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, 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.
+*/
+
+#ifndef KaimanStyle_H
+#define KaimanStyle_H
+
+#include <qstring.h>
+#include <qwidget.h>
+#include <qpixmap.h>
+#include <qbitmap.h>
+#include <qimage.h>
+#include <qevent.h>
+#include <qptrvector.h>
+
+class KaimanStyleElement : public QWidget
+{
+ Q_OBJECT
+public:
+ KaimanStyleElement(QWidget *parent, const char *name=0);
+ ~KaimanStyleElement();
+
+ virtual void loadPixmaps(QString &val_s_filename);
+
+ QString element;
+ QString filename;
+ QPoint upperLeft;
+ QSize dimension;
+
+ bool options[3];
+ int digits;
+
+ bool optionPrelight;
+ bool optionStatuslight;
+
+ int pixmapLines;
+ int pixmapColumns;
+
+ QPtrVector<QPixmap> pixmaps;
+
+public slots:
+ void setPixmap( int num );
+
+protected:
+ void paintEvent(QPaintEvent *qpe);
+ void dropEvent( QDropEvent *event );
+ void dragEnterEvent( QDragEnterEvent *event );
+
+ int pixmapNum;
+
+private:
+ int _currentPixmap;
+};
+
+
+class KaimanStyleMasked : public KaimanStyleElement
+{
+ Q_OBJECT
+public:
+ KaimanStyleMasked(QWidget *parent, const char *name=0)
+ : KaimanStyleElement( parent, name ) {};
+
+ virtual void loadPixmaps(QString &val_s_filename)
+ {
+ KaimanStyleElement::loadPixmaps( val_s_filename );
+ if(pixmaps[0]->mask())
+ setMask(*pixmaps[0]->mask());
+ };
+};
+
+
+class KaimanStyleButton : public KaimanStyleMasked
+{
+ Q_OBJECT
+public:
+ KaimanStyleButton(QWidget *parent, const char *name=0);
+ ~KaimanStyleButton();
+
+ // Button states.
+ enum { NormalUp=0, NormalDown, LitUp, LitDown, PrelightUp, PrelightLitUp, StateListEND };
+
+ QPtrVector<int> I_pmIndex;
+
+ void setLit(bool);
+ void setPrelight(bool);
+ void setDown(bool);
+ bool lit();
+ bool prelit();
+ bool down();
+ void updateButtonState();
+
+signals:
+ void clicked();
+
+protected:
+ void mousePressEvent(QMouseEvent *qme);
+ void mouseReleaseEvent(QMouseEvent *qme);
+ void enterEvent(QEvent * );
+ void leaveEvent ( QEvent * );
+
+private:
+ int i_i_currentState;
+ bool i_b_lit;
+ bool i_b_prelit;
+ bool i_b_down;
+};
+
+
+class KaimanStyleSlider : public KaimanStyleMasked
+{
+ Q_OBJECT
+public:
+ KaimanStyleSlider(int min, int max, QWidget *parent, const char *name=0);
+ ~KaimanStyleSlider();
+
+ int value() { return _value; };
+
+ static const bool optionVertical;
+ static const bool optionReversed;
+
+public slots:
+ void setValue( int value );
+ void setValue( int value, int min, int max );
+
+signals:
+ void newValue( int value );
+ void newValueDrag( int value );
+ void newValueDrop( int value );
+
+protected:
+ void mouseMoveEvent(QMouseEvent *qme);
+ void mousePressEvent(QMouseEvent *qme);
+ void mouseReleaseEvent(QMouseEvent *qme);
+ void paintEvent(QPaintEvent *qpe);
+ void enterEvent(QEvent * );
+ void leaveEvent ( QEvent * );
+
+ int pos2value( int x, int y );
+
+ bool _down;
+ bool _lit;
+ int _value;
+ int _min, _max;
+};
+
+
+class KaimanStyleBackground : public KaimanStyleMasked
+{
+ Q_OBJECT
+public:
+ KaimanStyleBackground(QWidget *parent, const char *name=0);
+ ~KaimanStyleBackground();
+
+protected:
+ void mousePressEvent(QMouseEvent *qme);
+ void mouseReleaseEvent(QMouseEvent *qme);
+ void mouseMoveEvent(QMouseEvent *qme);
+
+private:
+ bool i_b_move;
+ QPoint i_point_dragStart;
+ QPoint i_point_lastPos;
+};
+
+
+class KaimanStyleValue : public KaimanStyleMasked
+{
+ Q_OBJECT
+public:
+ KaimanStyleValue(int min, int max, QWidget *parent, const char *name=0);
+ ~KaimanStyleValue();
+
+ int value() { return _value; };
+
+public slots:
+ void setValue( int value );
+ void setValue( int value, int min, int max );
+
+private:
+ int _min, _max, _value;
+};
+
+
+class KaimanStyleState : public KaimanStyleMasked
+{
+ Q_OBJECT
+public:
+ KaimanStyleState(QWidget *parent, const char *name=0);
+ ~KaimanStyleState();
+
+ int value() { return _value; };
+
+public slots:
+ void setValue( int value );
+
+signals:
+ void clicked();
+
+protected:
+ void mousePressEvent(QMouseEvent *qme);
+
+private:
+ int _value;
+};
+
+
+class KaimanStyleNumber : public KaimanStyleElement
+{
+ Q_OBJECT
+public:
+ KaimanStyleNumber(QWidget *parent, const char *name=0);
+ ~KaimanStyleNumber();
+
+ virtual void loadPixmaps(QString &val_s_filename);
+
+ static const bool optionCentered = 1;
+
+ int value() { return _value; };
+
+public slots:
+ void setValue( int value );
+
+protected:
+ void paintEvent(QPaintEvent *qpe);
+
+private:
+ int _value;
+};
+
+
+class KaimanStyleText : public KaimanStyleElement
+{
+ Q_OBJECT
+public:
+ KaimanStyleText(QWidget *parent, const char *name=0);
+ ~KaimanStyleText();
+
+ virtual void loadPixmaps(QString &val_s_filename);
+
+ static const bool optionExtended;
+
+ QString value() { return _value; };
+
+ void startAnimation( int delay );
+ void stopAnimation();
+
+public slots:
+ void setValue( QString value );
+
+protected:
+ void paintEvent(QPaintEvent *qpe);
+
+protected slots:
+ void timeout();
+
+private:
+ QString _value;
+ int _pos;
+ int _direction;
+ int _delay;
+ QTimer *_timer;
+};
+
+
+class KaimanStyleAnimation : public KaimanStyleMasked
+{
+ Q_OBJECT
+public:
+ KaimanStyleAnimation(int delay, QWidget *parent, const char *name=0);
+ ~KaimanStyleAnimation();
+
+public slots:
+ void start();
+ void pause();
+ void stop();
+
+protected:
+ void timeout();
+
+private:
+ int _delay,_frame;
+ QTimer *_timer;
+};
+
+class KaimanStyle : public QWidget
+{
+ Q_OBJECT
+public:
+ KaimanStyle(QWidget *parent, const char *name=0);
+ ~KaimanStyle();
+
+ enum { background, mask, play_Button, stop_Button, pause_Button, prev_Button, next_Button, repeat_Button, shuffle_Button, playlist_Button, mixer_Button, exit_Button, Iconify_Button, Config_Button, Alt_Skin_Button, Minute_Number, Second_Number, in_Rate_Number, in_Hz_Number, song_Number, status_Item, cPU_Number, digit_Large, digit_Small_Default, title, volume_Item, volume_Slider, position_Item, position_Slider };
+
+ enum { ParsingError=1, FileNotFound };
+
+ /// Finds a style element, according to it's name. Returns 0 when element is not available.
+ KaimanStyleElement* find(const char* val_s_elemName);
+
+ /// Tries to load the given style and returns success (true) or failure (false)
+ bool loadStyle(const QString &styleName, const QString &descFile="skindata" );
+ QString skinName() { return i_skinName; };
+
+ /// Returns the mask
+ QBitmap* Mask();
+
+ virtual bool eventFilter( QObject *o, QEvent *e );
+
+private:
+ // Parses the "skindata" file and returns success (true) or failure (false)
+ int parseStyleFile(QString &l_s_tmpName);
+ QString getToken(QString &val_s_string, char val_c_separator);
+ void interpretTokens(QStringList& ref_s_tokens);
+ bool loadPixmaps();
+
+ /// The name of the style, e.g. "k9"
+ QString i_s_styleName;
+ /// The base directory, where the style is found. For example
+ /// "/opt/kde/share/apps/kaiman/Skins/k9/" or "/opt/kde/share/apps/kaiman/Skins/k9.tgz"
+ QString i_s_styleBase;
+
+
+ // The mask of the complete style. Used for doing shaped windows
+ QBitmap i_bitmap_Mask;
+
+ /// All style elements are stored here.
+ QPtrVector<KaimanStyleElement> I_styleElem;
+
+ // The parent window. In other words: The container that holds all the KaimanStyleElement's
+ QWidget* i_qw_parent;
+
+ QPtrList<QWidget> i_sliders;
+ bool i_eventSemaphore;
+
+ QString i_smallFont;
+ QString i_largeFont;
+ QString i_skinName;
+};
+
+
+#endif
diff --git a/noatun/modules/kaiman/userinterface.cpp b/noatun/modules/kaiman/userinterface.cpp
new file mode 100644
index 00000000..31db0e09
--- /dev/null
+++ b/noatun/modules/kaiman/userinterface.cpp
@@ -0,0 +1,562 @@
+/*
+ Copyright (c) 2000 Stefan Schimanski <[email protected]>
+
+ 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, 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
+ aint with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <noatun/effects.h>
+#include <noatun/app.h>
+#include <noatun/player.h>
+#include <noatun/pref.h>
+#include "userinterface.h"
+#include "pref.h"
+
+#include <qcursor.h>
+#include <qpixmap.h>
+#include <qbitmap.h>
+#include <qimage.h>
+#include <qdropsite.h>
+#include <qdragobject.h>
+#include <qtimer.h>
+
+#include <kfiledialog.h>
+#include <kdebug.h>
+#include <kapplication.h>
+#include <kwin.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kconfig.h>
+#include <kpopupmenu.h>
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+#include <kio/netaccess.h>
+#include <kurldrag.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+#include <X11/X.h>
+#include <X11/Xos.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/shape.h>
+
+Kaiman* Kaiman::kaiman=0;
+const char Kaiman::DEFAULT_SKIN[]="car-preset";
+
+Kaiman::Kaiman()
+ : KMainWindow(0, "NoatunKaiman"), UserInterface()
+{
+ NOATUNPLUGINC(Kaiman);
+ kaiman=this;
+
+ //setCaption( i18n("Kaiman") );
+ KWin::setType( this->winId(), NET::Override );
+ setBackgroundMode( NoBackground );
+ setAcceptDrops(true);
+
+ _style = 0;
+ _seeking = false;
+ _altSkin = false;
+
+ // init config
+ KConfig *config=KGlobal::config();
+ config->setGroup("Kaiman");
+
+ // load skin
+ QString skinName = config->readEntry( "SkinResource", DEFAULT_SKIN );
+
+ if ( !changeStyle(skinName, "skindata") )
+ {
+ KMessageBox::sorry( this, i18n("Cannot load skin %1. Switching to default skin.").arg(skinName) );
+ if ( !changeStyle( DEFAULT_SKIN, "skindata" ) )
+ {
+ KMessageBox::error( this, i18n("Cannot load default skin %1.").arg(DEFAULT_SKIN) );
+ QTimer::singleShot( 0, this, SLOT(close()) );
+ return;
+ }
+ }
+
+ // global connects
+ connect( napp, SIGNAL(hideYourself()), this, SLOT(hide()) );
+ connect( napp, SIGNAL(showYourself()), this, SLOT(show()) );
+
+ connect( napp->player(), SIGNAL(playing()), this, SLOT(updateMode()));
+ connect( napp->player(), SIGNAL(stopped()), this, SLOT(updateMode()));
+ connect( napp->player(), SIGNAL(paused()), this, SLOT(updateMode()));
+ connect( napp->player(), SIGNAL(timeout()), this, SLOT(timeout()));
+ connect( napp->player(), SIGNAL(loopTypeChange(int)), this, SLOT(loopTypeChange(int)));
+ connect( napp->player(), SIGNAL(newSongLen(int,int)), this, SLOT(newSongLen(int,int)));
+ connect( napp->player(), SIGNAL(newSong()), this, SLOT(newSong()));
+
+ if( napp->player()->isPlaying() )
+ newSong();
+
+ new KaimanPrefDlg(this);
+
+ show();
+}
+
+
+Kaiman::~Kaiman()
+{
+}
+
+
+bool Kaiman::changeStyle( const QString &style, const QString &desc )
+{
+ QString ldesc = desc;
+ if ( ldesc.isEmpty() )
+ ldesc = _altSkin ? "alt_skindata" : "skindata";
+
+ bool vis = isVisible();
+ if ( vis )
+ hide();
+
+ bool ret = loadStyle( style, ldesc );
+
+ newSongLen(0,0);
+ timeout();
+ loopTypeChange(0);
+ updateMode();
+
+ if ( vis )
+ show();
+ return ret;
+}
+
+
+bool Kaiman::loadStyle( const QString &style, const QString &desc )
+{
+ if ( _style ) delete _style;
+ _style = new KaimanStyle(this);
+ if ( !_style->loadStyle( style, desc ) )
+ {
+ delete _style;
+ _style = 0;
+ return false;
+ }
+
+ if ( _style->Mask() != 0 )
+ {
+ // Set the shaped window form
+ XShapeCombineMask( qt_xdisplay(), winId(), ShapeBounding, 0,0,
+ _style->Mask()->handle(), ShapeSet );
+ }
+
+ KaimanStyleElement* item = _style->find("Background");
+ setBackgroundMode(QWidget::NoBackground);
+ if ( item!=0 )
+ {
+ _style->resize( item->width(), item->height());
+ resize( item->width(), item->height());
+ setFixedSize( item->width(), item->height());
+ }
+
+ item = _style->find("Playlist_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), napp->player(), SLOT(toggleListView()) );
+
+ item = _style->find("Play_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), napp->player(), SLOT(playpause()) );
+
+ item = _style->find("Pause_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), napp->player(), SLOT(playpause()) );
+
+ item = _style->find("Stop_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), napp->player(), SLOT(stop()) );
+
+ item = _style->find("Next_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), napp->player(), SLOT(forward()) );
+
+ item = _style->find("Prev_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), napp->player(), SLOT(back()) );
+
+ item = _style->find("Exit_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), this, SLOT(close()) );
+
+ item = _style->find("Mixer_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), this, SLOT(execMixer()) );
+
+ item = _style->find("Iconify_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), this, SLOT(showMinimized()) );
+
+ item = _style->find("Alt_Skin_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), this, SLOT(toggleSkin()) );
+
+ item = _style->find("Repeat_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), this, SLOT(toggleLoop()) );
+
+ item = _style->find("Shuffle_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), this, SLOT(toggleShuffle()) );
+
+ item = _style->find("Config_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), napp, SLOT(preferences()) );
+
+ item = _style->find("Volume_Up_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), this,SLOT(volumeUp()));
+
+ item = _style->find("Volume_Down_Button");
+ if( item!=0 ) connect( item, SIGNAL(clicked()), this,SLOT(volumeDown()));
+
+ KaimanStyleSlider* slider =
+ static_cast<KaimanStyleSlider*>(_style->find("Position_Slider"));
+ if( slider!=0 )
+ {
+ connect( slider, SIGNAL(newValueDrag(int)), this, SLOT(seekStart(int)) );
+ connect( slider, SIGNAL(newValue(int)), this, SLOT(seekDrag(int)) );
+ connect( slider, SIGNAL(newValueDrop(int)), this, SLOT(seekStop(int)) );
+ slider->setValue( 0, 0, 1000 );
+ }
+
+ slider = static_cast<KaimanStyleSlider*>(_style->find("Volume_Slider"));
+ if ( slider!=0 )
+ {
+ connect(slider, SIGNAL(newValue(int)), this, SLOT(setVolume(int)));
+ slider->setValue( napp->player()->volume(), 0, 100 );
+ }
+
+ KaimanStyleValue* volItem = static_cast<KaimanStyleValue*>(_style->find("Volume_Item"));
+ if ( volItem )
+ volItem->setValue( napp->player()->volume(), 0, 100 );
+
+ KaimanStyleText* titleItem = static_cast<KaimanStyleText*>(_style->find("Title"));
+ if ( titleItem )
+ titleItem->startAnimation( 300 );
+
+ return true;
+}
+
+
+void Kaiman::closeEvent(QCloseEvent*)
+{
+ unload();
+}
+
+
+void Kaiman::dragEnterEvent( QDragEnterEvent *event )
+{
+ event->accept( KURLDrag::canDecode(event) );
+}
+
+
+void Kaiman::dropEvent( QDropEvent *event )
+{
+ doDropEvent(event);
+}
+
+
+void Kaiman::doDropEvent(QDropEvent *event)
+{
+ KURL::List uri;
+ if (KURLDrag::decode(event, uri))
+ {
+ for (KURL::List::Iterator i = uri.begin(); i != uri.end(); ++i)
+ napp->player()->openFile(*i, false);
+ }
+}
+
+
+void Kaiman::seekStart( int )
+{
+ _seeking = true;
+}
+
+
+void Kaiman::seekDrag( int value )
+{
+ int length = napp->player()->getLength()/1000;
+ if ( length < 0)
+ length = 0;
+
+ if ( !_style ) return;
+
+ KaimanStyleValue* posItem =
+ static_cast<KaimanStyleValue*>(_style->find("Position_Item"));
+ if ( posItem )
+ posItem->setValue( value, 0, length );
+
+ KaimanStyleSlider* posSlider =
+ static_cast<KaimanStyleSlider*>(_style->find("Position_Slider"));
+ if ( posSlider )
+ posSlider->setValue( value, 0, length );
+
+ // update time
+
+ KaimanStyleNumber* numItem =
+ static_cast<KaimanStyleNumber*>(_style->find("Minute_Number"));
+ if ( numItem )
+ numItem->setValue( value/60%60 );
+
+ numItem = static_cast<KaimanStyleNumber*>(_style->find("Second_Number"));
+ if ( numItem )
+ numItem->setValue( value % 60 );
+}
+
+
+void Kaiman::seekStop( int value )
+{
+ seek( value );
+ _seeking = false;
+}
+
+
+void Kaiman::seek( int value )
+{
+ napp->player()->skipTo( value*1000 ); // skipTo() takes milliseconds
+}
+
+
+void Kaiman::toggleSkin()
+{
+ _altSkin = !_altSkin;
+
+ QString skinName = _style->skinName();
+
+ QString oldDesc, newDesc;
+ if ( _altSkin )
+ {
+ oldDesc = QString::fromLatin1("skindata");
+ newDesc = QString::fromLatin1("alt_skindata");
+ }
+ else
+ {
+ newDesc = QString::fromLatin1("skindata");
+ oldDesc = QString::fromLatin1("alt_skindata");
+ }
+
+ if ( !changeStyle(skinName, newDesc) )
+ changeStyle(skinName, oldDesc);
+}
+
+
+void Kaiman::setVolume( int vol )
+{
+ if ( vol<0 ) vol=0;
+ if ( vol>=100 ) vol=100;
+
+ napp->player()->setVolume( vol );
+}
+
+
+void Kaiman::volumeUp()
+{
+ setVolume( napp->player()->volume()+10 );
+}
+
+
+void Kaiman::volumeDown()
+{
+ setVolume( napp->player()->volume()-10 );
+}
+
+
+void Kaiman::execMixer()
+{
+ kapp->startServiceByDesktopName ( QString::fromLatin1("kmix"), QString::null );
+}
+
+
+void Kaiman::timeout()
+{
+ if ( !_style ) return;
+
+ if (!napp->player()->current())
+ return;
+
+ // update volume
+ KaimanStyleSlider* l_elem_volslider = static_cast<KaimanStyleSlider*>(_style->find("Volume_Slider"));
+ KaimanStyleValue* l_elem_volitem = static_cast<KaimanStyleValue*>(_style->find("Volume_Item"));
+ if ( l_elem_volslider!=0 )
+ l_elem_volslider->setValue( napp->player()->volume(), 0, 100 );
+ if ( l_elem_volitem!=0 )
+ l_elem_volitem->setValue( napp->player()->volume(), 0, 100 );
+
+ // update position
+ if ( !_seeking )
+ {
+ int sec = napp->player()->getTime()/1000;
+ if ( sec < 0 )
+ sec = 0;
+
+ KaimanStyleValue* posItem =
+ static_cast<KaimanStyleValue*>(_style->find("Position_Item"));
+ if ( posItem ) posItem->setValue( sec, 0, napp->player()->getLength()/1000 );
+
+ KaimanStyleSlider* posSlider =
+ static_cast<KaimanStyleSlider*>(_style->find("Position_Slider"));
+ if ( posSlider ) posSlider->setValue( sec, 0, napp->player()->getLength()/1000 );
+
+ // update time
+ KaimanStyleNumber* numItem =
+ static_cast<KaimanStyleNumber*>(_style->find("Minute_Number"));
+ if ( numItem )
+ numItem->setValue( sec/60%60 );
+
+ numItem = static_cast<KaimanStyleNumber*>(_style->find("Second_Number"));
+ if ( numItem )
+ numItem->setValue( sec%60 );
+ }
+
+ const PlaylistItem &item = napp->playlist()->current();
+ KaimanStyleNumber* numItem = 0;
+
+ numItem = static_cast<KaimanStyleNumber*>(_style->find("In_Rate_Number"));
+ if ( numItem )
+ numItem->setValue(item.property("bitrate").toInt());
+
+ QString hzString = item.property("samplerate");
+ hzString.truncate(2);
+
+ numItem = static_cast<KaimanStyleNumber*>(_style->find("In_Hz_Number"));
+ if ( numItem )
+ numItem->setValue(hzString.toInt());
+}
+
+
+void Kaiman::updateMode()
+{
+ if ( !_style ) return;
+
+ KaimanStyleButton* pause =
+ static_cast<KaimanStyleButton*>(_style->find("Pause_Button"));
+ KaimanStyleButton* play =
+ static_cast<KaimanStyleButton*>(_style->find("Play_Button"));
+ KaimanStyleState* status =
+ static_cast<KaimanStyleState*>(_style->find("Status_Item"));
+
+ if (napp->player()->isStopped() )
+ {
+ if ( pause ) pause->setLit( false );
+ if ( play ) play->setLit( false );
+ if ( status ) status->setValue( 0 );
+ }
+ else if ( napp->player()->isPlaying() )
+ {
+ if ( pause ) pause->setLit( false );
+ if ( play ) play->setLit( true );
+ if ( status ) status->setValue( 2 );
+ }
+ else if ( napp->player()->isPaused() )
+ {
+ if ( pause ) pause->setLit( true );
+ if ( play ) play->setLit( false );
+ if ( status ) status->setValue( 1 );
+ }
+}
+
+
+void Kaiman::loopTypeChange( int )
+{
+ if ( !_style ) return;
+
+ KaimanStyleState* rep = static_cast<KaimanStyleState*>(_style->find("Repeat_Item"));
+ if ( rep )
+ rep->setValue( napp->player()->loopStyle() );
+}
+
+
+void Kaiman::newSongLen( int, int )
+{
+ if ( !_style )
+ return;
+
+ int len = napp->player()->getLength()/1000; // convert milliseconds -> seconds
+ if ( len < 0 ) // getLength returns -1 if there's no Playobject
+ len = 0;
+
+ // update time
+ KaimanStyleNumber* numItem =
+ static_cast<KaimanStyleNumber*>(_style->find("Minute_Total_Number"));
+ if ( numItem )
+ numItem->setValue( len/60%60 );
+
+ numItem = static_cast<KaimanStyleNumber*>(_style->find("Second_Total_Number"));
+ if ( numItem )
+ numItem->setValue( len%60 );
+
+ numItem = static_cast<KaimanStyleNumber*>(_style->find("Song_Minute_Number"));
+ if ( numItem )
+ numItem->setValue( len/60%60 );
+
+ numItem = static_cast<KaimanStyleNumber*>(_style->find("Second_Minute_Number"));
+ if ( numItem )
+ numItem->setValue( len%60 );
+
+ newSong();
+}
+
+
+void Kaiman::newSong()
+{
+ if ( !_style ) return;
+
+ KaimanStyleText* titleItem = static_cast<KaimanStyleText*>(_style->find("Title"));
+ if ( titleItem )
+ {
+ QString title = i18n("Noatun");
+ if ( napp->player()->current() )
+ {
+ title = napp->player()->current().title();
+ if ( title.isEmpty() )
+ title = napp->player()->current().file();
+
+ title = i18n("TITLE (LENGTH)", "%1 (%2)").arg(title,
+ napp->player()->current().lengthString());
+ }
+ titleItem->setValue( title );
+ }
+}
+
+
+#undef None
+void Kaiman::toggleLoop()
+{
+ KPopupMenu *loopMenu = new KPopupMenu(this, "loopMenu");
+ int selectedItem = 0;
+
+ loopMenu->setCheckable(true);
+ loopMenu->insertTitle(i18n("Loop Style"));
+ loopMenu->insertItem(i18n("&None"),
+ (int)Player::None);
+ loopMenu->insertItem(i18n("&Song"),
+ (int)Player::Song);
+ loopMenu->insertItem(i18n("&Playlist"),
+ (int)(Player::Playlist));
+ loopMenu->insertItem(i18n("&Random"),
+ (int)(Player::Random));
+
+ loopMenu->setItemChecked((int)napp->player()->loopStyle(), true); // select current loopstyle in menu
+ selectedItem = loopMenu->exec(QCursor::pos());
+ if (selectedItem != -1)
+ napp->player()->loop(selectedItem); // set new loopstyle
+
+ delete loopMenu;
+}
+
+
+void Kaiman::toggleShuffle()
+{
+ napp->player()->loop(Player::Random); // set loopstyle to be random
+}
+
+#include "userinterface.moc"
diff --git a/noatun/modules/kaiman/userinterface.h b/noatun/modules/kaiman/userinterface.h
new file mode 100644
index 00000000..2fb46184
--- /dev/null
+++ b/noatun/modules/kaiman/userinterface.h
@@ -0,0 +1,85 @@
+/*
+ Copyright (c) 2000 Stefan Schimanski <[email protected]>
+
+ 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, 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
+ aint with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef USERINTERFACE_H
+#define USERINTERFACE_H
+
+#include <noatun/plugin.h>
+#include <noatun/app.h>
+#include <kmainwindow.h>
+#include "style.h"
+
+
+class Player;
+
+/**
+ * @short Main window class
+ * @author Stefan Schimanski <[email protected]>
+ * @version 0.1
+ */
+class Kaiman : public KMainWindow, public UserInterface
+{
+Q_OBJECT
+ public:
+ Kaiman();
+ virtual ~Kaiman();
+
+ bool changeStyle( const QString &style, const QString &desc=QString::null );
+ public slots:
+ void dropEvent( QDropEvent * );
+ void doDropEvent( QDropEvent * );
+ void dragEnterEvent( QDragEnterEvent * );
+ void closeEvent(QCloseEvent*);
+
+ protected slots:
+ void seekStart( int );
+ void seekDrag( int );
+ void seekStop( int );
+ void seek( int );
+ void toggleSkin();
+
+ void setVolume( int vol );
+ void volumeUp();
+ void volumeDown();
+
+ void execMixer();
+
+
+ void timeout();
+ void loopTypeChange( int t );
+ void newSongLen( int mins, int sec );
+ void newSong();
+ void updateMode();
+ void toggleLoop();
+ void toggleShuffle();
+
+ public:
+ static const char DEFAULT_SKIN[];
+ static Kaiman *kaiman;
+
+ protected:
+ bool loadStyle( const QString &style, const QString &desc );
+
+
+ bool _seeking;
+ bool _altSkin;
+ KaimanStyle *_style;
+};
+
+
+#endif