开源桌面系统及设计图、下载地址

原创
2016/02/17 14:10
阅读数 622

开源桌面系统,极简单的mvc设计、数据绑定实现、微事件实现等等。

下载地址:http://git.oschina.net/eternal_rider/sapling/attach_files

设计如下图:

Controller.js

var DtController={
	cache:{}, 
	pubevt:function (topic,args,context) {
		var evtcontext = context || window,
		subs = evtcontext.DtController.cache[topic],
		len = subs ? subs.length : 0;
		while (len--) {
		  subs[len].apply(evtcontext, args || []);
		}
	},
	subevt:function (topic,callback) {
		if (!DtController.cache[topic]) {
		  DtController.cache[topic] = [];
		}
		DtController.cache[topic].push(callback);
		return [topic, callback]; 
	},
	unsubevt:function (handle,callback) {
		var subs = DtController.cache[callback ? handle : handle[0]],
		callback = callback || handle[1],
		len = subs ? subs.length : 0;
		while (len--) {
			if (subs[len] === callback) {
			subs.splice(len, 1);
			}
		}
	},
	bindmodel:function(model,callback){
		Object.observe(model, callback);
	},
	init:function(){
		DtController.subevt('/dtname/set',DtModel.setDtname);
		DtController.subevt('/alias/set',DtModel.setAlias);
		DtController.subevt('/theme/set',DtModel.setTheme);
		DtController.subevt('/wallpaper/set',DtModel.setWallpaper);
		DtController.subevt('/mm/load',DtModel.loadMenu);
		DtController.subevt('/mm/app/set',DtModel.setApp);
		DtController.subevt('/app/xy/set',DtModel.setAppXY);
		DtController.bindmodel(DtModel,function(data){
			data.forEach(function(item, i){
				switch(item.name){
					case 'theme':
						DtView.setTheme(item.object[item.name]);
						break;
					case 'wallpaper':
						DtView.setWallpaper(item.object[item.name]);
						break;
					case 'alias':
						DtView.setAlias(item.object[item.name]);
						break;
					case 'dtname':
						DtView.setDtname(item.object[item.name]);
						break;
					case 'menus':
						DtView.setMenus(item.object[item.name]);
						break;
					case 'apps':
						DtView.setApps(item.object[item.name].list);
						break;
				};
				//console.log(change.type, change.name, change.oldValue);
				DtView.setNotifications('监听到DtModel中' + item.name+',触发'+ item.type+'事件');
			});
		});
		DtController.pubevt('/mm/load',[]);
		var urlstr=window.location.href,
		username=urlstr.substr(urlstr.indexOf("?")+1);
		DtModel.setUserName(username);
		DtView.init();
	}
};



model.js

var DtModel = {
	dtname:"",
	username:"",
	alias:"",
	theme:"",
	wallpaper:{},
	menus:{},
	apps:{},
	storage:window.localStorage,
	loadMenu:function(){
		//初始化开始菜单和邮件菜单
		$.getJSON("assets/menu.json", function(data) {
			if (data) {
				var mm_tmp = [],app_tmp = [];
				$(data.menu).each(function(i, item) {
					mm_tmp.push(item);
				});
				$(data.app).each(function(i, item) {
					app_tmp.push(item);
				});
				var obj = {mm:mm_tmp,app:app_tmp};
				DtModel.menus = obj;
				DtModel.load();
			}
		});
		
		//初始化桌面布局菜单
		
	},
	setDtname:function(name){
		DtModel.dtname = name;
		DtModel.save();
	},
	setUserName:function(username){
		DtModel.username = username;
	},
	setAlias:function(alias){
		DtModel.alias = alias;
		DtModel.save();
	},
	setTheme:function(theme){
		DtModel.theme = theme.colors;
		DtModel.save();
	},
	setWallpaper:function(data){
		DtModel.wallpaper = data;
		DtModel.save();
	},
	setApp:function(id){
		var list = $.extend([],DtModel.apps.list || []);
		$.each(list, function(i,data){
			if(data.id == id){
				list[i].state = list[i].state ==0?1:0;
				id = "-1";
				return false;
			}
		});
		
		if(id != "-1"){
			$.each(DtModel.menus.app, function(i,data){
				if(data.id == id){
					data.state = 1;
					list.push(data);
					return false;
				}
			});
		}

		DtModel.apps = {list:list};
		DtModel.save();
	},
	setAppXY:function(id,x,y){
		$.each(DtModel.apps.list, function(i,data){
			if(data.id == id){
				DtModel.apps.list[i].x=x,DtModel.apps.list[i].y=y;
				return false;
			}
		});
		DtModel.apps = {list:DtModel.apps.list};
		DtModel.save();
	},
    save:function(){
        if(DtModel.storage) {
			var data = {};
			data.dtname = DtModel.dtname;
			data.username = DtModel.username;
			data.alias = DtModel.alias;
			data.theme=DtModel.theme;
			data.wallpaper = DtModel.wallpaper;
			data.apps=DtModel.apps;
            DtModel.storage.sapling = JSON.stringify(data);
			//通过websocket保存到服务器
        }else{
            alert('不支持LocalStorage');
        }
    },
    load:function(){
        if(DtModel.storage) {
			if(DtModel.storage.sapling){
				var data = JSON.parse(DtModel.storage.sapling);
				DtModel.dtname = data.dtname;
				DtModel.username = data.username;
				DtModel.alias = data.alias ? data.alias:data.username;
				DtModel.theme = data.theme;
				DtModel.wallpaper = data.wallpaper;
				DtModel.apps = data.apps;
			}else{
				DtModel.alias = DtModel.username;
			}
        }else{
            alert('不支持LocalStorage');
        }
    }
}



view.js

var DtView = {
	"init":function(){
		setInterval(function() {
			var time = new Date();
			$("#time").html(time.toLocaleTimeString());
		}, 1000);
		
		using('calendar',function(){
			$('#calendar').calendar({
				firstDay:1,
				width:250,
				height:250
			});
		});
		using('textbox',function(){
			$('#dt_name').textbox({
				onClickButton:function(){
					var text = $('#dt_name').textbox('getText');
					if(text){
						DtController.pubevt('/dtname/set',[text]);
					}
				}
			});
			$('#alias').textbox({
				onClickButton:function(){
					var text = $('#alias').textbox('getText');
					if(text){
						DtController.pubevt('/alias/set',[text]);
					}
				}
			});
		});
		
		$("#start").mouseenter(function(e) {
			e.preventDefault();
			$(this).attr("src", "assets/ima/2.jpg");
			using("menu", function() {
				$('#startmm').menu('show', {
					left : 0,
					top : 40
				});
			});
		}).mouseleave(function() {
			$(this).attr("src", "assets/ima/1.jpg");
		});
		$('#dock').on('click','li',function(ev){
			var target = $(this).find('a').attr('href');
			if($(target).dialog('options').minimized){
				$(target).dialog('open');
			}else{
				$(target).dialog('minimize');
			}
			ev.preventDefault();
			ev.stopPropagation();
		});

		$('#user').mouseenter(function(ev){
			ev.preventDefault();
			ev.stopPropagation();
			$('#calendar').hide();
			$('#user_panel').fadeIn();
		});
		$('#user_panel').mouseleave(function() {
			$('#user_panel').fadeOut();
		});
		
		$('#time').mouseenter(function(ev){
			ev.preventDefault();
			ev.stopPropagation();
			$('#user_panel').hide();
			$('#calendar').fadeIn();
		});
		$('#calendar').mouseleave(function() {
			$('#calendar').fadeOut();
		});
		
		$('#desktop,#task_bar').on('contextmenu',function(e){
			e.preventDefault();
			var target=e.target||e.srcElement;
			var tid = $(target).attr('id');
			if(tid == 'desktop'){
				using("menu", function() {
					$('#mm-setup').menu('show', {
						left: e.pageX,
						top: e.pageY
					});
				});
			}else if(tid == 'task_bar'){
				alert('任务栏的右键事件');
			}else{
				return false;
			}
		});
		$('#setup_app').on('click','li',function(ev){
			DtController.pubevt('/mm/app/set',[$(this).attr('id')]);
			ev.preventDefault();
			ev.stopPropagation();
		});
		$('#user_blog').on('click',function(ev){
			ev.preventDefault();
			ev.stopPropagation();
			DtView.dialogHandler({
				"id":"myblog",
				"title":"作者博客",
				"link":"http://my.oschina.net/eternal/blog",
				"load":"iframe",
				"icon":"world",
				"width":1280,
				"height":685
			});
		});
		$('#user_about').on('click',function(ev){
			ev.preventDefault();
			ev.stopPropagation();
			DtView.dialogHandler({
				"id":"aboutme",
				"title":"关于作者",
				"link":"apps/about/index.html",
				"load":"iframe",
				"icon":"user",
				"maximized":true
			});
		});
		$('#help_user').on('click',function(ev){
			ev.preventDefault();
			ev.stopPropagation();
			DtView.dialogHandler({
				"id":"helpme",
				"title":"随便给点吧",
				"link":"apps/helpme/index.html",
				"load":"iframe",
				"icon":"heart",
				"maximized":true
			});
		});
		$('#wallpapers_mm').on('click',function(ev){
			ev.preventDefault();
			ev.stopPropagation();
			DtView.dialogHandler({
				"id":"wallpapers",
				"title":"桌面壁纸",
				"link":"apps/wallpaper/index.html",
				"load":"iframe",
				"icon":"customization",
				"width":1280,
				"height":685
			});
		});
		$('#logout').on('click',function(ev){
			ev.preventDefault();
			ev.stopPropagation();
			if (confirm("确认退出系统吗?")==true){
				window.location.href="index.html";
			}
		});
	},
	setDtname:function(name){
		document.title = name;
		using('textbox',function(){
			$('#dt_name').textbox('setText',name);
		});
	},
	setAlias:function(name){
		$('#user').text(name);
		using('textbox',function(){
			$('#alias').textbox('setText',name);
		});
	},
	setApps:function(list){
		if(!list){
			return false;
		}
		$.each(list, function(i,data){
			var hasapp = $("#desktop").children("#dt_"+data.id).html();
			if(!hasapp){
				var app = {id:data.id,width:data.width,height:data.height,title:data.title,x:data.x,y:data.y};
				$("#dtapp_tmpl").tmpl(app).appendTo("#desktop");
				var $appi = $("<iframe border=0 frameborder=0  style='width:100%;height:100%;'  scrolling='yes' src='"+data.link+"'></iframe>");
				$("#dt_body_"+data.id).html($appi);
				
				using("draggable",function(){
					$("#dt_"+data.id).draggable({onStopDrag:function(e){
						var x = $(this).offset().left,y = $(this).offset().top-41;
						DtController.pubevt('/app/xy/set',[data.id,x,y]);
					}});
				});
			}else{
				if(data.state == 0){
					$("#desktop").children("#dt_"+data.id).remove();
				}
			}
		});
	},
	setMenus:function(menus){
		$("#startmm_tmpl").tmpl(menus.mm).appendTo("#startmm");
		using('menu',function(){
			$('#startmm').menu({
				onClick:function(item){
					DtView.menuHandler(item);
				}
			});
		});
		
		$("#app_tmpl").tmpl(menus.app).appendTo("#setup_app");
	},
	setTheme:function(theme){
		var colors = theme.split(',');
		$('#task_bar').css('background-color',colors[0]).css('border-bottom','1px solid '+colors[1]);
		$('body').css('background-color',colors[2]);
	},
	setWallpaper:function(data){
		if(data.type == 'rgb'){
			$('body').css('background',data.name);
		}else{
			$('body').css('background','#777777 url(assets/ima/'+data.name+')');
		}
	},
	setNotifications:function(content){
		var $lists = $("#user_panel_news").children(".notifications");
		if($lists.length >= 3){
			$lists[2].remove();
		}
		$("#notifications_tmpl").tmpl({content:content}).prependTo("#user_panel_news");
	},
	menuHandler:function(item) {
		var menumodel = {};
		$.each(DtModel.menus.mm, function(i,data){
		  if(data.id == item.id){
			  menumodel = data;
			  return false;
		  }
		});
		if(menumodel.id){
			DtView.dialogHandler(menumodel);
		}
	},	
	dialogHandler:function(menumodel) {
		if ($("#mm_"+menumodel.id).length > 0) {
			$("#mm_"+menumodel.id).html("");
		} else {
			$("#desktop").append("<div id='mm_"+menumodel.id+"' style='overflow: hidden;'></div>");
		}
		
		using('dialog', function() {
			var dlgconfig = {
				title:'&nbsp;'+menumodel.title,
				width:menumodel.width,
				height:menumodel.height,
				iconCls:'icon-'+menumodel.icon,
				collapsible:menumodel.collapsible||true,
				minimizable:menumodel.minimizable||true,
				maximizable:menumodel.maximizable||true,
				resizable:menumodel.resizable||true,
				draggable:menumodel.draggable||true,
				inline:true,
				shadow:true,
				maximized:menumodel.maximized||false,
				onBeforeClose:function(){
					$('#dock_'+menumodel.id).remove();
					$(this).parent().next().remove();
					$(this).parent().remove();
				},
				content : "<iframe border=0 frameborder=0  style='width:100%;height:100%;'  scrolling='yes' src='"+menumodel.link+"'  sandbox=\"allow-scripts allow-same-origin allow-forms\"></iframe>"
			};
			menumodel.load == "ajax"?dlgconfig.href=menumodel.link:"";
			$("#mm_"+menumodel.id).dialog(dlgconfig);
		});
		$('<li id="dock_'+menumodel.id+'"><a href="#mm_'+menumodel.id+'"><img src="assets/ima/' + menumodel.icon + '_22.png" />'+menumodel.title+'</a></li>').appendTo('#dock');
	}
};



展开阅读全文
打赏
3
4 收藏
分享
加载中
79
2016/02/18 13:19
回复
举报
不错,挺酷的
2016/02/18 08:49
回复
举报
更多评论
打赏
2 评论
4 收藏
3
分享
返回顶部
顶部