⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listmodel.c

📁 有了操作系统、TCP/IP协议栈、文件系统
💻 C
字号:
/*** $Id: listmodel.c,v 1.7 2005/01/19 05:41:06 clear Exp $**** listmodel.c: List data model.**** Copyright (C) 2004 Feynman Software.** ** Current maintainer: Zhong Shuyi (zhongsy@minigui.org).**** Create date: 2004/10/09*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "common.h"#include "minigui.h"#include "gdi.h"#include "window.h"#include "ctrl/ctrlhelper.h"#include "cliprect.h"#include "internals.h"#include "ctrlclass.h"#ifdef _CTRL_SCROLLVIEW#include "ctrlmisc.h"#include "listmodel.h"#include "scrolled.h"/* * mglist_get_sort_index : Get sort index of an item */int mglist_get_sort_index (MgList *mglst, MgItem *newci, BOOL bAdd){    list_t *me;    MgItem *pci = NULL;    int i = 0;    mglist_for_each (me, mglst) {        pci = mglist_entry (me);        if (mglst->itemCmp ((HITEM)newci, (HITEM)pci) < 0) {            if (bAdd)                list_add_tail (&newci->list, &pci->list);            return i;        }        i++;    }    if (bAdd)        list_add_tail (&newci->list, &mglst->queue);    return i;}/* * mgitem_add : add an item to the list */int mglist_add_item (MgList *mglst, MgItem *ci, MgItem* preitem,                          MgItem* nextitem, int nItem, int *idx){    int ret;    ci->flags = CTST_NORMAL;    if (mglst->iop.initItem) {        if (mglst->iop.initItem (mglst->hLst, (HITEM)ci) <0) {            return -1;        }    }    if (mglst->flags & CF_AUTOSORT && mglst->itemCmp) {        ret = mglist_get_sort_index (mglst, ci, TRUE);    }    else {        if (preitem) {            list_add (&ci->list, &preitem->list);            ret = -1;        }        else if (nextitem) {            list_add_tail (&ci->list, &nextitem->list);            ret = -1;        }        else {            ret = list_add_by_index (&ci->list, &mglst->queue, nItem);        }    }    mglst->nItemNr ++;    if (idx)        *idx = ( ret<0 ? mglst->nItemNr-1 : ret);    return 0;}int mglist_del_item (MgList *mglst, MgItem* pci){    if (mglst->iop.destroyItem) {        mglst->iop.destroyItem (mglst->hLst, (HITEM)pci);    }    list_del (&pci->list);    mglst->nItemNr --;    if (pci == mglst->pItemHilighted)        mglst->pItemHilighted = NULL;    if (pci->flags & CTST_SELECTED)        list_del (&pci->sel_list);    return 0;}intmglist_move_item (MgList *mglst, MgItem* pci, MgItem* preitem){    list_del (&pci->list);    if (preitem)        list_add_tail(&pci->list, &preitem->list);    else        list_add_tail(&pci->list, &mglst->queue);    return 0;}int mglist_adjust_items_height (HWND hWnd, MgList *mglst, PSCRDATA pscrdata, int diff){    mglst->nTotalItemH += diff;    if (mglist_is_frozen(mglst))        return 0;    scrolled_set_cont_height (hWnd, pscrdata, mglst->nTotalItemH);    scrolled_refresh_content (pscrdata);    return 0;}/* ---------------------------------------------------------------------------- */int mglist_init (MgList *mglst, HWND hWnd){    INIT_LIST_HEAD(&mglst->queue);    INIT_LIST_HEAD(&mglst->sel_queue);    mglst->nItemNr = 0;    mglst->pItemHilighted = NULL;    mglst->nTotalItemH = 0;    mglst->itemCmp = NULL;    mglst->hLst = hWnd;    mglst->flags = 0;    memset (&mglst->iop, 0, sizeof(mglst->iop));    return 0;}GET_ENTRY_BY_INDEX(mlGetItemByIndex, MgItem, list)GET_ENTRY_INDEX(mlGetItemIndex, MgItem, list)MgItem* mglist_getitem_byindex (MgList *mglst, int index){    return mlGetItemByIndex(&mglst->queue, index);}int mglist_get_item_index (MgList *mglst, MgItem *item){    return mlGetItemIndex(&mglst->queue, item);}MgItem* mglist_get_next_item (MgList *mglst, MgItem* hitem){    list_t *me = hitem ? hitem->list.next : mglst->queue.next;    return ( (me == &mglst->queue) ? 0 : mglist_entry(me) );}MgItem* mglist_get_prev_item (MgList *mglst, MgItem* hitem){    list_t *me = hitem ? hitem->list.prev : mglst->queue.prev;    return ( (me == &mglst->queue) ? 0 : mglist_entry(me) );}void mglist_hilight_item (MgList *mglst, MgItem* hitem){    if (hitem) {        MgItem* oldhitem;        oldhitem = mglst->pItemHilighted;        mglst->pItemHilighted = hitem;        mglist_select_item (mglst, hitem, TRUE);        mglist_refresh_item (mglst, (HITEM)oldhitem);        mglist_refresh_item (mglst, (HITEM)hitem);    }}DWORD mglist_get_item_adddata (HITEM hitem){    return hitem ? ((MgItem *)hitem)->addData : 0;}DWORD mglist_set_item_adddata (HITEM hitem, DWORD adddata){    DWORD old;    if (!hitem)        return 0;    old = ((MgItem *)hitem)->addData;    ((MgItem *)hitem)->addData = adddata;    return old;}void mglist_freeze (HWND hWnd, MgList *mglst, BOOL lock){    if (lock) {        mglst->flags |= MGLIST_ST_FROZEN;    }    else {        PSCRDATA pscrdata = (PSCRDATA)GetWindowAdditionalData2(hWnd);        mglst->flags &= ~MGLIST_ST_FROZEN;        scrolled_set_cont_height (hWnd, pscrdata, mglst->nTotalItemH);        //FIXME        scrolled_refresh_content (pscrdata);    }}int mglstSortItems (MgList *mglst, void* pfn, int fn_type){    MgItem *pci, *pci2;    list_t *me, *me2;    MGITEM_CMP pcmp = NULL;    MGITEM_CMP_EX pcmp_ex = NULL;    int ret;    if (fn_type == MG_CMP_TYPE_NORMAL) {        if ( !(pcmp = (MGITEM_CMP)pfn) )            return -1;    }    else if (fn_type == MG_CMP_TYPE_EX) {        if ( !(pcmp_ex = (MGITEM_CMP_EX)pfn) )            return -1;    }    else        return -1;    mglist_for_each (me, mglst) {        pci = mglist_entry (me);        pci2 = NULL;        ret = 0;        mglist_for_each (me2, mglst) {            if (me == me2)                break;            pci2 = mglist_entry (me2);            if (pcmp)                ret = pcmp ((HITEM)pci, (HITEM)pci2);            else                ret = pcmp_ex (mglst, (HITEM)pci, (HITEM)pci2);            if (ret < 0)                break;        }        if (ret < 0) {            me = me->prev;            mglist_move_item (mglst, pci, pci2);        }    }    return 0;}int mglist_sort_items (MgList *mglst, void* pfn, int fn_type){    int ret;    mglist_freeze (mglst->hLst, mglst, TRUE);    ret = mglstSortItems (mglst, pfn, fn_type);    mglist_freeze (mglst->hLst, mglst, FALSE);    return ret;}void mglist_refresh_item (MgList *mglst, HITEM hitem){    RECT rcItem;    if (!hitem || mglst->flags & MGLIST_ST_FROZEN)         return;    mglst->iop.getRect (mglst->hLst, hitem, &rcItem, TRUE);    InvalidateRect (mglst->hLst, &rcItem, TRUE);}void mglist_redraw_item (MgList *mglst, HITEM hivi){    RECT rcItem;    HDC hdc = GetClientDC (mglst->hLst);    if (!hivi)         return;    mglst->iop.getRect (mglst->hLst, hivi, &rcItem, TRUE);    mglst->iop.drawItem (mglst->hLst, hivi, hdc, &rcItem);    ReleaseDC (hdc);}BOOL mglist_make_item_visible (MgList *mglst, PSCRDATA pscrdata, HITEM hitem){    int pos_x, pos_y;    RECT rcItem;    int ret;    if (!hitem) return FALSE;    ret = mglst->iop.getRect (mglst->hLst, hitem, &rcItem, FALSE);    if (ret < 0)        return FALSE;    else if (ret == 1) { /* make y pos visible */        pos_x = -1;    }    else { /* x/y all visible */        pos_x = (rcItem.left >= pscrdata->nContX) ? rcItem.right : rcItem.left;    }    pos_y = (rcItem.top >= pscrdata->nContY) ? rcItem.bottom : rcItem.top;    return scrolled_make_pos_visible (mglst->hLst, pscrdata, pos_x, pos_y);}/* -------------------------------------------------------------------------- */SVITEM_DRAWFUNC mglist_set_itemdraw (MgList *mglst, SVITEM_DRAWFUNC draw_func){    SVITEM_DRAWFUNC oldfn;    oldfn = mglst->iop.drawItem;    mglst->iop.drawItem = draw_func;//FIXME, repaint ?    return oldfn;}void mglist_set_itemops (MgList *mglst, PMGITEMOPS iop){    mglst->iop = *iop;}int DefaultItemViewProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam,                          PSCRDATA pscrdata, MgList *mglst){    switch (message) {    case MSG_RBUTTONDOWN:    case MSG_LBUTTONDOWN:    {        int mouseY = HISWORD (lParam);        int mouseX = LOSWORD (lParam);        int nItem;        RECT rcVis;        MgItem *hitem;        if ( !mglst->iop.isInItem )            break;        scrolled_get_visible_rect (pscrdata, &rcVis);        /* not in the visible area */        if (!PtInRect (&rcVis, mouseX, mouseY))            break;        scrolled_window_to_content (pscrdata, &mouseX, &mouseY);        if ( (nItem = mglst->iop.isInItem(mglst, mouseX, mouseY, &hitem, NULL)) >= 0 ) {            NotifyParentEx (hWnd, GetDlgCtrlID(hWnd), SVN_CLICKED, (DWORD)hitem);            if (!mglist_is_item_hilight(mglst, hitem)) {                mglist_hilight_item (mglst, hitem);                mglist_make_item_visible (mglst, pscrdata, (HITEM)hitem);                NotifyParentEx (hWnd, GetDlgCtrlID(hWnd), SVN_SELCHANGED, (DWORD)hitem);            }            /* FIXME: should we auto-select the item? */            //mglist_select_item (mglst, hitem, TRUE);        }        break;    }    case MSG_FREEZECTRL:        mglist_freeze (hWnd, mglst, wParam);        return 0;    case SVM_SETITEMDRAW:        return (int)mglist_set_itemdraw (mglst, (SVITEM_DRAWFUNC)lParam);    case SVM_SETITEMINIT:    {        SVITEM_INITFUNC old_pfn;        old_pfn = mglst->iop.initItem;        mglst->iop.initItem = (SVITEM_INITFUNC)lParam;        return (int)old_pfn;    }    case SVM_SETITEMDESTROY:    {        SVITEM_DESTROYFUNC old_pfn;        old_pfn = mglst->iop.destroyItem;        mglst->iop.destroyItem = (SVITEM_DESTROYFUNC)lParam;        return (int)old_pfn;    }    case SVM_GETITEMADDDATA:    {        if (lParam)            return mglist_get_item_adddata(lParam);        else {            HITEM hitem = (HITEM)mglist_getitem_byindex(mglst, wParam);            return mglist_get_item_adddata(hitem);        }    }    case SVM_SETITEMADDDATA:    {        HITEM hitem = (HITEM)mglist_getitem_byindex(mglst, wParam);        mglist_set_item_adddata (hitem, lParam);        return 0;    }    case SVM_REFRESHITEM:    {        if (lParam)            mglist_refresh_item (mglst, (HITEM)lParam);        else {            HITEM hitem = (HITEM) mglist_getitem_byindex(mglst, wParam);            mglist_refresh_item (mglst, hitem);        }        return 0;    }    case SVM_SETITEMOPS:        *(SVITEMOPS*)&mglst->iop = *(SVITEMOPS*)lParam;        //mglist_set_itemops ((MgList *)&psvdata->svlist, (SVITEMOPS*)lParam);        return 0;    case SVM_GETCURSEL:        return mglist_get_item_index(mglst, mglist_get_hilighted_item(mglst));    case SVM_SETCURSEL:    {        HITEM hitem = (HITEM)mglist_getitem_byindex(mglst, wParam);        if (hitem) {            //FIXME, should we automatically refresh hilighted item ?            //mglist_set_hilighted_item (mglst, (MgItem *)hitem);            mglist_hilight_item (mglst, (MgItem *)hitem);            // make this item visible            if (lParam)                mglist_make_item_visible (mglst, pscrdata, hitem);        }        return 0;    }    case SVM_SHOWITEM:    {        if (lParam)            mglist_make_item_visible (mglst, pscrdata, (HITEM)lParam);        else {            HITEM hitem = (HITEM)mglist_getitem_byindex(mglst, wParam);            mglist_make_item_visible (mglst, pscrdata, hitem);        }        return 0;    }    case SVM_SELECTITEM:    {        HITEM hitem = (HITEM)mglist_getitem_byindex(mglst, wParam);        if (hitem) {            mglist_select_item (mglst, (MgItem *)hitem, lParam);        }        return 0;    }    case SVM_CHOOSEITEM:    {        HITEM hitem;        if (lParam)            hitem = (HITEM)lParam;        else            hitem = (HITEM)mglist_getitem_byindex(mglst, wParam);        mglist_select_item (mglst, (MgItem *)hitem, TRUE);        mglist_make_item_visible (mglst, pscrdata, hitem);        return 0;    }    case SVM_SETITEMCMP:    {        SVITEM_CMP oldcmp = mglst->itemCmp;        mglst->itemCmp = (SVITEM_CMP)lParam;        return (int)oldcmp;    }    case SVM_SORTITEMS:    {        SVITEM_CMP pfn = (SVITEM_CMP)lParam;         if (mglist_sort_items (mglst, (void*)pfn, MG_CMP_TYPE_NORMAL) == 0) {            //FIXME, need ?            InvalidateRect (hWnd, NULL, TRUE);        }        return 0;    }    case SVM_GETITEMCOUNT:        return mglist_get_item_count(mglst);    }/* end switch */    return DefaultScrolledProc (hWnd, message, wParam, lParam);}/* -------------------------------------------------------------------------- */#endif /* _CTRL_SCROLLVIEW */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -