亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Duilib中帶有權(quán)重的靈活控件排列實現(xiàn)(一)

2019-11-10 20:24:37
字體:
供稿:網(wǎng)友
在開發(fā)播放器軟件過程中,因為窗口的大小是可變的,為了讓控制欄部分的控件(播放,上一集,下一集,全屏,字幕等)適應(yīng)窗口的尺寸的變化而顯示隱藏,產(chǎn)品經(jīng)理會定義一系列的規(guī)則,好讓在任何時候都最核心的功能提供給用戶使用。先列一下產(chǎn)品經(jīng)理給予的需求:兩邊往中間縮,保證左側(cè)LOGO和右側(cè)X最優(yōu)先顯示。頂部隱藏優(yōu)先級:搜索欄,換膚,意見反饋,播放記錄,最小化,最大化底部隱藏優(yōu)先級:全屏,畫質(zhì)增強,無痕,打開文件,播放順序,音量條在處理這個需求過程中,前人也嘗試了一些方法,比較通過全float絕對布局的方式,自己通過管理類來完全訂制。而我個人還是希望通過而優(yōu)雅的相對布局,并利用Container自身的排布算法來實現(xiàn)。經(jīng)過幾天的探索,大致實現(xiàn)上這種效果,在此分享一下思路與實現(xiàn)。在分析此需求時,我希望引來類似于第3維的權(quán)重(weight)概念,即當(dāng)父容器所提供的位置不足于將所有子控件擺放顯示完全時,就按照重要性自低到高依次隱藏,將該控件的顯示騰出來提供給更為重要的控件來擺放,簡單推演一下,應(yīng)該是可行的,按照這樣簡單的規(guī)則,可以比較輕松地解決這個需求,并且代碼維護起來相對簡單。只需要一個能夠按照子控件的weight值來排列的父容器,命名為CWeightHorizontalLayoutUI。OK,讓我們來實現(xiàn)這個父容器,首先我介紹一下 CHorizontalLayoutUI::SetPos的方法。其實就是兩次for循環(huán),前一次來試算,將沒有設(shè)置寬度的控件記錄下來,將剩余的空間求個平均數(shù),設(shè)置給自適應(yīng)的控件,而設(shè)置了寬度的控件則按設(shè)置的值排布。
    void CWeightHorizontalLayoutUI::SetPos(RECT rc)    {        CControlUI::SetPos(rc);        rc = m_rcItem;        std::map<CControlUI*, int /*width*/> mapAjust;        // Adjust for inset        rc.left     += m_rcInset.left;        rc.top      += m_rcInset.top;        rc.right    -= m_rcInset.right;        rc.bottom   -= m_rcInset.bottom;        if (m_items.GetSize() == 0) {            PRocessScrollBar(rc, 0, 0);            return;        }        if (!m_bScrollFloat && m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible())             rc.right -= m_pVerticalScrollBar->GetFixedWidth();        if (!m_bScrollFloat && m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible())             rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();        ResetWeightDisplayControlState(); //  讀取當(dāng)前子控件的權(quán)重        m_mapWeight.clear();        for (int i = 0; i < m_items.GetSize(); i++) {            DuiLib::CControlUI* pControl = static_cast<DuiLib::CControlUI*>(m_items[i]);            if (pControl == nullptr) continue;            CStdString strweight = pControl->GetCustomAttribute(L"weight");            int nweight = _ttoi(strweight.GetData());            m_mapWeight[i] = nweight;        }        m_mapWeightCache = m_mapWeight;        // 查找最小權(quán)重控件          auto HideMinWeigth = [&](int index) -> bool {            CControlUI* pControl = static_cast<CControlUI*>(m_items[index]);            if (pControl && pControl->IsVisible()) {                pControl->SetInternVisible(false);                m_arrWeightHideControl.push_back(pControl);                return true;            }            return false;        };        // Determine the width of elements that are sizeable        SIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top };        if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible())            szAvailable.cx += m_pHorizontalScrollBar->GetScrollRange();        int nAdjustables = 0;        int cxFixed = 0;        int nEstimateNum = 0;        int cxExpand = 0;        std::pair<int, int> min_weight; // first:control index, second:weight        std::map<CControlUI*, int /*width*/> m_mapEstimateWidth;  // 試算時控件的預(yù)設(shè)寬度        std::map<CControlUI*, int /*width*/> m_mapBookWidth;        do {            // 查找出當(dāng)前權(quán)重值最小,并且顯示著的控件            min_weight = std::make_pair(999, 999);            std::for_each(m_mapWeight.begin(), m_mapWeight.end(), [&](std::pair<int, int> item)-> void {                CControlUI* pControl = static_cast<CControlUI*>(m_items[item.first]);                if (item.second <= min_weight.second && pControl->IsVisible())                    min_weight = item;            });            // 已經(jīng)找到后從map中移除,以避免下次查找的還是這個控件            auto min_it = std::find_if(m_mapWeight.begin(), m_mapWeight.end(), [min_weight](std::pair<int, int> item)-> bool {                return (item.first == min_weight.first && item.second == item.second);            });            if (min_it != m_mapWeight.end()) m_mapWeight.erase(min_it);            // 試算中            nAdjustables = 0;            cxFixed = 0;            nEstimateNum = 0;            for (int it1 = 0; it1 < m_items.GetSize(); it1++) {                CControlUI* pControl = static_cast<CControlUI*>(m_items[it1]);                if (pControl->IsFloat()) continue;                if (!pControl->IsVisible()) continue;                SIZE sz = pControl->EstimateSize(szAvailable);                if (sz.cx == 0) {                                                         nAdjustables++;                }                else {                    if (sz.cx < pControl->GetMinWidth()) sz.cx = pControl->GetMinWidth();                    if (sz.cx > pControl->GetMaxWidth()) sz.cx = pControl->GetMaxWidth();                }                m_mapEstimateWidth[pControl] = sz.cx;                cxFixed += sz.cx + pControl->GetPadding().left + pControl->GetPadding().right;                nEstimateNum++;            }            cxFixed += (nEstimateNum - 1) * m_iChildPadding;            cxExpand = 0;            if (nAdjustables > 0) cxExpand = max(0, (szAvailable.cx - cxFixed) / nAdjustables);// 此處下節(jié)解釋            // 如果小于空間不夠,先嘗試從低到高縮減帶有adjust屬性的控件            if (szAvailable.cx - cxFixed < 0) {                std::vector<std::pair<CControlUI*, int>> adj_ctrls;                for (int it1 = 0; it1 < m_items.GetSize(); it1++) {                    CControlUI* pControl = static_cast<CControlUI*>(m_items[it1]);                    if (pControl->IsFloat()) continue;                    //if (!pControl->IsVisible()) continue;                    if (pControl->GetCustomAttribute(L"adjustwidth") == NULL ||                        _tcscmp(pControl->GetCustomAttribute(L"adjustwidth"), L"true")) continue;                    adj_ctrls.push_back(std::make_pair(pControl, m_mapWeightCache[it1]));                }                // 自小到大按權(quán)重,先嘗試最小權(quán)重                std::sort(adj_ctrls.begin(), adj_ctrls.end(), [&](std::pair<CControlUI*, int> lhs,                    std::pair<CControlUI*, int> rhs) -> bool {                    return lhs.second < rhs.second;                });                             for (auto it = adj_ctrls.begin(); it != adj_ctrls.end(); it++) {                    auto ctrl = it->first;                    if (m_mapEstimateWidth[ctrl] > ctrl->GetMinWidth()) {                        int sub_width = min(abs(szAvailable.cx - cxFixed), m_mapEstimateWidth[ctrl] - ctrl->GetMinWidth());                        m_mapEstimateWidth[ctrl] = m_mapEstimateWidth[ctrl] - sub_width;    // 新的試算寬度                         m_mapBookWidth[ctrl] = m_mapEstimateWidth[ctrl];                        cxFixed -= sub_width;                        if (szAvailable.cx - cxFixed >= 0) break; // 已經(jīng)滿足排列空間                    }                                    }            }            // 空間不夠,從權(quán)重最小的依次隱藏        } while (szAvailable.cx - cxFixed < 0 && HideMinWeigth(min_weight.first));        // Position the elements        SIZE szRemaining = szAvailable;        int iposX = rc.left;        if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible()) {            iPosX -= m_pHorizontalScrollBar->GetScrollPos();        }        int iAdjustable = 0;        int cxFixedRemaining = cxFixed;        for (int it2 = 0; it2 < m_items.GetSize(); it2++) {            CControlUI* pControl = static_cast<CControlUI*>(m_items[it2]);            if (!pControl->IsVisible()) continue;            if (pControl->IsFloat()) {                SetFloatPos(it2);                continue;            }            RECT rcPadding = pControl->GetPadding();            szRemaining.cx -= rcPadding.left;            SIZE sz = pControl->EstimateSize(szRemaining);            if (sz.cx == 0) {                iAdjustable++;                sz.cx = cxExpand;                //最后一個自適應(yīng)尺寸大小無需另行計算                //if( iAdjustable == nAdjustables ) {                //	sz.cx = MAX(0, szRemaining.cx -cxFixedRemaining);                //}                if (sz.cx < pControl->GetMinWidth()) sz.cx = pControl->GetMinWidth();                if (sz.cx > pControl->GetMaxWidth()) sz.cx = pControl->GetMaxWidth();            }            else {                if (sz.cx < pControl->GetMinWidth()) sz.cx = pControl->GetMinWidth();                if (sz.cx > pControl->GetMaxWidth()) sz.cx = pControl->GetMaxWidth();            }            sz.cy = pControl->GetFixedHeight();            if (sz.cy == 0) sz.cy = rc.bottom - rc.top - rcPadding.top - rcPadding.bottom;            if (sz.cy < 0) sz.cy = 0;            if (sz.cy < pControl->GetMinHeight()) sz.cy = pControl->GetMinHeight();            if (sz.cy > pControl->GetMaxHeight()) sz.cy = pControl->GetMaxHeight();            //padding不算控件寬度//2012/09/12            //RECT rcCtrl = { iPosX + rcPadding.left, rc.top + rcPadding.top, iPosX + sz.cx + rcPadding.left + rcPadding.right, rc.top + rcPadding.top + sz.cy};            if (m_mapBookWidth.find(pControl) != m_mapBookWidth.end() &&                m_mapBookWidth[pControl] != sz.cx) {                sz.cx = m_mapBookWidth[pControl];            }            RECT rcCtrl = { iPosX + rcPadding.left, rc.top + rcPadding.top, min(iPosX + sz.cx + rcPadding.left, rc.right) , rc.top + rcPadding.top + sz.cy };            pControl->SetPos(rcCtrl);            iPosX += sz.cx + m_iChildPadding + rcPadding.left + rcPadding.right;            szRemaining.cx -= sz.cx + m_iChildPadding + rcPadding.right;            if (m_bWholeDisplay && rcCtrl.right > rc.left + szAvailable.cx)                m_arrWholeDisplayControl.push_back(pControl);        }        // Process the scrollbar        ProcessScrollBar(rc, 0, 0);    }以上代碼主要是在試算過程中,在剩余的空間寬度不足時隱藏一下最小的權(quán)重控件,再次試算一遍需要留心的是當(dāng)Hide時不能夠直接調(diào)用子控件的SetVisible接口,這樣會改變控件的基礎(chǔ)狀態(tài),而應(yīng)使用SetInternVisible,并且在再次SetPos時,清除這樣的記錄,并將狀態(tài)重置,這樣,不影響再次的試算過程?;疽陨蠈崿F(xiàn)了控制欄的自定義隱藏順序。而我們只需要在xml文件中配置一下各個控件的權(quán)重即可。實現(xiàn)效果:
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
国产极品嫩模在线视频一区| 亚洲欧美国产日韩综合| 国产亚洲精品久久久| 欧美在线视频在线播放完整版免费观看| 一本到高清视频免费精品| 国产熟女一区二区| 久久国产美女视频| 精品一区二区三区影院在线午夜| www青青草原| 亚洲天堂男人天堂女人天堂| 欧美激情一区二区三区成人| 日本a视频在线观看| 超碰在线电影| 久久久青草青青国产亚洲免观| 国产人成视频在线观看| caoporn国产精品| 国产精品996| 伦伦影院午夜理论片| 国产免费不卡| 天天躁日日躁狠狠躁免费麻豆| 国产欧美久久久| 5月婷婷6月丁香| 一区二区三区www| 国产h视频在线播放| 国产成人一区二区在线| 亚洲精品97久久中文字幕| 欧美放荡的少妇| 亚洲一级av毛片| 伊人国产在线看一| 久久福利电影| 久久福利视频一区二区| 日韩视频在线一区二区| 国内外成人免费激情在线视频| 欧美日韩亚洲国产成人| a级黄色毛片| 欧美涩涩网站| 丰满人妻妇伦又伦精品国产| 欧美成人精品激情在线观看| 中日韩高清电影网| 成人免费看吃奶视频网站| 在线黄色.com| 免费一级黄色录像| 久久久精品视频国产| 精品无码久久久久久久动漫| 久久久精品国产sm调教网站| 成人网站免费观看入口| 欧美77777| 人妻无码视频一区二区三区| 成人性生交视频免费观看| 神马影视一区二区| 手机在线理论片| 日韩精品三级| 国产四区在线观看| 久久日文中文字幕乱码| 国产精品视频无码| 日韩视频免费观看高清在线视频| 一区二区免费在线观看| 久久精品无码一区二区三区| 欧美视频在线免费播放| 丁香花五月婷婷| 亚洲免费av一区二区| 亚洲人成在线电影| 国产成人午夜99999| 中文字幕精品—区二区四季| 亚洲精品一区二区三区精华液| 丁香高清在线观看完整电影视频| 欧美日韩视频在线| 在线观看免费网站| 国产又大又硬又粗| 热99精品只有里视频精品| 欧美日韩国产限制| 日韩午夜激情视频| 欧美欧美全黄| 久久天天躁狠狠躁夜夜躁2014| 欧美深深色噜噜狠狠yyy| 国产精品一页| 成人国产视频在线观看| 北条麻妃69av| 四虎影在永久在线观看| 亚洲欧美日韩精品在线| 国产视频福利| 精品国产99久久久久久| 亚洲男人天堂2024| 日本精品一区二区三区四区| 国产卡一卡2卡三卡免费视频| 精品按摩偷拍| 欧美天堂在线观看| 不许穿内裤随时挨c调教h苏绵| 欧美 日韩 亚洲 一区| 精品视频无码一区二区三区| 麻豆精品久久精品色综合| 日韩黄色中文字幕| 欧美精品久久一区二区| 久久久久久久国产视频| www.精品av.com| 一区二区三区四区在线视频| 国产一区二区三区精品在线| 性生活视频网址| 国产精品成人一区二区三区吃奶| 精品黑人一区二区三区| 国产成人福利片| 99精品国产在热久久下载| 91成人免费观看网站| 英国三级经典在线观看| 最近中文字幕在线中文视频| 小说区图片区综合久久88| wwwwww色| 亚洲精品高清国产一线久久| 亚洲第一男人天堂| 国产精品成人一区二区三区吃奶| 亚洲精品乱码久久久久久动漫| 精品呦交小u女在线| 久久精品2019中文字幕| 一区二区在线观看免费视频| 日韩不卡在线| 一个人www视频在线免费观看| 亚洲综合网站在线观看| 欧美wwwwxxxx| 美国美女黄色片| 污网站免费在线观看| аⅴ资源天堂资源库在线| 日韩精品在线播放| 中文字幕在线播放网址| 亚洲欧美精品中文字幕在线| 亚洲视频资源| 国产成人精品免费视| 97超碰资源站在线观看| 一区二区成人在线观看| 五月天婷婷色综合| 女性隐私黄www网站视频| 欧美一区二区在线视频观看| 亚洲五月天综合| 欧美午夜网站| 性高爱久久久久久久久| 国产视频1区2区3区| 日韩手机在线观看视频| 全部免费的黄色毛片| 免费在线观看成人| 亚洲 欧美 视频| 国产午夜精品理论片在线| 欧美有码在线观看| 在线观看亚洲精品福利片| 国产传媒在线| www.豆豆成人网.com| 狠狠色丁香婷综合久久| 女人被爽到呻吟gif动态图下载| 精品国产31久久久久久| 露脸国产精品自产在线播| 男人用嘴添女人下身免费视频| 精品人妻一区二区三区四区在线| 69久久精品| 一本一道久久a久久精品综合蜜臀| 国产伦精品一区二区三区88av| 国产全是老熟女太爽了| 欧美日韩性生活视频| 亚洲综合色网站| 在线视频中文字幕一区二区| 国产视频精品va久久久久久| 婷婷亚洲婷婷综合色香五月| 久久综合国产精品台湾中文娱乐网| 国产福利电影一区二区三区| 黄色在线网站噜噜噜| 青娱乐av在线| 国产精品一区在线播放| 夜色激情一区二区| 97在线免费观看视频| 国产视频在线观看视频| 男人的天堂久久| 中文字幕在线观看网站| 国产99久久久久久免费看| 国产一级二级三级精品| 激情文学综合| 一本加勒比波多野结衣| 亚洲影院理伦片| 亚洲成人av中文| 久久影院午夜精品| av女人的天堂| 欧美专区一二三| 狠狠躁少妇一区二区三区| 国产精品人人爱一区二区白浆| 中字幕一区二区三区乱码| 亚洲级视频在线观看免费1级| 日本免费中文字幕在线| 一区二区三区视频| 亚洲免费电影一区| 亚洲天堂电影| 97se亚洲国产综合自在线| 欧美性生交大片免费| 国产精品久久国产愉拍| 亚洲高清乱码| 日韩免费高清视频网站| 1769国产精品视频| 色天天综合久久久久综合片| 久久99高清| 婷婷亚洲婷婷综合色香五月| 91丨九色丨国产在线| 欧美网站免费观看| 国产亚洲欧洲一区高清在线观看| 特大巨黑人吊性xxx视频| 深夜福利网址| 亚洲视频小说| 亚洲91网站| 鲁鲁视频www一区二区| 亚洲国产国产| 国产在线观看中文字幕| 99re热视频这里只精品| 国产成人精品免费| 无码人妻少妇伦在线电影| 青草视频在线播放| 国产欧美日韩中文字幕在线| 精品福利网址导航| 亚洲欧美日韩精品久久| 亚洲aaa级| 国产精品久久久久久影院8一贰佰| 亚洲五码在线| 色欧美在线观看| 美国毛片一区二区| 性活交片大全免费看| 国内精品视频| 麻豆成人在线播放| 亚洲激精日韩激精欧美精品| 在线日韩av观看| 永久免费看片在线观看| av综合在线观看| 可以看污的网站| 亚洲欧美日韩在线播放| 亚洲一二三专区| 精品国产成人av| 国产欧美在线观看| 国产精品一区二区在线观看网站| 伊人久久久久久久久久久久| 国产一区二区成人久久免费影院| 欧美日韩一区 二区 三区 久久精品| 久久成人免费电影| 性色av一区二区三区红粉影视| 亚洲一区不卡在线| 91久久精品一区| 欧美综合第一页| 久久精品一二三| xxxx.国产| 婷婷久久伊人| 亚洲私人影吧| 国产视频一区二区三区在线播放| 亚洲日本韩国一区| 欧美毛片在线观看| 亚洲免费av网址| 中文字幕午夜精品一区二区三区| 情趣视频网站在线免费观看| 99久久精品日本一区二区免费| 日本欧美三级| 亚洲一二三四| 国产精品国产三级国产专播精品人| 国产精品伦子伦免费视频| 最近免费中文字幕中文高清百度| 亚洲激情视频小说| 国产精品久久久久白浆| 亚洲女人的天堂| 亚洲一级在线观看| 2018狠狠干| 欧美激情在线精品一区二区三区| 五月婷婷中文字幕| 日本三级韩国三级久久| 国产成人无码aa精品一区| 国产偷自视频区视频一区二区| 亚洲欧美成人在线| 亚洲欧美自拍偷拍| 96精品久久久久中文字幕| 天天操夜夜操天天射| av一区二区三区四区电影| 在线观看亚洲免费视频| 中文字幕电影一区| 91精品国产入口在线| 国产亚洲欧美日韩日本| 国产网站免费在线观看| 日本黄色一区二区三区| 欧美日韩亚洲一区在线观看| 小说区视频区图片区| 国产日韩专区| 欧美极品jizzhd欧美仙踪林| 在线成人免费视频| 99自拍偷拍视频| 国产1区2区3区在线| 国产无遮挡裸体免费视频| 国产91aaa| 欧洲精品久久一区二区| 国产精品 欧美在线| 国产精品国产亚洲精品看不卡15| 91在线视频观看免费| 欧美精品videosex| a级片在线免费观看| 久久久av毛片精品| 亚洲国产一区二区三区在线播| 国产精品嫩草99av在线| 久久在线免费观看| 久久国产精品视频在线观看| 国产特级淫片高清视频| 亚洲欧美日本免费| 亚洲无码精品在线观看| 黄色在线网站噜噜噜| 欧美在线性视频| 国产一区二区看久久| 国产综合内射日韩久| 九九热精品免费视频| 精品免费久久久| 丁香花在线高清完整版视频| 成人高清免费观看mv| 中文字幕在线免费专区| 热99这里只有精品| 4444亚洲人成无码网在线观看| 欧美第十八页| 国产你懂的在线观看| 亚洲欧美在线高清| 久久久99免费视频| 美女扒开腿让男人桶爽久久软| 国产经典一区二区| 国产日韩欧美精品电影三级在线| 丁香视频五月| 欧美怡红院视频一区二区三区| 久久视频中文字幕| 欧美18—19性高清hd4k| 新久草在线视频| www.一区二区.com| 久久人体做爰大胆| 亚洲免费资源在线播放| 日韩有码视频在线| 81精品国产乱码久久久久久| 中文字幕日本乱码精品影院| 高清视频一区二区三区四区|