Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
  • abdsaber000/vlc
  • falbrechtskirchinger/vlc
  • b.sullender/vlc
  • hulxv/vlc
407 results
Show changes
Commits on Source (9)
......@@ -59,13 +59,17 @@ VideoAll {
}
header: Column {
width: root.width
topPadding: VLCStyle.margin_normal
bottomPadding: VLCStyle.margin_normal
Widgets.SubtitleLabel {
width: root.width
anchors.left: parent.left
anchors.right: parent.right
leftPadding : VLCStyle.margin_xlarge
bottomPadding: VLCStyle.margin_xsmall
// NOTE: We want this to be properly aligned with the grid items.
anchors.leftMargin: contentMargin + VLCStyle.margin_normal
text: root.name
}
......
......@@ -34,6 +34,10 @@ FocusScope {
// Properties
readonly property int contentMargin: (mainInterface.gridView
&&
_currentView) ? _currentView.contentMargin : 0
// NOTE: Specify an optionnal header for the view.
property Component header: undefined
......@@ -100,10 +104,10 @@ FocusScope {
if (initialIndex >= model.count)
initialIndex = 0
modelSelect.select(model.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect);
modelSelect.select(model.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
if (_currentView)
_currentView.positionViewAtIndex(initialIndex, ItemView.Contain);
_currentView.positionViewAtIndex(initialIndex, ItemView.Contain)
}
// Private
......@@ -114,9 +118,18 @@ FocusScope {
medialib.addAndPlay(model.getIdsForIndexes(modelSelect.selectedIndexes));
}
// Events
function _onNavigationUp() {
if (headerItem && headerItem.focus)
headerItem.setCurrentItemFocus(Qt.TabFocusReason);
else
Navigation.defaultNavigationUp();
}
function _onNavigationCancel() {
if (_currentView.currentIndex <= 0) {
Navigation.defaultNavigationCancel()
Navigation.defaultNavigationCancel();
} else {
_currentView.currentIndex = 0;
......@@ -200,7 +213,8 @@ FocusScope {
activeFocusOnTab: true
Navigation.parentItem: root
Navigation.upItem: (headerItem) ? headerItem.focusItem : null
Navigation.upAction: _onNavigationUp
//cancelAction takes a *function* pass it directly
Navigation.cancelAction: root._onNavigationCancel
......@@ -322,7 +336,8 @@ FocusScope {
activeFocusOnTab: true
Navigation.parentItem: root
Navigation.upItem: (headerItem) ? headerItem.focusItem : null
Navigation.upAction: _onNavigationUp
//cancelAction takes a *function* pass it directly
Navigation.cancelAction: root._onNavigationCancel
......
......@@ -41,10 +41,8 @@ VideoAll {
// Functions
function setCurrentItemFocus(reason) {
var loader = headerItem.loader;
if (loader.visible)
loader.item.forceActiveFocus(reason);
if (modelRecent.count)
headerItem.setCurrentItemFocus(reason);
else
_currentView.setCurrentItemFocus(reason);
}
......@@ -65,17 +63,29 @@ VideoAll {
width: root.width
topPadding: VLCStyle.margin_normal
spacing: VLCStyle.margin_normal
bottomPadding: VLCStyle.margin_normal
// NOTE: We want the header to be visible when we have at least one media visible.
// Otherwise it overlaps the default caption.
visible: (model.count)
// NOTE: Making sure this item will be focussed by VideoAll::_onNavigationUp().
focus: true
function setCurrentItemFocus(reason) {
var item = loader.item;
if (item)
item.setCurrentItemFocus(reason);
}
Loader {
id: loader
width: parent.width
anchors.left : parent.left
anchors.right: parent.right
anchors.margins: root.contentMargin
height: (status === Loader.Ready) ? item.implicitHeight : 0
......@@ -88,6 +98,9 @@ VideoAll {
width: parent.width
// NOTE: We want grid items to be visible on the sides.
displayMargins: root.contentMargin
model: modelRecent
focus: true
......@@ -101,10 +114,11 @@ VideoAll {
}
Widgets.SubtitleLabel {
width: root.width
anchors.left: loader.left
anchors.right: loader.right
leftPadding : VLCStyle.margin_xlarge
bottomPadding: VLCStyle.margin_xsmall
// NOTE: We want this to be properly aligned with the grid items.
anchors.leftMargin: VLCStyle.margin_normal
text: i18n.qtr("Videos")
}
......
......@@ -32,15 +32,16 @@ FocusScope {
// Properties
property int leftPadding: VLCStyle.margin_xlarge
property int rightPadding: VLCStyle.margin_xlarge
property Item focusItem: recentVideosListView
property int currentIndex: -1
property var model: undefined;
// Properties
property int displayMargins: 0
// Settings
implicitHeight: recentVideosColumn.height
......@@ -56,6 +57,12 @@ FocusScope {
root.currentIndex = 0
}
// Functions
function setCurrentItemFocus(reason) {
recentVideosListView.setCurrentItemFocus(reason);
}
function _actionAtIndex(index, model, selectionModel) {
g_mainDisplay.showPlayer()
medialib.addAndPlay( model.getIdsForIndexes( selectionModel.selectedIndexes ), [":restore-playback-pos=2"] )
......@@ -77,8 +84,13 @@ FocusScope {
Widgets.SubtitleLabel {
id: continueWatchingLabel
leftPadding: VLCStyle.margin_xlarge
width: parent.width
anchors.left: parent.left
anchors.right: parent.right
// NOTE: We want this to be properly aligned with the grid items.
anchors.leftMargin: VLCStyle.margin_normal
text: i18n.qtr("Continue Watching")
}
......@@ -86,18 +98,30 @@ FocusScope {
id: recentVideosListView
width: parent.width
implicitHeight: VLCStyle.gridItem_video_height_large + VLCStyle.gridItemSelectedBorder + VLCStyle.margin_xlarge
implicitHeight: VLCStyle.gridItem_video_height + VLCStyle.gridItemSelectedBorder
+
VLCStyle.margin_xlarge
spacing: VLCStyle.column_margin_width
// NOTE: Sometimes, we want items to be visible on the sides.
displayMarginBeginning: root.displayMargins
displayMarginEnd: root.displayMargins
// NOTE: We want navigation buttons to be centered on the item cover.
buttonMargin: VLCStyle.margin_xsmall + VLCStyle.gridCover_video_height / 2 - buttonLeft.height / 2
orientation: ListView.Horizontal
focus: true
Navigation.parentItem: root
model: root.model
Navigation.parentItem: root
header: Item {
width: VLCStyle.margin_xlarge
width: VLCStyle.margin_normal
}
delegate: VideoGridItem {
......@@ -105,8 +129,8 @@ FocusScope {
x: selectedBorderWidth
y: selectedBorderWidth
pictureWidth: VLCStyle.gridCover_video_width_large
pictureHeight: VLCStyle.gridCover_video_height_large
pictureWidth: VLCStyle.gridCover_video_width
pictureHeight: VLCStyle.gridCover_video_height
focus: true
......@@ -142,7 +166,7 @@ FocusScope {
}
footer: Item {
width: VLCStyle.margin_xlarge
width: VLCStyle.margin_normal
}
onSelectionUpdated: recentVideoSelection.updateSelection( keyModifiers, oldIndex, newIndex )
......@@ -154,8 +178,8 @@ FocusScope {
Widgets.GridShadows {
id: shadows
coverWidth: VLCStyle.gridCover_video_width_large
coverHeight: VLCStyle.gridCover_video_height_large
coverWidth: VLCStyle.gridCover_video_width
coverHeight: VLCStyle.gridCover_video_height
}
}
}
......
......@@ -164,9 +164,6 @@ QtObject {
readonly property int gridCover_video_height: ( gridCover_video_width * 10.0 ) / 16
readonly property int gridCover_video_border: dp(4, scale)
readonly property int gridCover_video_width_large: dp(406, scale)
readonly property int gridCover_video_height_large: ( gridCover_video_width_large * 10.0 ) / 16
readonly property int gridCover_radius: dp(4, scale)
readonly property int expandCover_music_height: dp(171, scale)
......@@ -186,10 +183,6 @@ QtObject {
readonly property int gridItem_video_width: VLCStyle.gridCover_video_width
readonly property int gridItem_video_height: VLCStyle.gridCover_video_height + VLCStyle.margin_xxsmall + VLCStyle.fontHeight_normal + VLCStyle.fontHeight_normal
readonly property int gridItem_video_width_large: VLCStyle.gridCover_video_width_large
readonly property int gridItem_video_height_large: VLCStyle.gridCover_video_height_large + VLCStyle.margin_xxsmall + VLCStyle.fontHeight_large +
VLCStyle.margin_xxsmall + VLCStyle.fontHeight_normal
readonly property int gridItemSelectedBorder: dp(8, scale)
readonly property int gridItem_newIndicator: dp(8, scale)
......
......@@ -25,6 +25,8 @@ import "qrc:///util/Helpers.js" as Helpers
FocusScope {
id: root
// Properties
/// cell Width
property int cellWidth: 100
// cell Height
......@@ -36,25 +38,31 @@ FocusScope {
property int leftMargin: VLCStyle.margin_normal
property int rightMargin: VLCStyle.margin_normal
// NOTE: The grid margin for the item(s) horizontal positioning.
readonly property int contentMargin: (_contentWidth - _nbItemPerRow * _effectiveCellWidth
+
horizontalSpacing) / 2
property int rowX: 0
property int horizontalSpacing: VLCStyle.column_margin_width
property int verticalSpacing: VLCStyle.column_margin_width
property int displayMarginEnd: 0
onDisplayMarginEndChanged: flickable.layout(false)
readonly property int _effectiveCellWidth: cellWidth + horizontalSpacing
readonly property int _effectiveCellHeight: cellHeight + verticalSpacing
readonly property int _contentWidth: width - rightMargin - leftMargin
readonly property int _nbItemPerRow: Math.max(Math.floor((_contentWidth + horizontalSpacing)
/
_effectiveCellWidth), 1)
property var delegateModel
property var model
property int currentIndex: 0
property alias contentHeight: flickable.contentHeight
property alias contentWidth: flickable.contentWidth
property alias contentX: flickable.contentX
property alias gridScrollBar: flickableScrollBar
property bool isAnimating: animateRetractItem.running || animateExpandItem.running
property int _count: 0
......@@ -70,37 +78,200 @@ FocusScope {
property int _currentFocusReason: Qt.OtherFocusReason
on_ExpandItemVerticalSpaceChanged: {
if (expandItem) {
expandItem.visible = root._expandItemVerticalSpace - root.verticalSpacing > 0
expandItem.height = Math.max(root._expandItemVerticalSpace - root.verticalSpacing, 0)
}
flickable.layout(true)
}
//delegate to display the extended item
property Component delegate: Item{}
property Component expandDelegate: Item{}
property alias expandItem: expandItemLoader.item
property Component headerDelegate: Item{}
property var _idChildrenList: []
property var _unusedItemList: []
property var _currentRange: [0,0]
// Aliases
property alias contentHeight: flickable.contentHeight
property alias contentWidth: flickable.contentWidth
property alias contentX: flickable.contentX
property alias gridScrollBar: flickableScrollBar
property alias expandItem: expandItemLoader.item
property alias headerHeight: headerItemLoader.implicitHeight
property alias headerItem: headerItemLoader.item
property alias footerItem: footerItemLoader.item
property alias footerDelegate: footerItemLoader.sourceComponent
// Signals
//signals emitted when selected items is updated from keyboard
signal selectionUpdated( int keyModifiers, int oldIndex,int newIndex )
signal selectAll()
signal actionAtIndex(int index)
property var _idChildrenList: []
property var _unusedItemList: []
property var _currentRange: [0,0]
// Settings
Accessible.role: Accessible.Table
// Events
Component.onCompleted: flickable.layout(true)
onHeightChanged: flickable.layout(false)
// NOTE: Update on contentMargin change rather than width since the margin defines the x
// position and depends on the width.
onContentMarginChanged: flickable.layout(true)
onDisplayMarginEndChanged: flickable.layout(false)
onModelChanged: _onModelCountChanged()
onCurrentIndexChanged: {
if (expandIndex !== -1)
retract()
positionViewAtIndex(currentIndex, ItemView.Contain)
}
on_ExpandItemVerticalSpaceChanged: {
if (expandItem) {
expandItem.visible = _expandItemVerticalSpace - verticalSpacing > 0
expandItem.height = Math.max(_expandItemVerticalSpace - verticalSpacing, 0)
}
flickable.layout(true)
}
// Keys
Keys.onPressed: {
var newIndex = -1
if (KeyHelper.matchRight(event)) {
if ((currentIndex + 1) % _nbItemPerRow !== 0) {//are we not at the end of line
newIndex = Math.min(_count - 1, currentIndex + 1)
}
} else if (KeyHelper.matchLeft(event)) {
if (currentIndex % _nbItemPerRow !== 0) {//are we not at the begining of line
newIndex = Math.max(0, currentIndex - 1)
}
} else if (KeyHelper.matchDown(event)) {
// we are not on the last line
if (Math.floor(currentIndex / _nbItemPerRow) !== Math.floor(_count / _nbItemPerRow)) {
newIndex = Math.min(_count - 1, currentIndex + _nbItemPerRow)
}
} else if (KeyHelper.matchPageDown(event)) {
newIndex = Math.min(_count - 1, currentIndex + _nbItemPerRow * 5)
} else if (KeyHelper.matchUp(event)) {
if (Math.floor(currentIndex / _nbItemPerRow) !== 0) { //we are not on the first line
newIndex = Math.max(0, currentIndex - _nbItemPerRow)
}
} else if (KeyHelper.matchPageUp(event)) {
newIndex = Math.max(0, currentIndex - _nbItemPerRow * 5)
} else if (KeyHelper.matchOk(event) || event.matches(StandardKey.SelectAll) ) {
//these events are matched on release
event.accepted = true
}
if (event.matches(StandardKey.SelectAll) || KeyHelper.matchOk(event)) {
_releaseActionButtonPressed = true
} else {
_releaseActionButtonPressed = false
}
if (newIndex !== -1 && newIndex !== currentIndex) {
event.accepted = true;
var oldIndex = currentIndex;
currentIndex = newIndex;
selectionUpdated(event.modifiers, oldIndex, newIndex);
// NOTE: We make sure we have the proper visual focus on components.
if (oldIndex < currentIndex)
setCurrentItemFocus(Qt.TabFocusReason);
else
setCurrentItemFocus(Qt.BacktabFocusReason);
}
if (!event.accepted) {
Navigation.defaultKeyAction(event)
}
}
Keys.onReleased: {
if (!_releaseActionButtonPressed)
return
if (event.matches(StandardKey.SelectAll)) {
event.accepted = true
selectAll()
} else if ( KeyHelper.matchOk(event) ) {
event.accepted = true
actionAtIndex(currentIndex)
}
_releaseActionButtonPressed = false
}
// Connections
Connections {
target: model
onDataChanged: {
var iMin = topLeft.row
var iMax = bottomRight.row + 1 // [] => [)
var f_l = _currentRange
if (iMin < f_l[1] && f_l[0] < iMax) {
_refreshData(iMin, iMax)
}
}
onRowsInserted: _onModelCountChanged()
onRowsRemoved: _onModelCountChanged()
onModelReset: _onModelCountChanged()
}
Connections {
target: delegateModel
onSelectionChanged: {
var i
for (i = 0; i < selected.length; ++i) {
_updateSelectedRange(selected[i].topLeft, selected[i].bottomRight, true)
}
for (i = 0; i < deselected.length; ++i) {
_updateSelectedRange(deselected[i].topLeft, deselected[i].bottomRight, false)
}
}
function _updateSelectedRange(topLeft, bottomRight, select) {
var iMin = topLeft.row
var iMax = bottomRight.row + 1 // [] => [)
if (iMin < root._currentRange[1] && root._currentRange[0] < iMax) {
iMin = Math.max(iMin, root._currentRange[0])
iMax = Math.min(iMax, root._currentRange[1])
for (var j = iMin; j < iMax; j++) {
var item = root._getItem(j)
console.assert(item)
item.selected = select
}
}
}
}
Connections {
target: mainInterface
onIntfScaleFactorChanged: flickable.layout(true)
}
// Animations
PropertyAnimation {
id: animateContentY;
target: flickable;
properties: "contentY"
}
// Functions
function setCurrentItemFocus(reason) {
// NOTE: Saving the focus reason for later.
......@@ -149,24 +320,16 @@ FocusScope {
flickable.retract()
}
function getNbItemsPerRow() {
return Math.max(Math.floor(((width - root.rightMargin - root.leftMargin) + root.horizontalSpacing) / root._effectiveCellWidth), 1)
}
function getItemRowCol(id) {
var nbItemsPerRow = getNbItemsPerRow()
var rowId = Math.floor(id / nbItemsPerRow)
var colId = id % nbItemsPerRow
var rowId = Math.floor(id / _nbItemPerRow)
var colId = id % _nbItemPerRow
return [colId, rowId]
}
function getItemPos(id) {
var remainingSpace = (flickable.width - rightMargin - leftMargin)
- getNbItemsPerRow() * _effectiveCellWidth + horizontalSpacing;
var rowCol = getItemRowCol(id);
var x = rowCol[0] * _effectiveCellWidth + remainingSpace / 2 + leftMargin;
var x = rowCol[0] * _effectiveCellWidth + contentMargin + leftMargin;
var y = rowCol[1] * _effectiveCellHeight + headerHeight + topMargin;
......@@ -190,13 +353,13 @@ FocusScope {
var newContentY = flickable.contentY
var itemTopY = root.getItemPos(index)[1]
var itemBottomY = itemTopY + root._effectiveCellHeight
var itemTopY = getItemPos(index)[1]
var itemBottomY = itemTopY + _effectiveCellHeight
var viewTopY = flickable.contentY
var viewBottomY = viewTopY + flickable.height
if (index < getNbItemsPerRow()) {
if (index < _nbItemPerRow) {
//force to see the header when on the first row
newContentY = 0
} else if ( itemTopY < viewTopY ) {
......@@ -212,12 +375,12 @@ FocusScope {
}
function leftClickOnItem(modifier, index) {
delegateModel.updateSelection( modifier , currentIndex, index)
delegateModel.updateSelection(modifier, currentIndex, index)
if (delegateModel.isSelected(model.index(index, 0)))
currentIndex = index
else if (currentIndex === index) {
if (root._containsItem(currentIndex))
root._getItem(currentIndex).focus = false
if (_containsItem(currentIndex))
_getItem(currentIndex).focus = false
currentIndex = -1
}
......@@ -227,27 +390,36 @@ FocusScope {
function rightClickOnItem(index) {
if (!delegateModel.isSelected(model.index(index, 0))) {
root.leftClickOnItem(Qt.NoModifier, index)
leftClickOnItem(Qt.NoModifier, index)
}
}
function animateFlickableContentY( newContentY ) {
animateContentY.stop()
animateContentY.duration = VLCStyle.duration_slow
animateContentY.to = newContentY
animateContentY.start()
}
// Private
function _initialize() {
if (root._isInitialised)
if (_isInitialised)
return;
if (flickable.width === 0 || flickable.height === 0)
return;
if (currentIndex !== 0)
positionViewAtIndex(currentIndex, ItemView.Contain)
root._isInitialised = true;
_isInitialised = true;
}
function _calculateCurrentRange() {
var myContentY = flickable.contentY - root.headerHeight - topMargin
var myContentY = flickable.contentY - headerHeight - topMargin
var contentYWithoutExpand = myContentY
var heightWithoutExpand = flickable.height + root.displayMarginEnd
if (root.expandIndex !== -1) {
var heightWithoutExpand = flickable.height + displayMarginEnd
if (expandIndex !== -1) {
if (myContentY >= expandItem.y && myContentY < expandItem.y + _expandItemVerticalSpace)
contentYWithoutExpand = expandItem.y
if (myContentY >= expandItem.y + _expandItemVerticalSpace)
......@@ -259,33 +431,33 @@ FocusScope {
heightWithoutExpand -= expandDisplayedHeight
}
var rowId = Math.floor(contentYWithoutExpand / root._effectiveCellHeight)
var firstId = Math.max(rowId * root.getNbItemsPerRow(), 0)
var rowId = Math.floor(contentYWithoutExpand / _effectiveCellHeight)
var firstId = Math.max(rowId * _nbItemPerRow, 0)
rowId = Math.ceil((contentYWithoutExpand + heightWithoutExpand) / root._effectiveCellHeight)
var lastId = Math.min(rowId * root.getNbItemsPerRow(), _count)
rowId = Math.ceil((contentYWithoutExpand + heightWithoutExpand) / _effectiveCellHeight)
var lastId = Math.min(rowId * _nbItemPerRow, _count)
return [firstId, lastId]
}
function _getItem(id) {
var i = id - root._currentRange[0]
return root._idChildrenList[i]
var i = id - _currentRange[0]
return _idChildrenList[i]
}
function _setItem(id, item) {
var i = id - root._currentRange[0]
root._idChildrenList[i] = item
var i = id - _currentRange[0]
_idChildrenList[i] = item
}
function _containsItem(id) {
var i = id - root._currentRange[0]
return i >= 0 && i < root._idChildrenList.length && typeof root._idChildrenList[i] !== "undefined"
var i = id - _currentRange[0]
return i >= 0 && i < _idChildrenList.length && typeof _idChildrenList[i] !== "undefined"
}
function _repositionItem(id, x, y) {
var item = root._getItem(id)
var item = _getItem(id)
if (item === undefined)
throw "wrong child: " + id
......@@ -309,13 +481,13 @@ FocusScope {
item.y = y
item.visible = true
root._setItem(id, item)
_setItem(id, item)
return item
}
function _createItem(id, x, y) {
var item = root.delegate.createObject( flickable.contentItem, {
var item = delegate.createObject( flickable.contentItem, {
selected: delegateModel.isSelected(model.index(id, 0)),
index: id,
model: model.getDataAt(id),
......@@ -326,17 +498,17 @@ FocusScope {
if (item === undefined)
throw "wrong unable to instantiate child " + id
root._setItem(id, item)
_setItem(id, item)
return item
}
function _setupChild(id, ydelta) {
var pos = root.getItemPos(id)
var pos = getItemPos(id)
var item;
if (root._containsItem(id))
if (_containsItem(id))
item = _repositionItem(id, pos[0], pos[1] + ydelta)
else if (_unusedItemList.length > 0)
item = _recycleItem(id, pos[0], pos[1] + ydelta)
......@@ -351,25 +523,25 @@ FocusScope {
}
function _refreshData( iMin, iMax ) {
var f_l = root._currentRange
var f_l = _currentRange
if (!iMin || iMin < f_l[0])
iMin = f_l[0]
if (!iMax || iMax > f_l[1])
iMax= f_l[1]
for (var id = iMin; id < iMax; id++) {
var item = root._getItem(id)
var item = _getItem(id)
item.model = model.getDataAt(id)
}
if (root.expandIndex >= iMin && root.expandIndex < iMax) {
expandItem.model = model.getDataAt(root.expandIndex)
if (expandIndex >= iMin && expandIndex < iMax) {
expandItem.model = model.getDataAt(expandIndex)
}
}
function _onModelCountChanged() {
_count = model ? model.rowCount() : 0
if (!root._isInitialised)
if (!_isInitialised)
return
// Hide the expandItem with no animation
......@@ -381,56 +553,7 @@ FocusScope {
_refreshData()
}
Connections {
target: model
onDataChanged: {
var iMin = topLeft.row
var iMax = bottomRight.row + 1 // [] => [)
var f_l = root._currentRange
if (iMin < f_l[1] && f_l[0] < iMax) {
_refreshData(iMin, iMax)
}
}
onRowsInserted: _onModelCountChanged()
onRowsRemoved: _onModelCountChanged()
onModelReset: _onModelCountChanged()
}
Connections {
target: delegateModel
onSelectionChanged: {
var i
for (i = 0; i < selected.length; ++i) {
_updateSelectedRange(selected[i].topLeft, selected[i].bottomRight, true)
}
for (i = 0; i < deselected.length; ++i) {
_updateSelectedRange(deselected[i].topLeft, deselected[i].bottomRight, false)
}
}
function _updateSelectedRange(topLeft, bottomRight, select) {
var iMin = topLeft.row
var iMax = bottomRight.row + 1 // [] => [)
if (iMin < root._currentRange[1] && root._currentRange[0] < iMax) {
iMin = Math.max(iMin, root._currentRange[0])
iMax = Math.min(iMax, root._currentRange[1])
for (var j = iMin; j < iMax; j++) {
var item = root._getItem(j)
console.assert(item)
item.selected = select
}
}
}
}
onModelChanged: _onModelCountChanged()
Connections {
target: mainInterface
onIntfScaleFactorChanged: flickable.layout(true)
}
// Children
//Gridview visible above the expanded item
Flickable {
......@@ -466,8 +589,9 @@ FocusScope {
Loader {
id: footerItemLoader
focus: (status === Loader.Ready) ? item.focus : false
y: root.topMargin + root.headerHeight + (root._effectiveCellHeight * (Math.ceil(model.count / getNbItemsPerRow()))) +
_expandItemVerticalSpace
y: root.topMargin + root.headerHeight + (root._effectiveCellHeight * (Math.ceil(model.count / root._nbItemPerRow))) +
root._expandItemVerticalSpace
}
Connections {
......@@ -500,10 +624,8 @@ FocusScope {
}
}
anchors.fill: parent
onWidthChanged: { layout(true) }
onHeightChanged: { layout(false) }
onContentYChanged: { scrollLayoutTimer.start() }
Timer {
......@@ -521,9 +643,9 @@ FocusScope {
if (root.expandIndex !== -1) {
var rowCol = root.getItemRowCol(root.expandIndex)
var rowId = rowCol[1] + 1
ret = rowId * root.getNbItemsPerRow()
ret = rowId * root._nbItemPerRow
} else {
ret = _count
ret = root._count
}
return ret
}
......@@ -561,16 +683,16 @@ FocusScope {
root._setItem(i, undefined)
}
for (i = _currentRange[0]; i < _currentRange[1]; ++i) {
for (i = root._currentRange[0]; i < root._currentRange[1]; ++i) {
var item = root._getItem(i)
if (typeof item !== "undefined") {
item.visible = false
_unusedItemList.push(item)
root._unusedItemList.push(item)
// root._setItem(i, undefined) // not needed the list will be reset following this loop
}
}
_idChildrenList = newList
root._idChildrenList = newList
root._currentRange = [first, last]
}
......@@ -610,13 +732,13 @@ FocusScope {
}
// Place the delegates after the expandItem
_setupIndexes(forceRelayout, [topGridEndId, lastId], _expandItemVerticalSpace)
_setupIndexes(forceRelayout, [topGridEndId, lastId], root._expandItemVerticalSpace)
// Calculate and set the contentHeight
var newContentHeight = root.getItemPos(_count - 1)[1] + root._effectiveCellHeight + _expandItemVerticalSpace
var newContentHeight = root.getItemPos(root._count - 1)[1] + root._effectiveCellHeight + root._expandItemVerticalSpace
contentHeight = newContentHeight + root.bottomMargin // topMargin is included from root.getItemPos
contentHeight += footerItemLoader.item ? footerItemLoader.item.height : 0
contentWidth = root._effectiveCellWidth * root.getNbItemsPerRow() - root.horizontalSpacing
contentWidth = root._effectiveCellWidth * root._nbItemPerRow - root.horizontalSpacing
}
Connections {
......@@ -630,17 +752,17 @@ FocusScope {
}
function expand() {
expandIndex = _newExpandIndex
if (expandIndex === -1)
root.expandIndex = root._newExpandIndex
if (root.expandIndex === -1)
return
expandItem.model = model.getDataAt(expandIndex)
expandItem.model = model.getDataAt(root.expandIndex)
/* We must also start the expand animation here since the expandItem implicitHeight is not
changed if it had the same height at previous opening. */
expandAnimation()
}
function expandAnimation() {
if (expandIndex === -1)
if (root.expandIndex === -1)
return
var expandItemHeight = expandItem.implicitHeight + root.verticalSpacing
......@@ -655,7 +777,7 @@ FocusScope {
animateExpandItem.start()
// Sliding animation
var currentItemYPos = root.getItemPos(expandIndex)[1]
var currentItemYPos = root.getItemPos(root.expandIndex)[1]
currentItemYPos += root._effectiveCellHeight / 2
animateFlickableContentY(currentItemYPos)
}
......@@ -672,8 +794,8 @@ FocusScope {
duration: VLCStyle.duration_slow
to: 0
onStopped: {
expandIndex = -1
if (_newExpandIndex !== -1)
root.expandIndex = -1
if (root._newExpandIndex !== -1)
flickable.expand()
}
}
......@@ -687,91 +809,4 @@ FocusScope {
from: 0
}
}
PropertyAnimation {
id: animateContentY;
target: flickable;
properties: "contentY"
}
function animateFlickableContentY( newContentY ) {
animateContentY.stop()
animateContentY.duration = VLCStyle.duration_slow
animateContentY.to = newContentY
animateContentY.start()
}
onCurrentIndexChanged: {
if (expandIndex !== -1)
retract()
positionViewAtIndex(root.currentIndex, ItemView.Contain)
}
Keys.onPressed: {
var colCount = root.getNbItemsPerRow()
var newIndex = -1
if (KeyHelper.matchRight(event)) {
if ((currentIndex + 1) % colCount !== 0) {//are we not at the end of line
newIndex = Math.min(_count - 1, currentIndex + 1)
}
} else if (KeyHelper.matchLeft(event)) {
if (currentIndex % colCount !== 0) {//are we not at the begining of line
newIndex = Math.max(0, currentIndex - 1)
}
} else if (KeyHelper.matchDown(event)) {
if (Math.floor(currentIndex / colCount) !== Math.floor(_count / colCount)) { //we are not on the last line
newIndex = Math.min(_count - 1, currentIndex + colCount)
}
} else if (KeyHelper.matchPageDown(event)) {
newIndex = Math.min(_count - 1, currentIndex + colCount * 5)
} else if (KeyHelper.matchUp(event)) {
if (Math.floor(currentIndex / colCount) !== 0) { //we are not on the first line
newIndex = Math.max(0, currentIndex - colCount)
}
} else if (KeyHelper.matchPageUp(event)) {
newIndex = Math.max(0, currentIndex - colCount * 5)
} else if (KeyHelper.matchOk(event) || event.matches(StandardKey.SelectAll) ) {
//these events are matched on release
event.accepted = true
}
if (event.matches(StandardKey.SelectAll) || KeyHelper.matchOk(event)) {
_releaseActionButtonPressed = true
} else {
_releaseActionButtonPressed = false
}
if (newIndex !== -1 && newIndex !== currentIndex) {
event.accepted = true;
var oldIndex = currentIndex;
currentIndex = newIndex;
root.selectionUpdated(event.modifiers, oldIndex, newIndex);
// NOTE: We make sure we have the proper visual focus on components.
if (oldIndex < currentIndex)
setCurrentItemFocus(Qt.TabFocusReason);
else
setCurrentItemFocus(Qt.BacktabFocusReason);
}
if (!event.accepted) {
root.Navigation.defaultKeyAction(event)
}
}
Keys.onReleased: {
if (!_releaseActionButtonPressed)
return
if (event.matches(StandardKey.SelectAll)) {
event.accepted = true
root.selectAll()
} else if ( KeyHelper.matchOk(event) ) {
event.accepted = true
root.actionAtIndex(currentIndex)
}
_releaseActionButtonPressed = false
}
}
......@@ -35,6 +35,9 @@ FocusScope {
property var fadeColor: undefined
// NOTE: We want buttons to be centered verticaly but configurable.
property int buttonMargin: height / 2 - button.height / 2
property int scrollBarWidth: scroll_id.visible ? scroll_id.width : 0
property bool keyNavigationWraps : false
......@@ -90,6 +93,9 @@ FocusScope {
property alias listScrollBar: scroll_id
property alias buttonLeft: buttonLeft
property alias buttonRight: buttonRight
// Signals
signal selectionUpdated(int keyModifiers, int oldIndex, int newIndex)
......@@ -208,7 +214,7 @@ FocusScope {
section.delegate: sectionHeading
boundsBehavior: Flickable.StopAtBounds
boundsMovement :Flickable.StopAtBounds
boundsMovement: Flickable.StopAtBounds
// NOTE: We always want a valid 'currentIndex' by default.
onCountChanged: if (count && currentIndex === -1) currentIndex = 0
......@@ -382,23 +388,34 @@ FocusScope {
}
}
// FIXME: We propbably need to upgrade these RoundButton(s) eventually. And we probably need
// to have some kind of animation when switching pages.
RoundButton {
id: leftBtn
id: buttonLeft
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
text:"<"
anchors.top: parent.top
anchors.topMargin: buttonMargin
text: '<'
visible: (view.orientation === ListView.Horizontal && !(view.atXBeginning))
onClicked: listview_id.prevPage()
visible: view.orientation === ListView.Horizontal && !view.atXBeginning
}
RoundButton {
id: rightBtn
id: buttonRight
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
text:">"
anchors.top: buttonLeft.top
text: '>'
visible: (view.orientation === ListView.Horizontal && !(view.atXEnd))
onClicked: listview_id.nextPage()
visible: view.orientation === ListView.Horizontal && !view.atXEnd
}
}